From 0724cad9cfdce2ace7d37277b096dccfc020f3b7 Mon Sep 17 00:00:00 2001 From: prinikasn <117314826+prinikasn@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:15:33 -0800 Subject: [PATCH 01/97] Add zr_supply_voltage_test (#2675) * fix addrundata * put all zr tests in under tests directory * remove extra supply * remove extra metadata files * add new test * add check for 400zr? * update * move if condition out of run * remove log line not needed * fix script * update subscriptiuoin metiod * update to fatal * move out variables * update changes * update testbed * update to fatal * add close * update * Update zr_supply_voltage_test.go updating doc to commets * Update zr_supply_voltage_test.go * update the file name * fix gofmt * move otg_tests too --- .../{ => tests}/zr_db_q_value_test/README.md | 0 .../{ => tests}/zr_esnr_and_cd_test/README.MD | 0 .../README.md | 0 .../zr_firmware_version_test/README.md | 0 .../zr_input_output_power_test/README.MD | 0 .../{ => tests}/zr_inventory_test/README.md | 0 .../zr_laser_bias_current_test/README.md | 0 .../zr_logical_channels_test/README.md | 0 .../zr_low_power_mode_test/README.md | 0 .../{ => tests}/zr_pre_fec_ber_test/README.md | 0 .../zr_supply_voltage_test/README.md | 0 .../zr_supply_voltage_test/metadata.textproto | 7 + .../zr_supply_voltage_test.go | 125 ++++++++++++++++++ .../zr_temperature_test/README.md | 0 .../zr_temperature_test/metadata.textproto | 0 .../zr_temperature_test.go | 0 .../zr_tunable_parameters_test/README.md | 0 .../transceiver/zr_temperature_test/README.md | 66 --------- 18 files changed, 132 insertions(+), 66 deletions(-) rename feature/platform/transceiver/{ => tests}/zr_db_q_value_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_esnr_and_cd_test/README.MD (100%) rename feature/platform/transceiver/{ => tests}/zr_fec_uncorrectable_frames_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_firmware_version_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_input_output_power_test/README.MD (100%) rename feature/platform/transceiver/{ => tests}/zr_inventory_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_laser_bias_current_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_logical_channels_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_low_power_mode_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_pre_fec_ber_test/README.md (100%) rename feature/platform/transceiver/{ => tests}/zr_supply_voltage_test/README.md (100%) create mode 100644 feature/platform/transceiver/tests/zr_supply_voltage_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go rename feature/platform/transceiver/{otg_tests => tests}/zr_temperature_test/README.md (100%) rename feature/platform/transceiver/{otg_tests => tests}/zr_temperature_test/metadata.textproto (100%) rename feature/platform/transceiver/{otg_tests => tests}/zr_temperature_test/zr_temperature_test.go (100%) rename feature/platform/transceiver/{ => tests}/zr_tunable_parameters_test/README.md (100%) delete mode 100644 feature/platform/transceiver/zr_temperature_test/README.md diff --git a/feature/platform/transceiver/zr_db_q_value_test/README.md b/feature/platform/transceiver/tests/zr_db_q_value_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_db_q_value_test/README.md rename to feature/platform/transceiver/tests/zr_db_q_value_test/README.md diff --git a/feature/platform/transceiver/zr_esnr_and_cd_test/README.MD b/feature/platform/transceiver/tests/zr_esnr_and_cd_test/README.MD similarity index 100% rename from feature/platform/transceiver/zr_esnr_and_cd_test/README.MD rename to feature/platform/transceiver/tests/zr_esnr_and_cd_test/README.MD diff --git a/feature/platform/transceiver/zr_fec_uncorrectable_frames_test/README.md b/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_fec_uncorrectable_frames_test/README.md rename to feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/README.md diff --git a/feature/platform/transceiver/zr_firmware_version_test/README.md b/feature/platform/transceiver/tests/zr_firmware_version_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_firmware_version_test/README.md rename to feature/platform/transceiver/tests/zr_firmware_version_test/README.md diff --git a/feature/platform/transceiver/zr_input_output_power_test/README.MD b/feature/platform/transceiver/tests/zr_input_output_power_test/README.MD similarity index 100% rename from feature/platform/transceiver/zr_input_output_power_test/README.MD rename to feature/platform/transceiver/tests/zr_input_output_power_test/README.MD diff --git a/feature/platform/transceiver/zr_inventory_test/README.md b/feature/platform/transceiver/tests/zr_inventory_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_inventory_test/README.md rename to feature/platform/transceiver/tests/zr_inventory_test/README.md diff --git a/feature/platform/transceiver/zr_laser_bias_current_test/README.md b/feature/platform/transceiver/tests/zr_laser_bias_current_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_laser_bias_current_test/README.md rename to feature/platform/transceiver/tests/zr_laser_bias_current_test/README.md diff --git a/feature/platform/transceiver/zr_logical_channels_test/README.md b/feature/platform/transceiver/tests/zr_logical_channels_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_logical_channels_test/README.md rename to feature/platform/transceiver/tests/zr_logical_channels_test/README.md diff --git a/feature/platform/transceiver/zr_low_power_mode_test/README.md b/feature/platform/transceiver/tests/zr_low_power_mode_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_low_power_mode_test/README.md rename to feature/platform/transceiver/tests/zr_low_power_mode_test/README.md diff --git a/feature/platform/transceiver/zr_pre_fec_ber_test/README.md b/feature/platform/transceiver/tests/zr_pre_fec_ber_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_pre_fec_ber_test/README.md rename to feature/platform/transceiver/tests/zr_pre_fec_ber_test/README.md diff --git a/feature/platform/transceiver/zr_supply_voltage_test/README.md b/feature/platform/transceiver/tests/zr_supply_voltage_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_supply_voltage_test/README.md rename to feature/platform/transceiver/tests/zr_supply_voltage_test/README.md diff --git a/feature/platform/transceiver/tests/zr_supply_voltage_test/metadata.textproto b/feature/platform/transceiver/tests/zr_supply_voltage_test/metadata.textproto new file mode 100644 index 00000000000..c645ec9f682 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_supply_voltage_test/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "7e0251e4-8c5c-4dff-9683-8c21c817816c" +plan_id: "TRANSCEIVER-12" +description: "Telemetry: 400ZR Transceiver Supply Voltage streaming." +testbed: TESTBED_DUT_400ZR diff --git a/feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go b/feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go new file mode 100644 index 00000000000..8ec0640deca --- /dev/null +++ b/feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go @@ -0,0 +1,125 @@ +// 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 zr_supply_voltage_test + +import ( + "fmt" + "reflect" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" +) + +const ( + samplingInterval = 10 * time.Second + targetOutputPowerdBm = -10 + targetFrequencyHz = 193100000 + intUpdateTime = 2 * time.Minute +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func verifyVoltageValue(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[float64], path string) float64 { + voltageSample := pStream.Next(t) + if voltageSample == nil { + t.Fatalf("Voltage telemetry %s was not streamed in the most recent subscription interval", path) + } + voltageVal, ok := voltageSample.Val() + if !ok { + t.Fatalf("Voltage %q telemetry is not present", voltageSample) + } + // Check voltage return value of correct type + if reflect.TypeOf(voltageVal).Kind() != reflect.Float64 { + t.Fatalf("Return value is not type float64") + } + t.Logf("Voltage sample value %s: %v", path, voltageVal) + return voltageVal +} + +func TestZrSupplyVoltage(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + for _, port := range []string{"port1", "port2"} { + t.Run(fmt.Sprintf("Port:%s", port), func(t *testing.T) { + dp := dut.Port(t, port) + + gnmi.Await(t, dut, gnmi.OC().Interface(dp.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) + + // Derive transceiver names from ports. + tr := gnmi.Get(t, dut, gnmi.OC().Interface(dp.Name()).Transceiver().State()) + component := gnmi.OC().Component(tr) + + outputPower := gnmi.Get(t, dut, component.OpticalChannel().TargetOutputPower().State()) + if outputPower != targetOutputPowerdBm { + t.Fatalf("Output power does not match target output power, got: %v want :%v", outputPower, targetOutputPowerdBm) + } + + frequency := gnmi.Get(t, dut, component.OpticalChannel().Frequency().State()) + if frequency != targetFrequencyHz { + t.Fatalf("Frequency does not match target frequency, got: %v want :%v", frequency, targetFrequencyHz) + } + + streamInst := samplestream.New(t, dut, component.Transceiver().SupplyVoltage().Instant().State(), samplingInterval) + defer streamInst.Close() + streamAvg := samplestream.New(t, dut, component.Transceiver().SupplyVoltage().Avg().State(), samplingInterval) + defer streamAvg.Close() + streamMin := samplestream.New(t, dut, component.Transceiver().SupplyVoltage().Min().State(), samplingInterval) + defer streamMin.Close() + streamMax := samplestream.New(t, dut, component.Transceiver().SupplyVoltage().Max().State(), samplingInterval) + defer streamMax.Close() + + volInst := verifyVoltageValue(t, dut, streamInst, "Instant") + t.Logf("Port %s instant voltage: %v", dp.Name(), volInst) + volAvg := verifyVoltageValue(t, dut, streamAvg, "Avg") + t.Logf("Port %s average voltage: %v", dp.Name(), volAvg) + volMin := verifyVoltageValue(t, dut, streamMin, "Min") + t.Logf("Port %s minimum voltage: %v", dp.Name(), volMin) + volMax := verifyVoltageValue(t, dut, streamMax, "Max") + t.Logf("Port %s maximum voltage: %v", dp.Name(), volMax) + + if volAvg >= volMin && volAvg <= volMax { + t.Logf("The average is between the maximum and minimum values") + } else { + t.Fatalf("The average is not between the maximum and minimum values, Avg:%v Max:%v Min:%v", volAvg, volMax, volMin) + } + + // Wait for the cooling off period + gnmi.Await(t, dut, gnmi.OC().Interface(dp.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_DOWN) + + volInstNew := verifyVoltageValue(t, dut, streamInst, "Instant") + t.Logf("Port %s instant voltage after port down: %v", dp.Name(), volInstNew) + volAvgNew := verifyVoltageValue(t, dut, streamAvg, "Avg") + t.Logf("Port %s average voltage after port down: %v", dp.Name(), volAvgNew) + volMinNew := verifyVoltageValue(t, dut, streamMin, "Min") + t.Logf("Port %s minimum voltage after port down: %v", dp.Name(), volMinNew) + volMaxNew := verifyVoltageValue(t, dut, streamMax, "Max") + t.Logf("Port %s maximum voltage after port down: %v", dp.Name(), volMaxNew) + + if volAvgNew >= volMinNew && volAvgNew <= volMaxNew { + t.Logf("The average voltage after port down is between the maximum and minimum values") + } else { + t.Fatalf("The average voltage after port down is not between the maximum and minimum values, Avg:%v Max:%v Min:%v", volAvgNew, volMaxNew, volMinNew) + } + }) + } + +} diff --git a/feature/platform/transceiver/otg_tests/zr_temperature_test/README.md b/feature/platform/transceiver/tests/zr_temperature_test/README.md similarity index 100% rename from feature/platform/transceiver/otg_tests/zr_temperature_test/README.md rename to feature/platform/transceiver/tests/zr_temperature_test/README.md diff --git a/feature/platform/transceiver/otg_tests/zr_temperature_test/metadata.textproto b/feature/platform/transceiver/tests/zr_temperature_test/metadata.textproto similarity index 100% rename from feature/platform/transceiver/otg_tests/zr_temperature_test/metadata.textproto rename to feature/platform/transceiver/tests/zr_temperature_test/metadata.textproto diff --git a/feature/platform/transceiver/otg_tests/zr_temperature_test/zr_temperature_test.go b/feature/platform/transceiver/tests/zr_temperature_test/zr_temperature_test.go similarity index 100% rename from feature/platform/transceiver/otg_tests/zr_temperature_test/zr_temperature_test.go rename to feature/platform/transceiver/tests/zr_temperature_test/zr_temperature_test.go diff --git a/feature/platform/transceiver/zr_tunable_parameters_test/README.md b/feature/platform/transceiver/tests/zr_tunable_parameters_test/README.md similarity index 100% rename from feature/platform/transceiver/zr_tunable_parameters_test/README.md rename to feature/platform/transceiver/tests/zr_tunable_parameters_test/README.md diff --git a/feature/platform/transceiver/zr_temperature_test/README.md b/feature/platform/transceiver/zr_temperature_test/README.md deleted file mode 100644 index 57a4ab52bbb..00000000000 --- a/feature/platform/transceiver/zr_temperature_test/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# TRANSCEIVER-8: Telemetry: 400ZR Optics module temperature streaming. - -## Summary - -Validate 400ZR optics report module level internally measured temperature -in 1/256 degree Celsius increments as defined in the CMIS. - -Link to CMIS: -https://www.oiforum.com/wp-content/uploads/CMIS5p0_Third_Party_Spec.pdf - -## Procedure - -* Connect two ZR optics using a duplex LC fiber jumper such that TX - output power of one is the RX input power of the other module. -* To establish a point to point ZR link ensure the following: - * Both transceivers state is enabled. - * Both transceivers are set to a valid target TX output power - example -10 dBm. - * Both transceivers are tuned to a valid centre frequency - example 193.1 THz. -* With the ZR link established as explained above, verify that the - following ZR transceiver telemetry paths exist and are streamed for both - the ZR optics. - * /platform/components/component/state/temperature/instant - * /platform/components/component/state/temperature/min - * /platform/components/component/state/temperature/max - * /platform/components/component/state/temperature/avg -* For reported data check for validity min <= avg/instant <= max - -* If the modules or the devices are in a boot stage, they must not stream - any invalid string values like "nil" or "-inf". -* Reported temperature value must always be of type decimal64. - - -**Note:** For min, max, and avg values, 10 second sampling is preferred. If the - min, max average values or the 10 seconds sampling is not supported, - the sampling interval used must be specified and this must be - captured by adding a deviation to the test. - - -* Verify the module temperature is reported correctly with optics interface - in disabled state. - - * Use /interfaces/interface/config/enabled to disable the interfaces and - wait 120 seconds(cooling off period) before taking the temperature - reading again. - * Verify the module is able to stream the temperature data in this state. - * Verify the module reported temperature in this state is always less - than the module temperature captured during steady state operation with - interface state enabled. - * For reported data check for validity min <= avg/instant <= max - - * If the modules or the devices are in a boot stage, they must not stream - any invalid string values like "nil" or "-inf". - * Reported temperature value must always be of type decimal64. - -## Config Parameter coverage - -* /interfaces/interface/config/enabled - -## Telemetry Parameter coverage - -* /platform/components/component/state/temperature/instant -* /platform/components/component/state/temperature/min -* /platform/components/component/state/temperature/max -* /platform/components/component/state/temperature/avg \ No newline at end of file From 79ff423ed1abcf4b6ede8ec44cdb0116bb11a7d5 Mon Sep 17 00:00:00 2001 From: prinikasn <117314826+prinikasn@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:23:32 -0800 Subject: [PATCH 02/97] Add zr_fec_uncorrectable_frames_test (#2709) * add all files * metadata.textproto * update * update changes * add samplestream * Update zr_fec_uncorrectable_frames_test.go Update based on other PR comments * Update zr_fec_uncorrectable_frames_test.go update paramerter * format --- .../metadata.textproto | 7 ++ .../zr_fec_uncorrectable_frames_test.go | 91 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go diff --git a/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/metadata.textproto b/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/metadata.textproto new file mode 100644 index 00000000000..5c9c9aea535 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "6f9059c8-e49c-4ff6-8bd2-f474cd4fcfce" +plan_id: "TRANSCEIVER-10" +description: "Telemetry: 400ZR Optics FEC(Forward Error Correction) Uncorrectable Frames Streaming." +testbed: TESTBED_DUT_400ZR diff --git a/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go b/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go new file mode 100644 index 00000000000..8a8ac84dfbc --- /dev/null +++ b/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go @@ -0,0 +1,91 @@ +// 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 zr_fec_uncorrectable_frames_test + +import ( + "fmt" + "reflect" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" +) + +const ( + sampleInterval = 10 * time.Second + targetOutputPowerdBm = -10 + targetFrequencyHz = 193100000 + intUpdateTime = 2 * time.Minute +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func validateFecUncorrectableBlocks(t *testing.T, dut *ondatra.DUTDevice, stream *samplestream.SampleStream[uint64]) { + fecStream := stream.Next(t) + if fecStream == nil { + t.Fatalf("Fec Uncorrectable Blocks was not streamed in the most recent subscription interval") + } + fec, ok := fecStream.Val() + if !ok { + t.Fatalf("Error capturing streaming Fec value") + } + if reflect.TypeOf(fec).Kind() != reflect.Int64 { + t.Fatalf("fec value is not type int64") + } + if fec != 0 { + t.Fatalf("Got FecUncorrectableBlocks got %d, want 0", fec) + } +} + +func TestZrUncorrectableFrames(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + for _, port := range []string{"port1", "port2"} { + t.Run(fmt.Sprintf("Port:%s", port), func(t *testing.T) { + dp := dut.Port(t, "port1") + gnmi.Await(t, dut, gnmi.OC().Interface(dp.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) + + // Derive transceiver names from ports. + tr := gnmi.Get(t, dut, gnmi.OC().Interface(dp.Name()).Transceiver().State()) + component := gnmi.OC().Component(tr) + + outputPower := gnmi.Get(t, dut, component.OpticalChannel().TargetOutputPower().State()) + if outputPower != targetOutputPowerdBm { + t.Fatalf("Output power does not match target output power, got: %v want :%v", outputPower, targetOutputPowerdBm) + } + + frequency := gnmi.Get(t, dut, component.OpticalChannel().Frequency().State()) + if frequency != targetFrequencyHz { + t.Fatalf("Frequency does not match target frequency, got: %v want :%v", frequency, targetFrequencyHz) + } + + streamFec := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(0).Otn().FecUncorrectableBlocks().State(), sampleInterval) + defer streamFec.Close() + validateFecUncorrectableBlocks(t, dut, streamFec) + + // Toggle interface enabled + gnmi.Update(t, dut, gnmi.OC().Interface(dp.Name()).Enabled().Config(), bool(false)) + gnmi.Update(t, dut, gnmi.OC().Interface(dp.Name()).Enabled().Config(), bool(true)) + + validateFecUncorrectableBlocks(t, dut, streamFec) + }) + } +} From 275be5c51ee125416746a1ba6ad9bad8e66d90fa Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:30:01 -0500 Subject: [PATCH 03/97] Fix documentation on proto Link message (#2780) --- topologies/proto/binding.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/topologies/proto/binding.proto b/topologies/proto/binding.proto index 014175f46a7..2391eb9ab51 100644 --- a/topologies/proto/binding.proto +++ b/topologies/proto/binding.proto @@ -164,6 +164,6 @@ message Port { // Link between two ports. // Links are only relevant if dynamic solving is enabled. message Link { - string a = 1; // First port in the format ":". - string b = 2; // Second port in the format ":". + string a = 1; // First port in the format ":". + string b = 2; // Second port in the format ":". } From d103662cfc74825bcb12b6df98e0bb3bdb8b019b Mon Sep 17 00:00:00 2001 From: anksaiki Date: Fri, 8 Mar 2024 17:50:54 -0500 Subject: [PATCH 04/97] ZR Tunable Parameters and ZR Logical Interfaces Test (#2782) * ZR Tunable and ZR Logical Interfaces Test * Fix metadata * fix formatting --- .../metadata.textproto | 16 + .../zr_logical_channels_test.go | 301 ++++++++++++++++++ .../metadata.textproto | 16 + .../zr_tunable_parameters_test.go | 284 +++++++++++++++++ 4 files changed, 617 insertions(+) create mode 100644 feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go create mode 100644 feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go diff --git a/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto b/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto new file mode 100644 index 00000000000..caa9410e80a --- /dev/null +++ b/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto @@ -0,0 +1,16 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata +uuid: "0bef25c1-0ea2-4b44-8a37-07de9f870cae" +plan_id: "TRANSCEIVER-11" +description: "Telemetry: 400ZR Optics logical channels provisioning and related telemetry." +testbed: TESTBED_DUT_400ZR +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + missing_port_to_optical_channel_component_mapping: true + } +} diff --git a/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go b/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go new file mode 100644 index 00000000000..8fd26627fee --- /dev/null +++ b/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go @@ -0,0 +1,301 @@ +package zr_logical_channels_test + +import ( + "fmt" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +const ( + targetOutputPower = -9 + frequency = 193100000 +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "dutPort1", + IPv4: "192.0.2.1", + IPv4Len: 30, + } + + dutPort2 = attrs.Attributes{ + Desc: "dutPort2", + IPv4: "192.0.2.5", + IPv4Len: 30, + } +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func Test400ZRLogicalChannels(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + + fptest.ConfigureDefaultNetworkInstance(t, dut) + fptest.ConfigureDefaultNetworkInstance(t, dut) + + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) + + oc1 := opticalChannelFromPort(t, dut, p1) + oc2 := opticalChannelFromPort(t, dut, p2) + + configureLogicalChannels(t, dut, 40000, 40001, oc1) + configureLogicalChannels(t, dut, 40002, 40003, oc2) + + ethChan1 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(40000).State(), 10*time.Second) + defer ethChan1.Close() + validateEthernetChannelTelemetry(t, 40000, 40001, ethChan1) + cohChan1 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(40001).State(), 10*time.Second) + defer cohChan1.Close() + validateCoherentChannelTelemetry(t, 40001, oc1, cohChan1) + ethChan2 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(40002).State(), 10*time.Second) + defer ethChan2.Close() + validateEthernetChannelTelemetry(t, 40002, 40003, ethChan2) + cohChan2 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(40002).State(), 10*time.Second) + defer cohChan2.Close() + validateCoherentChannelTelemetry(t, 40003, oc2, cohChan2) +} + +func configureLogicalChannels(t *testing.T, dut *ondatra.DUTDevice, ethernetChIdx, coherentChIdx uint32, opticalChannel string) { + t.Helper() + b := &gnmi.SetBatch{} + + // Optical Channel and Tunable Parameters + gnmi.BatchReplace(b, gnmi.OC().Component(opticalChannel).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(targetOutputPower), + Frequency: ygot.Uint64(frequency), + }) + + // Ethernet Logical Channel + gnmi.BatchReplace(b, gnmi.OC().TerminalDevice().Channel(ethernetChIdx).Config(), &oc.TerminalDevice_Channel{ + LogicalChannelType: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_ETHERNET, + AdminState: oc.TerminalDevice_AdminStateType_ENABLED, + Description: ygot.String("ETH Logical Channel"), + Index: ygot.Uint32(ethernetChIdx), + RateClass: oc.TransportTypes_TRIBUTARY_RATE_CLASS_TYPE_TRIB_RATE_400G, + TribProtocol: oc.TransportTypes_TRIBUTARY_PROTOCOL_TYPE_PROT_400GE, + Assignment: map[uint32]*oc.TerminalDevice_Channel_Assignment{ + 1: { + Index: ygot.Uint32(1), + LogicalChannel: ygot.Uint32(coherentChIdx), + Description: ygot.String("ETH to Coherent"), + Allocation: ygot.Float64(400), + AssignmentType: oc.Assignment_AssignmentType_LOGICAL_CHANNEL, + }, + }, + }) + + // Coherent Logical Channel + gnmi.BatchReplace(b, gnmi.OC().TerminalDevice().Channel(coherentChIdx).Config(), &oc.TerminalDevice_Channel{ + LogicalChannelType: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_OTN, + AdminState: oc.TerminalDevice_AdminStateType_ENABLED, + Description: ygot.String("Coherent Logical Channel"), + Index: ygot.Uint32(coherentChIdx), + Assignment: map[uint32]*oc.TerminalDevice_Channel_Assignment{ + 1: { + Index: ygot.Uint32(1), + OpticalChannel: ygot.String(opticalChannel), + Description: ygot.String("Coherent to Optical"), + Allocation: ygot.Float64(400), + AssignmentType: oc.Assignment_AssignmentType_OPTICAL_CHANNEL, + }, + }, + }) + + b.Set(t, dut) +} + +func validateEthernetChannelTelemetry(t *testing.T, ethernetChIdx, coherentChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { + val := stream.Next(t) // value received in the gnmi subscription within 10 seconds + if val == nil { + t.Fatalf("Ethernet Channel telemetry stream not received in last 10 seconds") + } + ec, ok := val.Val() + if !ok { + t.Fatalf("Ethernet Channel telemetry stream empty in last 10 seconds") + } + tcs := []struct { + desc string + got any + want any + }{ + { + desc: "Index", + got: ec.GetIndex(), + want: ethernetChIdx, + }, + { + desc: "Admin State", + got: ec.GetAdminState().String(), + want: oc.TerminalDevice_AdminStateType_ENABLED.String(), + }, + { + desc: "Description", + got: ec.GetDescription(), + want: "ETH Logical Channel", + }, + { + desc: "Logical Channel Type", + got: ec.GetLogicalChannelType().String(), + want: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_ETHERNET.String(), + }, + { + desc: "Rate Class", + got: ec.GetRateClass().String(), + want: oc.TransportTypes_TRIBUTARY_RATE_CLASS_TYPE_TRIB_RATE_400G.String(), + }, + { + desc: "Trib Protocol", + got: ec.GetTribProtocol().String(), + want: oc.TransportTypes_TRIBUTARY_PROTOCOL_TYPE_PROT_400GE.String(), + }, + { + desc: "Assignment: Index", + got: ec.GetAssignment(1).GetIndex(), + want: uint32(1), + }, + { + desc: "Assignment: Logical Channel", + got: ec.GetAssignment(1).GetLogicalChannel(), + want: coherentChIdx, + }, + { + desc: "Assignment: Description", + got: ec.GetAssignment(1).GetDescription(), + want: "ETH to Coherent", + }, + { + desc: "Assignment: Allocation", + got: ec.GetAssignment(1).GetAllocation(), + want: float64(400), + }, + { + desc: "Assignment: Type", + got: ec.GetAssignment(1).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), + }, + } + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + if diff := cmp.Diff(tc.got, tc.want); diff != "" { + t.Errorf("Ethernet Logical Channel: %s, diff (-got +want):\n%s", tc.desc, diff) + } + }) + } +} + +func validateCoherentChannelTelemetry(t *testing.T, coherentChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { + val := stream.Next(t) // value received in the gnmi subscription within 10 seconds + if val == nil { + t.Fatalf("Coherent Channel telemetry stream not received in last 10 seconds") + } + cc, ok := val.Val() + if !ok { + t.Fatalf("Coherent Channel telemetry stream empty in last 10 seconds") + } + tcs := []struct { + desc string + got any + want any + }{ + { + desc: "Admin State", + got: cc.GetAdminState().String(), + want: oc.TerminalDevice_AdminStateType_ENABLED.String(), + }, + { + desc: "Description", + got: cc.GetDescription(), + want: "Coherent Logical Channel", + }, + { + desc: "Index", + got: cc.GetIndex(), + want: coherentChIdx, + }, + { + desc: "Logical Channel Type", + got: cc.GetLogicalChannelType().String(), + want: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_OTN.String(), + }, + { + desc: "Assignment: Index", + got: cc.GetAssignment(1).GetIndex(), + want: uint32(1), + }, + { + desc: "Assignment: Optical Channel", + got: cc.GetAssignment(1).GetOpticalChannel(), + want: opticalChannel, + }, + { + desc: "Assignment: Description", + got: cc.GetAssignment(1).GetDescription(), + want: "Coherent to Optical", + }, + { + desc: "Assignment: Allocation", + got: cc.GetAssignment(1).GetAllocation(), + want: float64(400), + }, + { + desc: "Assignment: Type", + got: cc.GetAssignment(1).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(), + }, + } + + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + if diff := cmp.Diff(tc.got, tc.want); diff != "" { + t.Errorf("Coherent Logical Channel: %s, diff (-got +want):\n%s", tc.desc, diff) + } + }) + } +} + +// opticalChannelFromPort returns the connected optical channel component name for a given ondatra port. +func opticalChannelFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { + t.Helper() + + if deviations.MissingPortToOpticalChannelMapping(dut) { + switch dut.Vendor() { + case ondatra.ARISTA: + return fmt.Sprintf("%s-Optical0", p.Name()) + default: + t.Fatal("Manual Optical channel name required when deviation missing_port_to_optical_channel_component_mapping applied.") + } + } + compName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).HardwarePort().State()) + + for { + comp, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(compName).State()).Val() + if !ok { + t.Fatalf("Recursive optical channel lookup failed for port: %s, component %s not found.", p.Name(), compName) + } + if comp.GetType() == oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL { + return compName + } + + if comp.GetParent() == "" { + t.Fatalf("Recursive optical channel lookup failed for port: %s, parent of component %s not found.", p.Name(), compName) + } + + compName = comp.GetParent() + } +} diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto b/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto new file mode 100644 index 00000000000..7dd07261362 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto @@ -0,0 +1,16 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata +uuid: "47c623ec-69b3-4bca-ae07-012feff496b8" +plan_id: "TRANSCEIVER-5" +description: "Configuration: 400ZR channel frequency, output TX launch power and operational mode setting." +testbed: TESTBED_DUT_400ZR +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + missing_port_to_optical_channel_component_mapping: true + } +} diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go new file mode 100644 index 00000000000..05a08b02a1f --- /dev/null +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go @@ -0,0 +1,284 @@ +package zr_tunable_parameters_test + +import ( + "fmt" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +const ( + samplingInterval = 10 * time.Second + frequencyTolerance = 1800 +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "dutPort1", + IPv4: "192.0.2.1", + IPv4Len: 30, + } + dutPort2 = attrs.Attributes{ + Desc: "dutPort2", + IPv4: "192.0.2.5", + IPv4Len: 30, + } +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} +func Test400ZRTunableFrequency(t *testing.T) { + dut := ondatra.DUT(t, "dut") + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + fptest.ConfigureDefaultNetworkInstance(t, dut) + fptest.ConfigureDefaultNetworkInstance(t, dut) + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) + oc1 := opticalChannelFromPort(t, dut, p1) + oc2 := opticalChannelFromPort(t, dut, p2) + streamOC1 := samplestream.New(t, dut, gnmi.OC().Component(oc1).State(), 10*time.Second) + defer streamOC1.Close() + streamOC2 := samplestream.New(t, dut, gnmi.OC().Component(oc2).State(), 10*time.Second) + defer streamOC2.Close() + tests := []struct { + description string + startFreq uint64 + endFreq uint64 + freqStep uint64 + targetOutputPower float64 + }{ + { + // Validate setting 400ZR optics module tunable laser center frequency + // across frequency range 196.100 - 191.400 THz for 100GHz grid. + description: "100GHz grid", + startFreq: 191400000, + endFreq: 196100000, + freqStep: 100000, + targetOutputPower: -13, + }, + { + // Validate setting 400ZR optics module tunable laser center frequency + // across frequency range 196.100 - 191.375 THz for 75GHz grid. + description: "75GHz grid", + startFreq: 191375000, + endFreq: 196100000, + freqStep: 75000, + targetOutputPower: -9, + }, + } + for _, tc := range tests { + t.Run(tc.description, func(t *testing.T) { + for freq := tc.startFreq; freq <= tc.endFreq; freq += tc.freqStep { + t.Run(fmt.Sprintf("Freq: %v", freq), func(t *testing.T) { + gnmi.Replace(t, dut, gnmi.OC().Component(oc1).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(tc.targetOutputPower), + Frequency: ygot.Uint64(freq), + }) + gnmi.Replace(t, dut, gnmi.OC().Component(oc2).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(tc.targetOutputPower), + Frequency: ygot.Uint64(freq), + }) + validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, freq, tc.targetOutputPower) + }) + } + }) + } +} +func Test400ZRTunableOutputPower(t *testing.T) { + dut := ondatra.DUT(t, "dut") + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + fptest.ConfigureDefaultNetworkInstance(t, dut) + fptest.ConfigureDefaultNetworkInstance(t, dut) + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) + oc1 := opticalChannelFromPort(t, dut, p1) + oc2 := opticalChannelFromPort(t, dut, p2) + streamOC1 := samplestream.New(t, dut, gnmi.OC().Component(oc1).State(), 10*time.Second) + defer streamOC1.Close() + streamOC2 := samplestream.New(t, dut, gnmi.OC().Component(oc2).State(), 10*time.Second) + defer streamOC2.Close() + tests := []struct { + description string + frequency uint64 + startTargetOutputPower float64 + endTargetOutputPower float64 + targetOutputPowerStep float64 + }{ + { + // Validate adjustable range of transmit output power across -13 to -9 dBm + // range in steps of 1dB. So the module’s output power will be set to -13, + // -12, -11, -10, -9 dBm in each step. + description: "adjustable range of transmit output power across -13 to -9 dBm range in steps of 1dB", + frequency: 193100000, + startTargetOutputPower: -13, + endTargetOutputPower: -9, + targetOutputPowerStep: 1, + }, + } + for _, tc := range tests { + for top := tc.startTargetOutputPower; top <= tc.endTargetOutputPower; top += tc.targetOutputPowerStep { + t.Run(fmt.Sprintf("Target Power: %v", top), func(t *testing.T) { + gnmi.Replace(t, dut, gnmi.OC().Component(oc1).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(top), + Frequency: ygot.Uint64(tc.frequency), + }) + gnmi.Replace(t, dut, gnmi.OC().Component(oc2).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(top), + Frequency: ygot.Uint64(tc.frequency), + }) + validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, tc.frequency, top) + }) + } + } +} +func Test400ZRInterfaceFlap(t *testing.T) { + dut := ondatra.DUT(t, "dut") + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + fptest.ConfigureDefaultNetworkInstance(t, dut) + fptest.ConfigureDefaultNetworkInstance(t, dut) + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) + oc1 := opticalChannelFromPort(t, dut, p1) + oc2 := opticalChannelFromPort(t, dut, p2) + streamOC1 := samplestream.New(t, dut, gnmi.OC().Component(oc1).State(), 10*time.Second) + defer streamOC1.Close() + streamOC2 := samplestream.New(t, dut, gnmi.OC().Component(oc2).State(), 10*time.Second) + defer streamOC2.Close() + targetPower := float64(-9) + frequency := uint64(193100000) + gnmi.Replace(t, dut, gnmi.OC().Component(oc1).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(targetPower), + Frequency: ygot.Uint64(frequency), + }) + gnmi.Replace(t, dut, gnmi.OC().Component(oc2).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(targetPower), + Frequency: ygot.Uint64(frequency), + }) + t.Run("Telemetry before flap", func(t *testing.T) { + validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) + }) + // Disable or shut down the interface on the DUT. + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Enabled().Config(), false) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Enabled().Config(), false) + // Verify with interfaces in down state both optics are streaming uint 0 + // value for frequency. + // Verify for the TX output power with interface in down state a decimal64 + // value of -40 dB is streamed. + t.Run("Telemetry during interface disabled", func(t *testing.T) { + validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, 0, -40) + }) + // Re-enable the interfaces on the DUT. + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Enabled().Config(), true) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Enabled().Config(), true) + gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_UP) + gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_UP) + // Verify the ZR optics tune back to the correct frequency and TX output + // power as per the configuration and related telemetry values are updated + // to the value in the normal range again. + t.Run("Telemetry after flap", func(t *testing.T) { + validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) + }) +} +func validateOpticsTelemetry(t *testing.T, dut *ondatra.DUTDevice, streams []*samplestream.SampleStream[*oc.Component], frequency uint64, outputPower float64) { + var ocs []*oc.Component_OpticalChannel + for _, s := range streams { + val := s.Next(t) + if val == nil { + t.Fatal("Optical channel streaming telemetry not received") + } + v, ok := val.Val() + if !ok { + t.Fatal("Optical channel streaming telemetry empty") + } + ocs = append(ocs, v.GetOpticalChannel()) + } + for _, oc := range ocs { + inst := oc.GetCarrierFrequencyOffset().GetInstant() + avg := oc.GetCarrierFrequencyOffset().GetAvg() + min := oc.GetCarrierFrequencyOffset().GetMin() + max := oc.GetCarrierFrequencyOffset().GetMax() + // Laser frequency offset should not be more than +/- 1.8 GHz max from the + // configured centre frequency. + if inst < -1*frequencyTolerance || inst > frequencyTolerance { + t.Errorf("Optical-Channel: carrier-frequency-offset not in tolerable range, got: %v, want: (+/-)%v", inst, frequencyTolerance) + } + // For reported data check for validity: min <= avg/instant <= max + if min > inst { + t.Errorf("Optical-Channel: carrier-frequency-offset min: %v greater than carrier-frequency-offset instant: %v", min, inst) + } + if max < inst { + t.Errorf("Optical-Channel: carrier-frequency-offset max: %v less than carrier-frequency-offset instant: %v", max, inst) + } + if min > avg { + t.Errorf("Optical-Channel: carrier-frequency-offset min: %v greater than carrier-frequency-offset avg: %v", min, avg) + } + if max < avg { + t.Errorf("Optical-Channel: carrier-frequency-offset max: %v less than carrier-frequency-offset avg: %v", max, avg) + } + inst = oc.GetOutputPower().GetInstant() + avg = oc.GetOutputPower().GetAvg() + min = oc.GetOutputPower().GetMin() + max = oc.GetOutputPower().GetMax() + // When set to a specific target output power, transmit power control + // absolute accuracy should be within +/- 1 dBm of the target configured + // output power. + if inst < outputPower-1 || inst > outputPower+1 { + t.Errorf("Optical-Channel: output-power not in tolerable range, got: %v, want: %v", inst, outputPower) + } + // For reported data check for validity: min <= avg/instant <= max + if min > inst { + t.Errorf("Optical-Channel: output-power min: %v greater than output-power instant: %v", min, inst) + } + if max < inst { + t.Errorf("Optical-Channel: output-power max: %v less than output-power instant: %v", max, inst) + } + if min > avg { + t.Errorf("Optical-Channel: output-power min: %v greater than output-power avg: %v", min, avg) + } + if max < avg { + t.Errorf("Optical-Channel: output-power max: %v less than output-power avg: %v", max, avg) + } + if got, want := oc.GetFrequency(), frequency; got != want { + t.Errorf("Optical-Channel: frequency: %v, want: %v", got, want) + } + } +} + +// opticalChannelFromPort returns the connected optical channel component name for a given ondatra port. +func opticalChannelFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { + t.Helper() + if deviations.MissingPortToOpticalChannelMapping(dut) { + switch dut.Vendor() { + case ondatra.ARISTA: + return fmt.Sprintf("%s-Optical0", p.Name()) + default: + t.Fatal("Manual Optical channel name required when deviation missing_port_to_optical_channel_component_mapping applied.") + } + } + compName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).HardwarePort().State()) + for { + comp, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(compName).State()).Val() + if !ok { + t.Fatalf("Recursive optical channel lookup failed for port: %s, component %s not found.", p.Name(), compName) + } + if comp.GetType() == oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL { + return compName + } + if comp.GetParent() == "" { + t.Fatalf("Recursive optical channel lookup failed for port: %s, parent of component %s not found.", p.Name(), compName) + } + compName = comp.GetParent() + } +} From 32de5e7773ce2ad8f013a844f3d4222285998594 Mon Sep 17 00:00:00 2001 From: sunilprgit <158420069+sunilprgit@users.noreply.github.com> Date: Mon, 11 Mar 2024 10:46:54 +0530 Subject: [PATCH 05/97] TRANSCEIVER-9 Telemetry: 400ZR TX laser bias current telemetry values streaming. (#2694) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * TRANSCEIVER-9 * TRANSCEIVER-8: Telemetry: 400ZR Optics module temperature streaming. (#2672) * TRANSCEIVER-8: Telemetry: 400ZR Optics module temperature streaming. * correcting file path * implemented review comments * fixing rundata * Add FP test for BGP to ISIS redistribution test with prefix and commu… (#2678) * Add FP test for BGP to ISIS redistribution test with prefix and community based routing policy * updated ondatra version to 0.5.2 * deviation name fixes * Update IP list to include RT-1.32 (#2693) * implemented review comments * added changes to use samplestream lib * fix static check * fix static check * fix static check * fix fmt * fix fmt * fix fmt * fix fmt * implementing comment * implementing comment --------- Co-authored-by: Pramod Maurya Co-authored-by: Calvin F <131898783+cfernanz@users.noreply.github.com> * added changes to use samplestream lib * [DCGate][RT-5.9]: IPv6 Link Local generated by SLAAC (#2759) * [DCGate][RT-5.9]: IPv6 Link Local generated by SLAAC * [DCGate][RT-5.9]: IPv6 Link Local generated by SLAAC * [DCGate][RT-5.9]: IPv6 Link Local generated by SLAAC, correct path * Moved test files to otg_tests path and reserved RT-5.10 in the test registry. Note that TestID RT-5.9 is already used by another test. * Moving test files to otg_tests path and reserving RT-5.10 in the test registry. Note that RT-5.9 is already used by another test. * updating metadata with addrundata --fix --------- Co-authored-by: Benson Schliesser * Remove restore-keys from Github Actions (#2775) * Add dynamic solving to feature profiles binding (#2773) * Add dynamic solving if binding.Dynamic is set * Add/fix copyright headers * Add/fix copyright headers * Add blank line to end of file * remove old print statements * Update Ondatra version (#2777) * Add zr_supply_voltage_test (#2675) * fix addrundata * put all zr tests in under tests directory * remove extra supply * remove extra metadata files * add new test * add check for 400zr? * update * move if condition out of run * remove log line not needed * fix script * update subscriptiuoin metiod * update to fatal * move out variables * update changes * update testbed * update to fatal * add close * update * Update zr_supply_voltage_test.go updating doc to commets * Update zr_supply_voltage_test.go * update the file name * fix gofmt * move otg_tests too * Add zr_fec_uncorrectable_frames_test (#2709) * add all files * metadata.textproto * update * update changes * add samplestream * Update zr_fec_uncorrectable_frames_test.go Update based on other PR comments * Update zr_fec_uncorrectable_frames_test.go update paramerter * format * implementing comments * TRANSCEIVER-8: Telemetry: 400ZR Optics module temperature streaming. (#2672) * TRANSCEIVER-8: Telemetry: 400ZR Optics module temperature streaming. * correcting file path * implemented review comments * fixing rundata * Add FP test for BGP to ISIS redistribution test with prefix and commu… (#2678) * Add FP test for BGP to ISIS redistribution test with prefix and community based routing policy * updated ondatra version to 0.5.2 * deviation name fixes * Update IP list to include RT-1.32 (#2693) * implemented review comments * added changes to use samplestream lib * fix static check * fix static check * fix static check * fix fmt * fix fmt * fix fmt * fix fmt * implementing comment * implementing comment --------- Co-authored-by: Pramod Maurya Co-authored-by: Calvin F <131898783+cfernanz@users.noreply.github.com> * implementing comment * correcting directory --------- Co-authored-by: Pramod Maurya Co-authored-by: Calvin F <131898783+cfernanz@users.noreply.github.com> Co-authored-by: ming2004 Co-authored-by: Benson Schliesser Co-authored-by: Brandon Stoll Co-authored-by: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Co-authored-by: prinikasn <117314826+prinikasn@users.noreply.github.com> --- .../metadata.textproto | 17 ++ .../zr_laser_bias_current_test.go | 218 ++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 feature/platform/transceiver/tests/zr_laser_bias_current_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go diff --git a/feature/platform/transceiver/tests/zr_laser_bias_current_test/metadata.textproto b/feature/platform/transceiver/tests/zr_laser_bias_current_test/metadata.textproto new file mode 100644 index 00000000000..66bb18f7316 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_laser_bias_current_test/metadata.textproto @@ -0,0 +1,17 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "3559ab05-7b5b-40e5-86d8-63eb0e668c8a" +plan_id: "TRANSCEIVER-9" +description: "Telemetry: 400ZR TX laser bias current telemetry values streaming." +testbed: TESTBED_DUT_400ZR +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + missing_port_to_optical_channel_component_mapping: true + } +} diff --git a/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go b/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go new file mode 100644 index 00000000000..57278323887 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go @@ -0,0 +1,218 @@ +// Copyright 2022 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 zr_laser_bias_current_test + +import ( + "fmt" + "reflect" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +const ( + dp16QAM = 1 + targetOutputPower = -10 + frequency = 193100000 +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// Topology: +// dut:port1 <--> port2:dut +// + +func verifyLaserBiasCurrent(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[float64], sensorName string) float64 { + laserBias := pStream.Next(t) + if laserBias == nil { + t.Fatalf("laserBias telemetry %q was not streamed in the most recent subscription interval", sensorName) + } + laserBiasVal, ok := laserBias.Val() + if !ok { + t.Fatalf("LaserBias %q telemetry is not present", sensorName) + } + if reflect.TypeOf(laserBiasVal).Kind() != reflect.Float64 { + t.Errorf("Return value is not type float64") + } + if laserBiasVal <= 0 && laserBiasVal >= 131 { + t.Errorf("The laser bias value is not between 0 and 131") + } + t.Logf("laserBias value: %f", laserBiasVal) + return laserBiasVal +} + +func verifyLaserBiasCurrentAll(t *testing.T, dut1 *ondatra.DUTDevice, pStreamInstant *samplestream.SampleStream[float64], pStreamAvg *samplestream.SampleStream[float64], pStreamMax *samplestream.SampleStream[float64], pStreamMin *samplestream.SampleStream[float64]) { + laserbiasInstant := verifyLaserBiasCurrent(t, dut1, pStreamInstant, "laserbiasInstant") + t.Logf("laserBias Instant value: %f", laserbiasInstant) + laserbiasMin := verifyLaserBiasCurrent(t, dut1, pStreamMin, "laserbiasMin") + t.Logf("laserBias Min value: %f", laserbiasMin) + laserbiasMax := verifyLaserBiasCurrent(t, dut1, pStreamMax, "laserbiasMax") + t.Logf("laserBias Max value: %f", laserbiasMax) + laserbiasAvg := verifyLaserBiasCurrent(t, dut1, pStreamAvg, "laserbiasAvg") + t.Logf("laserBias Avg value: %f", laserbiasAvg) + if laserbiasAvg >= laserbiasMin && laserbiasAvg <= laserbiasMax { + t.Logf("The average is between the maximum and minimum values") + } else { + t.Fatalf("The average is not between the maximum and minimum values Avg:%f Min:%f Max:%f", laserbiasAvg, laserbiasMin, laserbiasMax) + } +} +func interfaceConfig(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port) { + d := &oc.Root{} + i := d.GetOrCreateInterface(dp.Name()) + i.Enabled = ygot.Bool(true) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp.Name()).Config(), i) + OCcomponent := opticalChannelComponentFromPort(t, dut1, dp) + gnmi.Replace(t, dut1, gnmi.OC().Component(OCcomponent).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(targetOutputPower), + Frequency: ygot.Uint64(frequency), + }) +} +func TestZRLaserBiasCurrentState(t *testing.T) { + dut1 := ondatra.DUT(t, "dut") + dp1 := dut1.Port(t, "port1") + dp2 := dut1.Port(t, "port2") + t.Logf("dut1: %v", dut1) + t.Logf("dut1 dp1 name: %v", dp1.Name()) + interfaceConfig(t, dut1, dp1) + interfaceConfig(t, dut1, dp2) + intUpdateTime := 2 * time.Minute + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) + transceiverState := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) + if dp1.PMD() != ondatra.PMD400GBASEZR { + t.Fatalf("%s Transceiver is not 400ZR its of type: %v", transceiverState, dp1.PMD()) + } + OCcomponent := opticalChannelComponentFromPort(t, dut1, dp1) + component1 := gnmi.OC().Component(OCcomponent) + p1StreamInstant := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Instant().State(), 10*time.Second) + p1StreamMin := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Min().State(), 10*time.Second) + p1StreamMax := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Max().State(), 10*time.Second) + p1StreamAvg := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Avg().State(), 10*time.Second) + defer p1StreamAvg.Close() + defer p1StreamMax.Close() + defer p1StreamMin.Close() + defer p1StreamInstant.Close() + verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) +} +func TestZRLaserBiasCurrentStateInterface_Flap(t *testing.T) { + dut1 := ondatra.DUT(t, "dut") + dp1 := dut1.Port(t, "port1") + dp2 := dut1.Port(t, "port2") + t.Logf("dut1: %v", dut1) + t.Logf("dut1 dp1 name: %v", dp1.Name()) + interfaceConfig(t, dut1, dp1) + interfaceConfig(t, dut1, dp2) + intUpdateTime := 2 * time.Minute + // Check interface is up + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) + // Check if TRANSCEIVER is of type 400ZR + transceiverState := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) + if dp1.PMD() != ondatra.PMD400GBASEZR { + t.Fatalf("%s Transceiver is not 400ZR its of type: %v", transceiverState, dp1.PMD()) + } + // Disable interface + d := &oc.Root{} + i := d.GetOrCreateInterface(dp1.Name()) + i.Enabled = ygot.Bool(false) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Config(), i) + OCcomponent := opticalChannelComponentFromPort(t, dut1, dp1) + component1 := gnmi.OC().Component(OCcomponent) + p1StreamInstant := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Instant().State(), 10*time.Second) + p1StreamMin := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Min().State(), 10*time.Second) + p1StreamMax := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Max().State(), 10*time.Second) + p1StreamAvg := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Avg().State(), 10*time.Second) + defer p1StreamInstant.Close() + defer p1StreamMin.Close() + defer p1StreamMax.Close() + defer p1StreamAvg.Close() + verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + // Wait 120 sec cooling off period + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_DOWN) + // Enable interface + verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + i.Enabled = ygot.Bool(true) + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Config(), i) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) + verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) +} +func TestZRLaserBiasCurrentStateTransceiverOnOff(t *testing.T) { + dut1 := ondatra.DUT(t, "dut") + dp1 := dut1.Port(t, "port1") + dp2 := dut1.Port(t, "port2") + t.Logf("dut1: %v", dut1) + t.Logf("dut1 dp1 name: %v", dp1.Name()) + interfaceConfig(t, dut1, dp1) + interfaceConfig(t, dut1, dp2) + intUpdateTime := 2 * time.Minute + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) + transceiverState := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) + // Check if TRANSCEIVER is of type 400ZR + if dp1.PMD() != ondatra.PMD400GBASEZR { + t.Fatalf("%s Transceiver is not 400ZR its of type: %v", transceiverState, dp1.PMD()) + } + OCcomponent := opticalChannelComponentFromPort(t, dut1, dp1) + component1 := gnmi.OC().Component(OCcomponent) + p1StreamInstant := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Instant().State(), 10*time.Second) + p1StreamMin := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Min().State(), 10*time.Second) + p1StreamMax := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Max().State(), 10*time.Second) + p1StreamAvg := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Avg().State(), 10*time.Second) + defer p1StreamInstant.Close() + defer p1StreamMin.Close() + defer p1StreamMax.Close() + defer p1StreamAvg.Close() + // Disable interface transceiver power off + gnmi.Update(t, dut1, gnmi.OC().Component(dp1.Name()).Transceiver().Enabled().Config(), false) + verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + // Enable interface transceiver power on + gnmi.Update(t, dut1, gnmi.OC().Component(dp1.Name()).Transceiver().Enabled().Config(), true) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) + verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) +} +func opticalChannelComponentFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { + t.Helper() + if deviations.MissingPortToOpticalChannelMapping(dut) { + switch dut.Vendor() { + case ondatra.ARISTA: + transceiverState := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).Transceiver().State()) + return fmt.Sprintf("%s-Optical0", transceiverState) + default: + t.Fatal("Manual Optical channel name required when deviation missing_port_to_optical_channel_component_mapping applied.") + } + } + compName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).HardwarePort().State()) + for { + comp, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(compName).State()).Val() + if !ok { + t.Fatalf("Recursive optical channel lookup failed for port: %s, component %s not found.", p.Name(), compName) + } + if comp.GetType() == oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL { + return compName + } + if comp.GetParent() == "" { + t.Fatalf("Recursive optical channel lookup failed for port: %s, parent of component %s not found.", p.Name(), compName) + } + compName = comp.GetParent() + } +} From 7751aad5270ee6ee0c8d259a8902c9cf16162e42 Mon Sep 17 00:00:00 2001 From: Marc Charlebois <105758144+MarcCharlebois@users.noreply.github.com> Date: Mon, 11 Mar 2024 04:57:57 -0700 Subject: [PATCH 06/97] RT-1.4 ATE Native ACL Fix (#2774) "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --- .../bgp_graceful_restart_test.go | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go b/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go index 545290eba11..207b9ffe4be 100644 --- a/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go +++ b/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go @@ -479,11 +479,13 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { "drop": map[string]any{}, }, "match": map[string]any{ - "destination-ip": map[string]any{ - "prefix": ateDstCIDR, - }, - "source-ip": map[string]any{ - "prefix": aclNullPrefix, + "ipv4": map[string]any{ + "destination-ip": map[string]any{ + "prefix": ateDstCIDR, + }, + "source-ip": map[string]any{ + "prefix": aclNullPrefix, + }, }, }, }, @@ -499,11 +501,13 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { "drop": map[string]any{}, }, "match": map[string]any{ - "source-ip": map[string]any{ - "prefix": ateDstCIDR, - }, - "destination-ip": map[string]any{ - "prefix": aclNullPrefix, + "ipv4": map[string]any{ + "source-ip": map[string]any{ + "prefix": ateDstCIDR, + }, + "destination-ip": map[string]any{ + "prefix": aclNullPrefix, + }, }, }, }, @@ -519,11 +523,13 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { "accept": map[string]any{}, }, "match": map[string]any{ - "source-ip": map[string]any{ - "prefix": aclNullPrefix, - }, - "destination-ip": map[string]any{ - "prefix": aclNullPrefix, + "ipv4": map[string]any{ + "source-ip": map[string]any{ + "prefix": aclNullPrefix, + }, + "destination-ip": map[string]any{ + "prefix": aclNullPrefix, + }, }, }, }, @@ -534,14 +540,14 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { } gpbSetRequest := &gpb.SetRequest{ Prefix: &gpb.Path{ - Origin: "srl", + Origin: "native", }, Update: []*gpb.Update{ { Path: &gpb.Path{ Elem: []*gpb.PathElem{ {Name: "acl"}, - {Name: "ipv4-filter", Key: map[string]string{"name": name}}, + {Name: "acl-filter", Key: map[string]string{"name": name, "type": "ipv4"}}, {Name: "entry", Key: map[string]string{"sequence-id": "10"}}, }, }, @@ -555,7 +561,7 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { Path: &gpb.Path{ Elem: []*gpb.PathElem{ {Name: "acl"}, - {Name: "ipv4-filter", Key: map[string]string{"name": name}}, + {Name: "acl-filter", Key: map[string]string{"name": name, "type": "ipv4"}}, {Name: "entry", Key: map[string]string{"sequence-id": "20"}}, }, }, @@ -569,7 +575,7 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { Path: &gpb.Path{ Elem: []*gpb.PathElem{ {Name: "acl"}, - {Name: "ipv4-filter", Key: map[string]string{"name": name}}, + {Name: "acl-filter", Key: map[string]string{"name": name, "type": "ipv4"}}, {Name: "entry", Key: map[string]string{"sequence-id": "30"}}, }, }, @@ -598,20 +604,20 @@ func configAdmitAllACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { case ondatra.NOKIA: gpbDelRequest := &gpb.SetRequest{ Prefix: &gpb.Path{ - Origin: "srl", + Origin: "native", }, Delete: []*gpb.Path{ { Elem: []*gpb.PathElem{ {Name: "acl"}, - {Name: "ipv4-filter", Key: map[string]string{"name": name}}, + {Name: "acl-filter", Key: map[string]string{"name": name, "type": "ipv4"}}, {Name: "entry", Key: map[string]string{"sequence-id": "10"}}, }, }, { Elem: []*gpb.PathElem{ {Name: "acl"}, - {Name: "ipv4-filter", Key: map[string]string{"name": name}}, + {Name: "acl-filter", Key: map[string]string{"name": name, "type": "ipv4"}}, {Name: "entry", Key: map[string]string{"sequence-id": "20"}}, }, }, @@ -635,8 +641,9 @@ func configACLInterfaceNative(t *testing.T, d *ondatra.DUTDevice, ifName string) case ondatra.NOKIA: var interfaceAclVal = []any{ map[string]any{ - "ipv4-filter": []any{ - aclName, + "acl-filter": map[string]any{ + "name": aclName, + "type": "ipv4", }, }, } @@ -646,15 +653,14 @@ func configACLInterfaceNative(t *testing.T, d *ondatra.DUTDevice, ifName string) } gpbSetRequest := &gpb.SetRequest{ Prefix: &gpb.Path{ - Origin: "srl", + Origin: "native", }, Update: []*gpb.Update{ { Path: &gpb.Path{ Elem: []*gpb.PathElem{ - {Name: "interface", Key: map[string]string{"name": ifName}}, - {Name: "subinterface", Key: map[string]string{"index": "0"}}, {Name: "acl"}, + {Name: "interface", Key: map[string]string{"interface-id": ifName + ".0"}}, {Name: "input"}, }, }, From 12fba0178e658480930d78fd97ebb518dea86e4d Mon Sep 17 00:00:00 2001 From: ahsaanyousaf <46231245+ahsaanyousaf@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:33:47 -0700 Subject: [PATCH 07/97] Update zr_input_output_power_test. (#2776) --- .../tests/zr_input_output_power_test/README.MD | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/feature/platform/transceiver/tests/zr_input_output_power_test/README.MD b/feature/platform/transceiver/tests/zr_input_output_power_test/README.MD index 5cd87b500b5..0a6fbcdf506 100644 --- a/feature/platform/transceiver/tests/zr_input_output_power_test/README.MD +++ b/feature/platform/transceiver/tests/zr_input_output_power_test/README.MD @@ -53,8 +53,8 @@ power. are available for streaming. * RX Input and TX output power values must always be of type decimal64. - When link interfaces are in down state 0 must be reported as a valid - value. + When link interfaces are in down state RX Input power of -40 dbm must be + reported as a valid value. **Note:** For min, max, and avg values, 10 second sampling is preferred. If 10 seconds is not supported, the sampling interval used must be @@ -76,7 +76,7 @@ power. * Verify the ZR optics RX input and TX output power telemetry values are updated to the value in the normal range again. * Typical min/max value range for RX Signal Power -14 to 0 dbm. - * Typical min/max value range for TX Output Power -13 to -9 dbm. + * Typical min/max value range for TX Output Power -10 to -6 dbm. ## TRANSCEIVER-4.4 @@ -95,7 +95,7 @@ power. * Verify the ZR optics RX input and TX output power telemetry values are updated to the value in the normal range again. * Typical min/max value range for RX Signal Power -14 to 0 dbm. - * Typical min/max value range for TX Output Power -13 to -9 dbm. + * Typical min/max value range for TX Output Power -10 to -6 dbm. ## Config Parameter coverage From 07055416fd63b7701bde60405e9127e30f90427f Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Tue, 12 Mar 2024 10:01:56 +0530 Subject: [PATCH 08/97] updated bgp util to take input ports to configure bgp (#2787) --- .../route_summary_counters_test.go | 2 +- .../bgp_isis_redistribution_test.go | 4 +- .../bgp_multipath_ecmp_test.go | 4 +- .../bgp_multipath_wecmp_test.go | 4 +- .../aspath_and_community_test.go | 8 +- .../otg_tests/aspath_test/aspath_test.go | 8 +- .../community_test/community_test.go | 8 +- internal/cfgplugins/bgp.go | 249 ++++++++++-------- 8 files changed, 153 insertions(+), 134 deletions(-) diff --git a/feature/aft/aft_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go b/feature/aft/aft_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go index ee6193d047e..6d8a28e7880 100644 --- a/feature/aft/aft_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go +++ b/feature/aft/aft_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go @@ -339,7 +339,7 @@ func (d *dutData) Configure(t *testing.T, dut *ondatra.DUTDevice) { if !d.ipv4 { aftType = oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST } - bgpOC := cfgplugins.BuildBGPOCConfig(t, dut, d.routerID, aftType, d.neighborConfig) + bgpOC := cfgplugins.BuildBGPOCConfig(t, dut, d.routerID, []oc.E_BgpTypes_AFI_SAFI_TYPE{aftType}, d.neighborConfig) for _, a := range []attrs.Attributes{dutPort1, dutPort2} { ocName := dut.Port(t, a.Name).Name() diff --git a/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go b/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go index b732a371bf0..4778afbec5b 100644 --- a/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go +++ b/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go @@ -39,8 +39,8 @@ const ( bgpName = "BGP" maskLenExact = "exact" dummyAS = uint32(64655) - dutAS = uint32(65656) - ateAS = uint32(65657) + dutAS = uint32(64656) + ateAS = uint32(64657) v4Route = "203.10.113.0" v4TrafficStart = "203.10.113.1" v4DummyRoute = "192.51.100.0" diff --git a/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go b/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go index df68aa2f1e0..9af13da3fdd 100644 --- a/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go +++ b/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go @@ -167,8 +167,8 @@ func TestBGPSetup(t *testing.T) { for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount4) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, true, !tc.enableMultiAS) + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount4, nil) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST}, []string{"port2", "port3", "port4"}, true, !tc.enableMultiAS) dni := deviations.DefaultNetworkInstance(bs.DUT) bgp := bs.DUTConf.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() gEBGP := bgp.GetOrCreateGlobal().GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().GetOrCreateEbgp() diff --git a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go index 5a8a21640a7..a83268751d1 100644 --- a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go +++ b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go @@ -141,8 +141,8 @@ func verifyECMPLoadBalance(t *testing.T, ate *ondatra.ATEDevice, pc int, expecte } func TestBGPSetup(t *testing.T) { - bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount4) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, true, false) + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount4, nil) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST}, []string{"port3", "port4"}, true, false) dni := deviations.DefaultNetworkInstance(bs.DUT) bgp := bs.DUTConf.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() gEBGP := bgp.GetOrCreateGlobal().GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().GetOrCreateEbgp() diff --git a/feature/bgp/policybase/otg_tests/aspath_and_community_test/aspath_and_community_test.go b/feature/bgp/policybase/otg_tests/aspath_and_community_test/aspath_and_community_test.go index e08a901bdaf..4394d2c4248 100644 --- a/feature/bgp/policybase/otg_tests/aspath_and_community_test/aspath_and_community_test.go +++ b/feature/bgp/policybase/otg_tests/aspath_and_community_test/aspath_and_community_test.go @@ -15,7 +15,6 @@ package aspath_and_community_test import ( - "sort" "testing" "time" @@ -139,8 +138,6 @@ func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string } devices := bs.ATETop.Devices().Items() - byName := func(i, j int) bool { return devices[i].Name() < devices[j].Name() } - sort.Slice(devices, byName) ipv4 := devices[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0] bgp4Peer := devices[1].Bgp().Ipv4Interfaces().Items()[0].Peers().Items()[0] @@ -243,9 +240,8 @@ func verifyTraffic(t *testing.T, ate *ondatra.ATEDevice, ports int, testResults func TestCommunitySet(t *testing.T) { testResults := [5]bool{true, true, true, false, false} - bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, true, true) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST, true, true) + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{"port2"}, true, true) configureOTG(t, bs, prefixesV4, prefixesV6) bs.PushAndStart(t) diff --git a/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go b/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go index b5b05f93d94..31d36dc6c63 100644 --- a/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go +++ b/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go @@ -15,7 +15,6 @@ package aspath_test import ( - "sort" "testing" "time" @@ -91,8 +90,6 @@ func configureImportBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string, prefixesV6 [][]string, aspathMembers [][]uint32) { devices := bs.ATETop.Devices().Items() - byName := func(i, j int) bool { return devices[i].Name() < devices[j].Name() } - sort.Slice(devices, byName) ipv4 := devices[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0] bgp4Peer := devices[1].Bgp().Ipv4Interfaces().Items()[0].Peers().Items()[0] @@ -187,9 +184,8 @@ type testCase struct { } func TestCommunitySet(t *testing.T) { - bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, true, true) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST, true, true) + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{"port2"}, true, true) var aspathMembers = [][]uint32{ {100, 200, 300}, diff --git a/feature/bgp/policybase/otg_tests/community_test/community_test.go b/feature/bgp/policybase/otg_tests/community_test/community_test.go index 940e69e8ba6..01a2f5b9c14 100644 --- a/feature/bgp/policybase/otg_tests/community_test/community_test.go +++ b/feature/bgp/policybase/otg_tests/community_test/community_test.go @@ -15,7 +15,6 @@ package community_test import ( - "sort" "testing" "time" @@ -97,8 +96,6 @@ func configureImportBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string, prefixesV6 [][]string, communityMembers [][][]int) { devices := bs.ATETop.Devices().Items() - byName := func(i, j int) bool { return devices[i].Name() < devices[j].Name() } - sort.Slice(devices, byName) ipv4 := devices[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0] bgp4Peer := devices[1].Bgp().Ipv4Interfaces().Items()[0].Peers().Items()[0] @@ -201,9 +198,8 @@ type testCase struct { } func TestCommunitySet(t *testing.T) { - bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, true, true) - bs.WithEBGP(t, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST, true, true) + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{"port2"}, true, true) var communityMembers = [][][]int{ { diff --git a/internal/cfgplugins/bgp.go b/internal/cfgplugins/bgp.go index 23815ee23f6..62f00216b0e 100644 --- a/internal/cfgplugins/bgp.go +++ b/internal/cfgplugins/bgp.go @@ -41,15 +41,15 @@ const ( RPLPermitAll = "PERMIT-ALL" // DutAS dut AS - DutAS = uint32(65656) + DutAS = uint32(65501) // AteAS1 for ATE port1 - AteAS1 = uint32(65536) + AteAS1 = uint32(65511) // AteAS2 for ATE port2 - AteAS2 = uint32(65537) + AteAS2 = uint32(65512) // AteAS3 for ATE port3 - AteAS3 = uint32(65538) + AteAS3 = uint32(65513) // AteAS4 for ATE port4 - AteAS4 = uint32(65539) + AteAS4 = uint32(65514) // BGPPeerGroup1 for ATE port1 BGPPeerGroup1 = "BGP-PEER-GROUP1" @@ -149,15 +149,16 @@ type BGPSession struct { DUTConf *oc.Root ATETop gosnappi.Config - DUTPorts []*attrs.Attributes - ATEPorts []*attrs.Attributes - aftType oc.E_BgpTypes_AFI_SAFI_TYPE + DUTPorts []*attrs.Attributes + ATEPorts []*attrs.Attributes + afiTypes []oc.E_BgpTypes_AFI_SAFI_TYPE + networkInstance string } // NewBGPSession creates a new BGPSession using the default global config, and // configures the interfaces on the dut and the ate based in given topology port count. // Only supports 2 and 4 port DUT-ATE topology -func NewBGPSession(t *testing.T, pc PortCount) *BGPSession { +func NewBGPSession(t *testing.T, pc PortCount, ni *string) *BGPSession { conf := &BGPSession{ DUT: ondatra.DUT(t, "dut"), DUTConf: &oc.Root{}, @@ -186,15 +187,25 @@ func NewBGPSession(t *testing.T, pc PortCount) *BGPSession { conf.ATEIntfs[i] = conf.ATEPorts[i].AddToOTG(conf.ATETop, conf.OndatraATEPorts[i], conf.DUTPorts[i]) } } + + if ni == nil { + fptest.ConfigureDefaultNetworkInstance(t, conf.DUT) + conf.networkInstance = deviations.DefaultNetworkInstance(conf.DUT) + } else { + conf.networkInstance = *ni + } + return conf } // WithEBGP adds eBGP specific config -func (bs *BGPSession) WithEBGP(t *testing.T, aftype oc.E_BgpTypes_AFI_SAFI_TYPE, isSamePG, isSameAS bool) *BGPSession { - if aftype != oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST && aftype != oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST { - t.Fatalf("Unsupported AFI type: %v", bs.aftType) +func (bs *BGPSession) WithEBGP(t *testing.T, afiTypes []oc.E_BgpTypes_AFI_SAFI_TYPE, bgpPorts []string, isSamePG, isSameAS bool) *BGPSession { + for _, afiType := range afiTypes { + if afiType != oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST && afiType != oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST { + t.Fatalf("Unsupported AFI type: %v", afiType) + } } - bs.aftType = aftype + bs.afiTypes = afiTypes asNumbers := []uint32{AteAS1, AteAS2, AteAS3, AteAS4} if isSameAS { @@ -205,34 +216,36 @@ func (bs *BGPSession) WithEBGP(t *testing.T, aftype oc.E_BgpTypes_AFI_SAFI_TYPE, byName := func(i, j int) bool { return devices[i].Name() < devices[j].Name() } sort.Slice(devices, byName) for i, otgPort := range bs.ATEPorts { + if !containsValue(bgpPorts, otgPort.Name) { + continue + } bgp := devices[i].Bgp().SetRouterId(otgPort.IPv4) - switch aftype { - case oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST: - ipv4 := devices[i].Ethernets().Items()[0].Ipv4Addresses().Items()[0] - bgp4Peer := bgp.Ipv4Interfaces().Add().SetIpv4Name(ipv4.Name()).Peers().Add().SetName(devices[i].Name() + ".BGP4.peer") - bgp4Peer.SetPeerAddress(ipv4.Gateway()) - bgp4Peer.SetAsNumber(uint32(asNumbers[i])) - bgp4Peer.SetAsType(gosnappi.BgpV4PeerAsType.EBGP) - bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) - bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) - case oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: - ipv6 := devices[i].Ethernets().Items()[0].Ipv6Addresses().Items()[0] - bgp6Peer := bgp.Ipv6Interfaces().Add().SetIpv6Name(ipv6.Name()).Peers().Add().SetName(devices[i].Name() + ".BGP6.peer") - bgp6Peer.SetPeerAddress(ipv6.Gateway()) - bgp6Peer.SetAsNumber(uint32(asNumbers[i])) - bgp6Peer.SetAsType(gosnappi.BgpV6PeerAsType.EBGP) - bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true).SetExtendedNextHopEncoding(true) - bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + for _, afiType := range afiTypes { + switch afiType { + case oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST: + ipv4 := devices[i].Ethernets().Items()[0].Ipv4Addresses().Items()[0] + bgp4Peer := bgp.Ipv4Interfaces().Add().SetIpv4Name(ipv4.Name()).Peers().Add().SetName(devices[i].Name() + ".BGP4.peer") + bgp4Peer.SetPeerAddress(ipv4.Gateway()) + bgp4Peer.SetAsNumber(uint32(asNumbers[i])) + bgp4Peer.SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + case oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: + ipv6 := devices[i].Ethernets().Items()[0].Ipv6Addresses().Items()[0] + bgp6Peer := bgp.Ipv6Interfaces().Add().SetIpv6Name(ipv6.Name()).Peers().Add().SetName(devices[i].Name() + ".BGP6.peer") + bgp6Peer.SetPeerAddress(ipv6.Gateway()) + bgp6Peer.SetAsNumber(uint32(asNumbers[i])) + bgp6Peer.SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true).SetExtendedNextHopEncoding(true) + bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + } } } - dni := bs.DUTConf.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(bs.DUT)) - dni.SetType(oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) - - niProtocol := dni.GetOrCreateProtocol(PTBGP, bgpName) - neighborConfig := BuildNeigborConfig(isSamePG, isSameAS, len(bs.DUTPorts)) - niProtocol.Bgp = BuildBGPOCConfig(t, bs.DUT, dutPort1.IPv4, aftype, neighborConfig) + niProtocol := bs.DUTConf.GetOrCreateNetworkInstance(bs.networkInstance).GetOrCreateProtocol(PTBGP, bgpName) + neighborConfig := bs.buildNeigborConfig(isSamePG, isSameAS, bgpPorts) + niProtocol.Bgp = BuildBGPOCConfig(t, bs.DUT, dutPort1.IPv4, afiTypes, neighborConfig) err := bs.configureRoutingPolicy() if err != nil { @@ -273,7 +286,7 @@ func (bs *BGPSession) PushDUT(t testing.TB) error { if deviations.ExplicitInterfaceInDefaultVRF(bs.DUT) { for i := 0; i < len(bs.DUTPorts); i++ { - fptest.AssignToNetworkInstance(t, bs.DUT, bs.OndatraDUTPorts[i].Name(), deviations.DefaultNetworkInstance(bs.DUT), 0) + fptest.AssignToNetworkInstance(t, bs.DUT, bs.OndatraDUTPorts[i].Name(), bs.networkInstance, 0) } } if deviations.ExplicitPortSpeed(bs.DUT) { @@ -291,11 +304,13 @@ func (bs *BGPSession) PushAndStartATE(t testing.TB) { otg.PushConfig(t, bs.ATETop) otg.StartProtocols(t) - switch bs.aftType { - case oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST: - otgutils.WaitForARP(t.(*testing.T), otg, bs.ATETop, "IPv4") - case oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: - otgutils.WaitForARP(t.(*testing.T), otg, bs.ATETop, "IPv6") + for _, afiType := range bs.afiTypes { + switch afiType { + case oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST: + otgutils.WaitForARP(t.(*testing.T), otg, bs.ATETop, "IPv4") + case oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: + otgutils.WaitForARP(t.(*testing.T), otg, bs.ATETop, "IPv6") + } } } @@ -334,74 +349,74 @@ func VerifyOTGBGPEstablished(t *testing.T, ate *ondatra.ATEDevice) { // NeighborConfig to hold neighbor specific config type NeighborConfig struct { + Name string IPv4Neighbor string IPv6Neighbor string PeerGroup string AS uint32 } -// BuildNeigborConfig builds neighbor config based on given flags -func BuildNeigborConfig(isSamePG, isSameAS bool, portCount int) []*NeighborConfig { - nc := []*NeighborConfig{ - { - IPv4Neighbor: atePort1.IPv4, - IPv6Neighbor: atePort1.IPv6, - PeerGroup: BGPPeerGroup1, - AS: AteAS1, - }, - { - IPv4Neighbor: atePort2.IPv4, - IPv6Neighbor: atePort2.IPv6, - PeerGroup: BGPPeerGroup2, - AS: AteAS2, - }, - } - - if portCount == int(PortCount4) { - nc = append( - nc, - &NeighborConfig{ - IPv4Neighbor: atePort3.IPv4, - IPv6Neighbor: atePort3.IPv6, - PeerGroup: BGPPeerGroup3, - AS: AteAS3, - }, - &NeighborConfig{ - IPv4Neighbor: atePort4.IPv4, - IPv6Neighbor: atePort4.IPv6, - PeerGroup: BGPPeerGroup4, - AS: AteAS4, - }, - ) +// buildNeigborConfig builds neighbor config based on given flags +func (bs *BGPSession) buildNeigborConfig(isSamePG, isSameAS bool, bgpPorts []string) []*NeighborConfig { + nc1 := &NeighborConfig{ + Name: "port1", + IPv4Neighbor: atePort1.IPv4, + IPv6Neighbor: atePort1.IPv6, + PeerGroup: BGPPeerGroup1, + AS: AteAS1, + } + nc2 := &NeighborConfig{ + Name: "port2", + IPv4Neighbor: atePort2.IPv4, + IPv6Neighbor: atePort2.IPv6, + PeerGroup: BGPPeerGroup2, + AS: AteAS2, + } + nc3 := &NeighborConfig{ + Name: "port3", + IPv4Neighbor: atePort3.IPv4, + IPv6Neighbor: atePort3.IPv6, + PeerGroup: BGPPeerGroup3, + AS: AteAS3, + } + nc4 := &NeighborConfig{ + Name: "port4", + IPv4Neighbor: atePort4.IPv4, + IPv6Neighbor: atePort4.IPv6, + PeerGroup: BGPPeerGroup4, + AS: AteAS4, + } + ncAll := []*NeighborConfig{nc1, nc2, nc3, nc4} + + validNC := []*NeighborConfig{} + for _, nc := range ncAll[:len(bs.DUTPorts)] { + if containsValue(bgpPorts, nc.Name) { + validNC = append(validNC, nc) + } } if isSamePG { - for _, n := range nc { - n.PeerGroup = BGPPeerGroup1 + for _, nc := range validNC { + nc.PeerGroup = BGPPeerGroup1 } } if isSameAS { - for _, n := range nc { - n.AS = AteAS1 + for _, nc := range validNC { + nc.AS = AteAS1 } } - return nc + return validNC } // BuildBGPOCConfig builds the BGP OC config applying global, neighbors and peer-group config -func BuildBGPOCConfig(t *testing.T, dut *ondatra.DUTDevice, routerID string, aftType oc.E_BgpTypes_AFI_SAFI_TYPE, neighborConfig []*NeighborConfig) *oc.NetworkInstance_Protocol_Bgp { - afiSafiGlobal := map[oc.E_BgpTypes_AFI_SAFI_TYPE]*oc.NetworkInstance_Protocol_Bgp_Global_AfiSafi{ - aftType: { - AfiSafiName: aftType, +func BuildBGPOCConfig(t *testing.T, dut *ondatra.DUTDevice, routerID string, afiTypes []oc.E_BgpTypes_AFI_SAFI_TYPE, neighborConfig []*NeighborConfig) *oc.NetworkInstance_Protocol_Bgp { + afiSafiGlobal := map[oc.E_BgpTypes_AFI_SAFI_TYPE]*oc.NetworkInstance_Protocol_Bgp_Global_AfiSafi{} + for _, afiType := range afiTypes { + afiSafiGlobal[afiType] = &oc.NetworkInstance_Protocol_Bgp_Global_AfiSafi{ + AfiSafiName: afiType, Enabled: ygot.Bool(true), - }, - } - afiSafiNeighbor := map[oc.E_BgpTypes_AFI_SAFI_TYPE]*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi{ - aftType: { - AfiSafiName: aftType, - Enabled: ygot.Bool(true), - }, + } } global := &oc.NetworkInstance_Protocol_Bgp_Global{ @@ -414,23 +429,30 @@ func BuildBGPOCConfig(t *testing.T, dut *ondatra.DUTDevice, routerID string, aft peerGroups := make(map[string]*oc.NetworkInstance_Protocol_Bgp_PeerGroup) var neighbor string for _, nc := range neighborConfig { - switch aftType { - case oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST: - neighbor = nc.IPv4Neighbor - case oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: - neighbor = nc.IPv6Neighbor - default: - t.Fatalf("Unsupported AFI type: %v", aftType) - } - - neighbors[neighbor] = &oc.NetworkInstance_Protocol_Bgp_Neighbor{ - PeerAs: ygot.Uint32(nc.AS), - PeerGroup: ygot.String(nc.PeerGroup), - NeighborAddress: ygot.String(neighbor), - AfiSafi: afiSafiNeighbor, + for _, afiType := range afiTypes { + switch afiType { + case oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST: + neighbor = nc.IPv4Neighbor + case oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: + neighbor = nc.IPv6Neighbor + default: + t.Fatalf("Unsupported AFI type: %v", afiType) + } + + neighbors[neighbor] = &oc.NetworkInstance_Protocol_Bgp_Neighbor{ + PeerAs: ygot.Uint32(nc.AS), + PeerGroup: ygot.String(nc.PeerGroup), + NeighborAddress: ygot.String(neighbor), + AfiSafi: map[oc.E_BgpTypes_AFI_SAFI_TYPE]*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi{ + afiType: { + AfiSafiName: afiType, + Enabled: ygot.Bool(true), + }, + }, + } + + peerGroups[nc.PeerGroup] = getPeerGroup(nc.PeerGroup, dut, afiType) } - - peerGroups[nc.PeerGroup] = getPeerGroup(nc.PeerGroup, dut, aftType) } return &oc.NetworkInstance_Protocol_Bgp{ @@ -441,7 +463,7 @@ func BuildBGPOCConfig(t *testing.T, dut *ondatra.DUTDevice, routerID string, aft } // getPeerGroup build peer-config -func getPeerGroup(pgn string, dut *ondatra.DUTDevice, aftype oc.E_BgpTypes_AFI_SAFI_TYPE) *oc.NetworkInstance_Protocol_Bgp_PeerGroup { +func getPeerGroup(pgn string, dut *ondatra.DUTDevice, afiType oc.E_BgpTypes_AFI_SAFI_TYPE) *oc.NetworkInstance_Protocol_Bgp_PeerGroup { bgp := &oc.NetworkInstance_Protocol_Bgp{} pg := bgp.GetOrCreatePeerGroup(pgn) @@ -454,10 +476,19 @@ func getPeerGroup(pgn string, dut *ondatra.DUTDevice, aftype oc.E_BgpTypes_AFI_S } // policy under peer group AFI - afisafi := pg.GetOrCreateAfiSafi(aftype) + afisafi := pg.GetOrCreateAfiSafi(afiType) afisafi.Enabled = ygot.Bool(true) rpl := afisafi.GetOrCreateApplyPolicy() rpl.SetExportPolicy([]string{RPLPermitAll}) rpl.SetImportPolicy([]string{RPLPermitAll}) return pg } + +func containsValue[T comparable](slice []T, value T) bool { + for _, v := range slice { + if v == value { + return true + } + } + return false +} From 3bb8ff714829e7564fcedd3c279bce0e5f922763 Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Mon, 11 Mar 2024 22:07:31 -0700 Subject: [PATCH 09/97] Move cache directory to scratch disk partition (#2783) --- .github/workflows/go.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 66b2f09a11d..6ab972f2897 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -63,6 +63,8 @@ jobs: sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo mv "${HOME}/.cache" /mnt/cache + ln -s /mnt/cache "${HOME}/.cache" - name: Checkout code uses: actions/checkout@v3 - name: Cache From 47dcfd69b1b027d0404b9f35c529f851e4d25194 Mon Sep 17 00:00:00 2001 From: mananpat-cisco Date: Tue, 12 Mar 2024 03:41:10 -0400 Subject: [PATCH 10/97] Gnmi 1.15 deviations (#2202) * gNMI-1.15_deviations * fixes * unset rootOP flag * updated call * rebase * rebase * fixed call following infra change * updated lookup calls to Await * fixes * removed unwanted deviations * addressed deviation comments * incorporated comments * addressed comment * incorported comment * added vendor specific condition, need to check with google if deviation is needed by them --------- Co-authored-by: AmrNJ <155722765+AmrNJ@users.noreply.github.com> --- .../set/tests/gnmi_set_test/gnmi_set_test.go | 374 +++++++++++++++--- .../tests/gnmi_set_test/metadata.textproto | 5 +- internal/deviations/deviations.go | 24 ++ proto/metadata.proto | 12 + proto/metadata_go_proto/metadata.pb.go | 136 +++++-- 5 files changed, 463 insertions(+), 88 deletions(-) diff --git a/feature/system/gnmi/set/tests/gnmi_set_test/gnmi_set_test.go b/feature/system/gnmi/set/tests/gnmi_set_test/gnmi_set_test.go index 5f5d489e81a..8152a803887 100644 --- a/feature/system/gnmi/set/tests/gnmi_set_test/gnmi_set_test.go +++ b/feature/system/gnmi/set/tests/gnmi_set_test/gnmi_set_test.go @@ -15,12 +15,14 @@ package gnmi_set_test import ( + "context" "fmt" "regexp" "strconv" "strings" "sync" "testing" + "time" "flag" @@ -31,6 +33,7 @@ import ( "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" "github.com/openconfig/ondatra/netutil" + "github.com/openconfig/ygnmi/schemaless" "github.com/openconfig/ygnmi/ygnmi" "github.com/openconfig/ygot/ygot" "github.com/openconfig/ygot/ytypes" @@ -53,7 +56,11 @@ var ( pruneQoS = flag.Bool("prune_qos", true, "Prune QoS config.") // Experimental flags that will likely become a deviation. - cannotDeleteVRF = flag.Bool("cannot_delete_vrf", true, "Device cannot delete VRF.") // See "Note about cannotDeleteVRF" below. + cannotDeleteVRF = flag.Bool("cannot_delete_vrf", true, "Device cannot delete VRF.") // See "Note about cannotDeleteVRF" below. + cannotConfigurePortSpeed = flag.Bool("cannot_config_port_speed", false, "Some devices depending on the type of line card may not allow changing port speed, while still supporting the port speed leaf.") + + // Flags to ensure test passes without any dependency to the device config + baseOCConfigIsPresent = flag.Bool("base_oc_config_is_present", false, "No OC config is loaded on router, so Get config on the root returns no data.") ) var ( @@ -74,6 +81,29 @@ var ( } ) +// Options are optional parameters to pass when deleting configs from the collected running config used in removeStatementsBetweenWords +type Options struct { + interfaces []string +} + +// breakout struct parameters define the speed and number of physical channels +type breakout struct { + breakoutSpeed oc.E_IfEthernet_ETHERNET_SPEED + numPhysicalChannels *uint8 +} + +// showRunningConfig gets the running config from the router +func showRunningConfig(t testing.TB, dut *ondatra.DUTDevice) string { + if ondatra.DUT(t, "dut").Vendor() == ondatra.CISCO { + runningConfig, err := dut.RawAPIs().CLI(t).RunCommand(context.Background(), "show running-config") + if err != nil { + t.Fatalf("'show running-config' failed: %v", err) + } + return runningConfig.Output() + } + return "" +} + // Implementation Note // // Tests have three push variants: ItemOp, ContainerOp, and RootOp. @@ -108,8 +138,10 @@ func TestGetSet(t *testing.T) { // Configuring basic interface and network instance as some devices only populate OC after configuration. gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) - gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Type().Config(), - oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) + gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Config(), &oc.NetworkInstance{ + Name: ygot.String(deviations.DefaultNetworkInstance(dut)), + Type: oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE, + }) scope := defaultPushScope(dut) @@ -142,12 +174,12 @@ func TestDeleteInterface(t *testing.T) { op.push(t, dut, config, scope) t.Run("VerifyBeforeDelete", func(t *testing.T) { - v1 := gnmi.Lookup(t, dut, q1) - if got1, ok := v1.Val(); !ok || got1 != want1 { + v1, ok := gnmi.Await(t, dut, q1, 60*time.Second, want1).Val() + if !ok { t.Errorf("State got %v, want %v", v1, want1) } - v2 := gnmi.Lookup(t, dut, q2) - if got2, ok := v2.Val(); !ok || got2 != want2 { + v2, ok := gnmi.Await(t, dut, q2, 60*time.Second, want2).Val() + if !ok { t.Errorf("State got %v, want %v", v2, want2) } }) @@ -157,12 +189,8 @@ func TestDeleteInterface(t *testing.T) { config.DeleteInterface(p1.Name()) config.DeleteInterface(p2.Name()) - for _, iname := range scope.interfaces { - iface := config.GetInterface(iname) - if iface == nil { - config.Interface = nil - - } + if len(config.Interface) == 0 { + config.Interface = nil } op.push(t, dut, config, scope) @@ -208,6 +236,10 @@ func TestReuseIP(t *testing.T) { forEachPushOp(t, dut, func(t *testing.T, op pushOp, config *oc.Root) { t.Log("Initialize") + if deviations.SkipMacaddressCheck(dut) { + *setEthernetFromState = false + } + config.DeleteInterface(p1.Name()) config.DeleteInterface(agg1) configMember(config.GetOrCreateInterface(p1.Name()), agg1, dut) @@ -321,6 +353,10 @@ func TestDeleteNonDefaultVRF(t *testing.T) { config.DeleteInterface(p1.Name()) config.DeleteInterface(p2.Name()) + if deviations.ReorderCallsForVendorCompatibilty(dut) { + op.push(t, dut, config, scope) + } + ip1.ConfigOCInterface(config.GetOrCreateInterface(p1.Name()), dut) ip2.ConfigOCInterface(config.GetOrCreateInterface(p2.Name()), dut) @@ -328,8 +364,8 @@ func TestDeleteNonDefaultVRF(t *testing.T) { ni := config.GetOrCreateNetworkInstance(vrf) ni.Type = oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF - id1 := attachInterface(ni, p1.Name(), 0) - id2 := attachInterface(ni, p2.Name(), 0) + id1 := attachInterface(dut, ni, p1.Name(), 0) + id2 := attachInterface(dut, ni, p2.Name(), 0) op.push(t, dut, config, scope) @@ -341,7 +377,10 @@ func TestDeleteNonDefaultVRF(t *testing.T) { }) t.Log("Cleanup") - + if deviations.ReorderCallsForVendorCompatibilty(dut) { + config.DeleteInterface(p1.Name()) + config.DeleteInterface(p2.Name()) + } config.DeleteNetworkInstance(vrf) op.push(t, dut, config, scope) @@ -369,6 +408,7 @@ func testMoveInterfaceBetweenVRF(t *testing.T, dut *ondatra.DUTDevice, firstVRF, p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") + var id1, id2 string scope := &pushScope{ interfaces: []string{p1.Name(), p2.Name()}, @@ -387,11 +427,18 @@ func testMoveInterfaceBetweenVRF(t *testing.T, dut *ondatra.DUTDevice, firstVRF, config.DeleteNetworkInstance(firstVRF) ni := config.GetOrCreateNetworkInstance(firstVRF) ni.Type = oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF + // add interface to firstVRF + if deviations.ReorderCallsForVendorCompatibilty(dut) { + id1 = attachInterface(dut, ni, p1.Name(), 0) + id2 = attachInterface(dut, ni, p2.Name(), 0) + } } - firstni := config.GetOrCreateNetworkInstance(firstVRF) - id1 := attachInterface(firstni, p1.Name(), 0) - id2 := attachInterface(firstni, p2.Name(), 0) + if !deviations.ReorderCallsForVendorCompatibilty(dut) { + firstni := config.GetOrCreateNetworkInstance(firstVRF) + id1 = attachInterface(dut, firstni, p1.Name(), 0) + id2 = attachInterface(dut, firstni, p2.Name(), 0) + } config.DeleteNetworkInstance(secondVRF) if *cannotDeleteVRF { @@ -404,9 +451,11 @@ func testMoveInterfaceBetweenVRF(t *testing.T, dut *ondatra.DUTDevice, firstVRF, t.Run("VerifyBeforeMove", func(t *testing.T) { verifyInterface(t, dut, p1.Name(), &ip1) verifyInterface(t, dut, p2.Name(), &ip2) - verifyAttachment(t, dut, firstVRF, id1, p1.Name()) - verifyAttachment(t, dut, firstVRF, id2, p2.Name()) - + // verify the added interface to first Non default VRF + if !deviations.ReorderCallsForVendorCompatibilty(dut) || firstVRF != defaultVRF { + verifyAttachment(t, dut, firstVRF, id1, p1.Name()) + verifyAttachment(t, dut, firstVRF, id2, p2.Name()) + } // We don't check /network-instances/network-instance/vlans/vlan/members because // these are for L2 switched ports, not L3 routed ports. }) @@ -416,18 +465,37 @@ func testMoveInterfaceBetweenVRF(t *testing.T, dut *ondatra.DUTDevice, firstVRF, if firstVRF != defaultVRF { // It is not necessary to explicitly remove the interface attachments since the VRF // is being deleted. + // delete interface before deleting NI + if deviations.ReorderCallsForVendorCompatibilty(dut) { + config.DeleteInterface(p1.Name()) + config.DeleteInterface(p2.Name()) + } config.DeleteNetworkInstance(firstVRF) } else { - // Remove just the interface attachments but keep the VRF. - firstni.DeleteInterface(id1) - firstni.DeleteInterface(id2) + // Delete interface from default NI before modifying the attachement + if deviations.ReorderCallsForVendorCompatibilty(dut) { + config.DeleteInterface(p1.Name()) + config.DeleteInterface(p2.Name()) + } else { + // Remove just the interface attachments but keep the VRF. + firstni := config.GetOrCreateNetworkInstance(firstVRF) + firstni.DeleteInterface(id1) + firstni.DeleteInterface(id2) + } } + op.push(t, dut, config, scope) secondni := config.GetOrCreateNetworkInstance(secondVRF) secondni.Type = oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF - attachInterface(secondni, p1.Name(), 0) - attachInterface(secondni, p2.Name(), 0) - + if deviations.ReorderCallsForVendorCompatibilty(dut) { + id1 = attachInterface(dut, secondni, p1.Name(), 0) + id2 = attachInterface(dut, secondni, p2.Name(), 0) + ip1.ConfigOCInterface(config.GetOrCreateInterface(p1.Name()), dut) + ip2.ConfigOCInterface(config.GetOrCreateInterface(p2.Name()), dut) + } else { + attachInterface(dut, secondni, p1.Name(), 0) + attachInterface(dut, secondni, p2.Name(), 0) + } op.push(t, dut, config, scope) t.Run("VerifyAfterMove", func(t *testing.T) { @@ -438,7 +506,11 @@ func testMoveInterfaceBetweenVRF(t *testing.T, dut *ondatra.DUTDevice, firstVRF, }) t.Log("Cleanup") - + // delete interface before deleting NI + if deviations.ReorderCallsForVendorCompatibilty(dut) { + config.DeleteInterface(p1.Name()) + config.DeleteInterface(p2.Name()) + } config.DeleteNetworkInstance(secondVRF) op.push(t, dut, config, scope) @@ -447,6 +519,9 @@ func testMoveInterfaceBetweenVRF(t *testing.T, dut *ondatra.DUTDevice, firstVRF, func TestStaticProtocol(t *testing.T) { dut := ondatra.DUT(t, "dut") + if deviations.SkipContainerOp(dut) { + *skipContainerOp = true + } if deviations.StaticRouteNextHopInterfaceRefUnsupported(dut) { t.Skip() } @@ -487,8 +562,8 @@ func TestStaticProtocol(t *testing.T) { otherni := config.GetOrCreateNetworkInstance(otherVRF) otherni.Type = oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF - id1 := attachInterface(otherni, p1.Name(), 0) - id2 := attachInterface(otherni, p2.Name(), 0) + id1 := attachInterface(dut, otherni, p1.Name(), 0) + id2 := attachInterface(dut, otherni, p2.Name(), 0) protocol := otherni.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, staticName) @@ -600,7 +675,11 @@ func TestStaticProtocol(t *testing.T) { }) t.Log("Cleanup") - + // delete interface before deleting NI + if deviations.ReorderCallsForVendorCompatibilty(dut) { + config.DeleteInterface(p1.Name()) + config.DeleteInterface(p2.Name()) + } config.DeleteNetworkInstance(otherVRF) config.DeleteNetworkInstance(unusedVRF) op.push(t, dut, config, scope) @@ -673,8 +752,8 @@ func configAggregate(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevic func verifyMember(t testing.TB, p *ondatra.Port, aggID string) { t.Helper() q := gnmi.OC().Interface(p.Name()).Ethernet().AggregateId().State() - v := gnmi.Lookup(t, p.Device(), q) - if got, ok := v.Val(); !ok || got != aggID { + v, ok := gnmi.Await(t, p.Device(), q, 60*time.Second, aggID).Val() + if !ok { t.Errorf("State got %v, want %v", v, aggID) } } @@ -683,9 +762,9 @@ func verifyMember(t testing.TB, p *ondatra.Port, aggID string) { func verifyAggregate(t testing.TB, dev gnmi.DeviceOrOpts, aggID string, a *attrs.Attributes) { t.Helper() q := gnmi.OC().Interface(aggID).Aggregation().LagType().State() - v := gnmi.Lookup(t, dev, q) const want = oc.IfAggregate_AggregationType_STATIC - if got, ok := v.Val(); !ok || got != want { + v, ok := gnmi.Await(t, dev, q, 60*time.Second, want).Val() + if !ok { t.Errorf("State got %v, want %v", v, want) } verifyInterface(t, dev, aggID, a) @@ -695,8 +774,8 @@ func verifyAggregate(t testing.TB, dev gnmi.DeviceOrOpts, aggID string, a *attrs func verifyInterface(t testing.TB, dev gnmi.DeviceOrOpts, name string, a *attrs.Attributes) { t.Helper() q := gnmi.OC().Interface(name).Subinterface(0).Ipv4().Address(a.IPv4).PrefixLength().State() - v := gnmi.Lookup(t, dev, q) - if got, ok := v.Val(); !ok || got != a.IPv4Len { + v, ok := gnmi.Await(t, dev, q, 60*time.Second, a.IPv4Len).Val() + if !ok { t.Errorf("State got %v, want %v", v, a.IPv4Len) } else { t.Logf("Verified %v", v) @@ -704,12 +783,14 @@ func verifyInterface(t testing.TB, dev gnmi.DeviceOrOpts, name string, a *attrs. } // attachInterface attaches an interface name and subinterface sub to a network instance. -func attachInterface(ni *oc.NetworkInstance, name string, sub int) string { +func attachInterface(dut *ondatra.DUTDevice, ni *oc.NetworkInstance, name string, sub int) string { id := name // Possibly vendor specific? May have to use sub. niface := ni.GetOrCreateInterface(id) niface.Interface = ygot.String(name) niface.Subinterface = ygot.Uint32(uint32(sub)) - id = fmt.Sprintf("%s.%d", id, sub) + if deviations.InterfaceRefInterfaceIDFormat(dut) { + id = fmt.Sprintf("%s.%d", id, sub) + } return id } @@ -718,8 +799,8 @@ func attachInterface(ni *oc.NetworkInstance, name string, sub int) string { func verifyAttachment(t testing.TB, dev gnmi.DeviceOrOpts, vrf string, id string, name string) { t.Helper() q := gnmi.OC().NetworkInstance(vrf).Interface(id).Interface().State() - v := gnmi.Lookup(t, dev, q) - if got, ok := v.Val(); !ok || got != name { + v, ok := gnmi.Await(t, dev, q, 60*time.Second, name).Val() + if !ok { t.Errorf("State got %v, want %v", v, name) } else { t.Logf("Verified %v", v) @@ -789,6 +870,56 @@ func getDeviceConfig(t testing.TB, dev gnmi.DeviceOrOpts) *oc.Root { config := gnmi.Get[*oc.Root](t, dev, gnmi.OC().Config()) fptest.WriteQuery(t, "Untouched", gnmi.OC().Config(), config) + // load the base oc config from the device state when no oc config is loaded + if !*baseOCConfigIsPresent { + if ondatra.DUT(t, "dut").Vendor() == ondatra.CISCO { + intfsState := gnmi.GetAll(t, dev, gnmi.OC().InterfaceAny().State()) + for _, intf := range intfsState { + ygot.PruneConfigFalse(oc.SchemaTree["Interface"], intf) + config.DeleteInterface(intf.GetName()) + if intf.GetName() == "Loopback0" || intf.GetName() == "PTP0/RP1/CPU0/0" || intf.GetName() == "Null0" || intf.GetName() == "PTP0/RP0/CPU0/0" { + continue + } + intf.ForwardingViable = nil + intf.Mtu = nil + intf.HoldTime = nil + if intf.Subinterface != nil { + if intf.Subinterface[0].Ipv6 != nil { + intf.Subinterface[0].Ipv6.Autoconf = nil + } + } + config.AppendInterface(intf) + } + vrfsStates := gnmi.GetAll(t, dev, gnmi.OC().NetworkInstanceAny().State()) + for _, vrf := range vrfsStates { + // only needed for containerOp + if vrf.GetName() == "**iid" { + continue + } + if vrf.GetName() == "DEFAULT" { + config.NetworkInstance = nil + vrf.Interface = nil + for _, ni := range config.NetworkInstance { + ni.Mpls = nil + } + } + ygot.PruneConfigFalse(oc.SchemaTree["NetworkInstance"], vrf) + vrf.Table = nil + vrf.RouteLimit = nil + vrf.Mpls = nil + for _, intf := range vrf.Interface { + intf.AssociatedAddressFamilies = nil + } + for _, protocol := range vrf.Protocol { + for _, routes := range protocol.Static { + routes.Description = nil + } + } + config.AppendNetworkInstance(vrf) + } + } + } + if *pruneComponents { for cname, component := range config.Component { // Keep the port components in order to preserve the breakout-mode config. @@ -810,16 +941,39 @@ func getDeviceConfig(t testing.TB, dev gnmi.DeviceOrOpts) *oc.Root { // Ethernet config may not contain meaningful values if it wasn't explicitly // configured, so use its current state for the config, but prune non-config leaves. intf := gnmi.Get(t, dev, gnmi.OC().Interface(iname).State()) - breakout := config.GetComponent(intf.GetHardwarePort()).GetPort().GetBreakoutMode() e := intf.GetEthernet() - // Set port speed to unknown for non breakout interfaces - if breakout.GetGroup(1) == nil && e != nil { - e.SetPortSpeed(oc.IfEthernet_ETHERNET_SPEED_SPEED_UNKNOWN) + if len(intf.GetHardwarePort()) != 0 { + breakout := config.GetComponent(intf.GetHardwarePort()).GetPort().GetBreakoutMode() + e := intf.GetEthernet() + // Set port speed to unknown for non breakout interfaces + if breakout.GetGroup(1) == nil && e != nil { + e.SetPortSpeed(oc.IfEthernet_ETHERNET_SPEED_SPEED_UNKNOWN) + } } ygot.PruneConfigFalse(oc.SchemaTree["Interface_Ethernet"], e) if e.PortSpeed != 0 && e.PortSpeed != oc.IfEthernet_ETHERNET_SPEED_SPEED_UNKNOWN { iface.Ethernet = e } + // need to set mac address for mgmt interface to nil + if intf.GetName() == "MgmtEth0/RP0/CPU0/0" || intf.GetName() == "MgmtEth0/RP1/CPU0/0" && deviations.SkipMacaddressCheck(ondatra.DUT(t, "dut")) { + e.MacAddress = nil + } + // need to set mac address for bundle interface to nil + if iface.Ethernet.AggregateId != nil && deviations.SkipMacaddressCheck(ondatra.DUT(t, "dut")) { + iface.Ethernet.MacAddress = nil + continue + } + } + } + + if !*cannotConfigurePortSpeed { + for _, iface := range config.Interface { + if iface.GetEthernet() == nil { + continue + } + iface.GetEthernet().PortSpeed = oc.IfEthernet_ETHERNET_SPEED_UNSET + iface.GetEthernet().DuplexMode = oc.Ethernet_DuplexMode_UNSET + iface.GetEthernet().EnableFlowControl = nil } } @@ -887,7 +1041,14 @@ func (op rootOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, _ *p setEthernetFromBase(t, op.base, config) } fptest.WriteQuery(t, "RootOp", gnmi.OC().Config(), config) - gnmi.Replace(t, dev, gnmi.OC().Config(), config) + dut := ondatra.DUT(t, "dut") + if deviations.AddMissingBaseConfigViaCli(dut) { + if ondatra.DUT(t, "dut").Vendor() == ondatra.CISCO { + addMissingConfigForRootReplace(t, dev, config) + } + } else { + gnmi.Replace(t, dev, gnmi.OC().Config(), config) + } } // containerOp pushes config using replace of containers of lists directly under root in @@ -905,6 +1066,22 @@ func (op containerOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, fptest.WriteQuery(t, "ContainerOp", gnmi.OC().Config(), config) batch := &gnmi.SetBatch{} + if deviations.AddMissingBaseConfigViaCli(ondatra.DUT(t, "dut")) { + if ondatra.DUT(t, "dut").Vendor() == ondatra.CISCO { + supContainerConfig := addMissingConfigForContainerReplace(t, dev) + for port, data := range supContainerConfig { + gnmi.Update(t, ondatra.DUT(t, "dut"), gnmi.OC().Component(port).Config(), &oc.Component{ + Name: ygot.String(port), + }) + bmode := &oc.Component_Port_BreakoutMode{} + gp := bmode.GetOrCreateGroup(0) + gp.BreakoutSpeed = data.breakoutSpeed + gp.NumBreakouts = ygot.Uint8(*data.numPhysicalChannels + 1) + bmp := gnmi.OC().Component(port).Port().BreakoutMode() + gnmi.BatchReplace(batch, bmp.Config(), bmode) + } + } + } gnmi.BatchReplace(batch, interfacesQuery, &Interfaces{Interface: config.Interface}) gnmi.BatchReplace(batch, networkInstancesQuery, &NetworkInstances{NetworkInstance: config.NetworkInstance}) batch.Set(t, dev) @@ -1034,3 +1211,106 @@ type NetworkInstances struct { } func (*NetworkInstances) IsYANGGoStruct() {} + +func removeStatementsBetweenWords(inputStr, startWord, endWord string, opts ...*Options) string { + lines := strings.Split(inputStr, "\n") + result := []string{} + betweenWords := false + var start bool + for _, line := range lines { + if strings.HasPrefix(line, startWord) { + if len(opts) != 0 { + for _, opt := range opts { + for _, intf := range opt.interfaces { + if strings.Contains(line, intf) { + start = true + betweenWords = true + continue + } + } + } + } else { + start = true + betweenWords = true + continue + } + } + if strings.HasPrefix(line, endWord) { + betweenWords = false + if start == true { + start = false + continue + } + } + if !betweenWords { + result = append(result, line) + } + } + return strings.Join(result, "\n") +} + +func addMissingConfigForContainerReplace(t testing.TB, dev gnmi.DeviceOrOpts) map[string]breakout { + intfsState := gnmi.GetAll(t, dev, gnmi.OC().InterfaceAny().State()) + breakoutPortsMap := make(map[string]breakout) // which holds map of optic: {BreakoutSpeed:10, NumBreakouts:4} + port := make(map[string]uint8) + var trackspeed oc.E_IfEthernet_ETHERNET_SPEED + + for _, intf := range intfsState { + if intf.HardwarePort == nil || intf.PhysicalChannel == nil { + continue + } + hwp := strings.Split(intf.GetHardwarePort(), "Port")[1] + name := strings.Split(intf.GetName(), "GigE")[1] + channel := strconv.Itoa(int(intf.GetPhysicalChannel()[0])) + + if hwp+"/"+(channel) == name { + var speed oc.E_IfEthernet_ETHERNET_SPEED + + _, keyExists := breakoutPortsMap[intf.GetHardwarePort()] + if !keyExists && speed == oc.IfEthernet_ETHERNET_SPEED_UNSET { + if intf.GetEthernet().PortSpeed.String() == "SPEED_100GB" { + trackspeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB + } else if intf.GetEthernet().PortSpeed.String() == "SPEED_10GB" { + trackspeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_10GB + } + } + + numChannels := make([]*uint8, len(intf.GetPhysicalChannel())) + truncated := uint8(intf.GetPhysicalChannel()[0]) + numChannels[0] = &truncated + + _, keyExists = port[intf.GetHardwarePort()] + if !keyExists { + breakoutPortsMap[intf.GetHardwarePort()] = breakout{numPhysicalChannels: numChannels[0], breakoutSpeed: trackspeed} + port[intf.GetHardwarePort()] = 0 + } + + if port[intf.GetHardwarePort()] < *numChannels[0] { + breakoutPortsMap[intf.GetHardwarePort()] = breakout{numPhysicalChannels: numChannels[0], breakoutSpeed: trackspeed} + port[intf.GetHardwarePort()] = *numChannels[0] + } + } + } + return breakoutPortsMap +} + +func addMissingConfigForRootReplace(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root) { + batch := &gnmi.SetBatch{} + running := showRunningConfig(t, ondatra.DUT(t, "dut")) + //editing config while removing NI and interface since it will be part of another replace call + data := "hostname " + strings.Split(running, "hostname ")[1] + modifiedStr := strings.Replace(data, "\r\n", "\n", -1) + // remove interface config from the running configure + fileString := removeStatementsBetweenWords(modifiedStr, "interface ", "!", &Options{interfaces: []string{"HundredGigE", "FourHundredGigE", "TenGigE", "Bundle-Ether", "Loopback", "MgmtEth0", "FortyGigE", "PTP0/RP"}}) + // remove router static config from the running config + fileString = removeStatementsBetweenWords(fileString, "router static ", "!") + // need to explicitly remove configured NI "BLUE" since it is still present in running config and will overwrite config parameter which doesn't set it + fileString = removeStatementsBetweenWords(fileString, "vrf BLUE", "!") + cliPath, err := schemaless.NewConfig[string]("", "cli") + if err != nil { + t.Fatalf("Failed to create CLI ygnmi query: %v", err) + } + gnmi.BatchReplace(batch, cliPath, fileString) + gnmi.BatchReplace(batch, gnmi.OC().Config(), config) + batch.Set(t, dev) +} diff --git a/feature/system/gnmi/set/tests/gnmi_set_test/metadata.textproto b/feature/system/gnmi/set/tests/gnmi_set_test/metadata.textproto index d6df13be2ef..9fe05d0e4b2 100644 --- a/feature/system/gnmi/set/tests/gnmi_set_test/metadata.textproto +++ b/feature/system/gnmi/set/tests/gnmi_set_test/metadata.textproto @@ -10,7 +10,10 @@ platform_exceptions: { vendor: CISCO } deviations: { - ipv4_missing_enabled: true + skip_container_op: true + reorder_calls_for_vendor_compatibilty: true + add_missing_base_config_via_cli: true + skip_macaddress_check: true } } platform_exceptions: { diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 23880679ca0..008a5ae0cc3 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -801,3 +801,27 @@ func PfRequireMatchDefaultRule(dut *ondatra.DUTDevice) bool { func MissingPortToOpticalChannelMapping(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetMissingPortToOpticalChannelComponentMapping() } + +// SkipContainerOp returns true if gNMI container OP needs to be skipped. +// Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 +func SkipContainerOp(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetSkipContainerOp() +} + +// ReorderCallsForVendorCompatibilty returns true if call needs to be updated/added/deleted. +// Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 +func ReorderCallsForVendorCompatibilty(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetReorderCallsForVendorCompatibilty() +} + +// AddMissingBaseConfigViaCli returns true if missing base config needs to be added using CLI. +// Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 +func AddMissingBaseConfigViaCli(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetAddMissingBaseConfigViaCli() +} + +// SkipMacaddressCheck returns true if mac address for an interface via gNMI needs to be skipped. +// Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 +func SkipMacaddressCheck(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetSkipMacaddressCheck() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 6cfed151bbc..b8f53519fab 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -427,6 +427,18 @@ message Metadata { // Devices missing component tree mapping from hardware port // to optical channel. bool missing_port_to_optical_channel_component_mapping = 150; + // Skip gNMI container OP tc. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + bool skip_container_op = 151; + // Reorder calls for vendor compatibility. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + bool reorder_calls_for_vendor_compatibilty = 152; + // Add missing base config using cli. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + bool add_missing_base_config_via_cli = 153; + // skip_macaddress_check returns true if mac address for an interface via gNMI needs to be skipped. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + bool skip_macaddress_check = 154; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index add2dc9e174..5efd1976ab2 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 +// protoc-gen-go v1.30.0 +// protoc v3.19.3 // source: metadata.proto package metadata_go_proto @@ -698,6 +698,18 @@ type Metadata_Deviations struct { // Devices missing component tree mapping from hardware port // to optical channel. MissingPortToOpticalChannelComponentMapping bool `protobuf:"varint,150,opt,name=missing_port_to_optical_channel_component_mapping,json=missingPortToOpticalChannelComponentMapping,proto3" json:"missing_port_to_optical_channel_component_mapping,omitempty"` + // Skip gNMI container OP tc. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + SkipContainerOp bool `protobuf:"varint,151,opt,name=skip_container_op,json=skipContainerOp,proto3" json:"skip_container_op,omitempty"` + // Reorder calls for vendor compatibility. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + ReorderCallsForVendorCompatibilty bool `protobuf:"varint,152,opt,name=reorder_calls_for_vendor_compatibilty,json=reorderCallsForVendorCompatibilty,proto3" json:"reorder_calls_for_vendor_compatibilty,omitempty"` + // Add missing base config using cli. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + AddMissingBaseConfigViaCli bool `protobuf:"varint,153,opt,name=add_missing_base_config_via_cli,json=addMissingBaseConfigViaCli,proto3" json:"add_missing_base_config_via_cli,omitempty"` + // skip_macaddress_check returns true if mac address for an interface via gNMI needs to be skipped. + // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 + SkipMacaddressCheck bool `protobuf:"varint,154,opt,name=skip_macaddress_check,json=skipMacaddressCheck,proto3" json:"skip_macaddress_check,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1670,6 +1682,34 @@ func (x *Metadata_Deviations) GetMissingPortToOpticalChannelComponentMapping() b return false } +func (x *Metadata_Deviations) GetSkipContainerOp() bool { + if x != nil { + return x.SkipContainerOp + } + return false +} + +func (x *Metadata_Deviations) GetReorderCallsForVendorCompatibilty() bool { + if x != nil { + return x.ReorderCallsForVendorCompatibilty + } + return false +} + +func (x *Metadata_Deviations) GetAddMissingBaseConfigViaCli() bool { + if x != nil { + return x.AddMissingBaseConfigViaCli + } + return false +} + +func (x *Metadata_Deviations) GetSkipMacaddressCheck() bool { + if x != nil { + return x.SkipMacaddressCheck + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1733,7 +1773,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfe, 0x53, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf9, 0x55, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1764,7 +1804,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xff, 0x4b, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xfa, 0x4d, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2369,43 +2409,59 @@ var file_metadata_proto_rawDesc = []byte{ 0x96, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, - 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, - 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, - 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x18, 0x97, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x70, + 0x12, 0x51, 0x0a, 0x25, 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x74, 0x79, 0x18, 0x98, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x21, 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x46, 0x6f, + 0x72, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, + 0x6c, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x1f, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, + 0x69, 0x61, 0x5f, 0x63, 0x6c, 0x69, 0x18, 0x99, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x61, + 0x64, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x42, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x56, 0x69, 0x61, 0x43, 0x6c, 0x69, 0x12, 0x33, 0x0a, 0x15, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x18, 0x9a, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x4d, + 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4a, 0x04, + 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, + 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, + 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, + 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, + 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, - 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, - 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, - 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, - 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, - 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, - 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, - 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, - 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, - 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, - 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, - 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, - 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, + 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, + 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, + 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, + 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, + 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, + 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, + 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, + 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, + 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, + 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, + 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, + 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 03253e4d998b0cc0a8ec25fb96e9d0cc53c23e74 Mon Sep 17 00:00:00 2001 From: ANISH-GOTTAPU <48308607+ANISH-GOTTAPU@users.noreply.github.com> Date: Tue, 12 Mar 2024 23:44:34 +0530 Subject: [PATCH 11/97] OTG: gNMI-1.3: Benchmarking: Drained Configuration Convergence Time (#1405) * ATE tests copy * initial otg commit * update test * update test * update isis test * update test * update files * rebase with ATE * Address review comments * Align the test with ATE * update metadata * addressing review comment * update deviations * address review comment * update deviations and align with ATE * update metadata * remove unused constant PeerGrpEgressName * requested PR changes * update MED Verification * sync metadata.textproto * added missing deviation * PR review comments addressed * removed gnmi/benchmarking/tests folder * added the correct feature/experimental/system/gnmi/benchmarking/tests * small change in commented line --------- Co-authored-by: Octavian Petre <96260185+octpetre@users.noreply.github.com> Co-authored-by: Octavian Petre --- .../gnmi/benchmarking/internal/setup/setup.go | 66 +++- .../README.md | 55 +++ ...configuration_convergence_time_bgp_test.go | 335 ++++++++++++++++++ ...onfiguration_convergence_time_isis_test.go | 149 ++++++++ .../metadata.textproto | 43 +++ 5 files changed, 647 insertions(+), 1 deletion(-) create mode 100644 feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md create mode 100644 feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go create mode 100644 feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go create mode 100644 feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto diff --git a/feature/experimental/system/gnmi/benchmarking/internal/setup/setup.go b/feature/experimental/system/gnmi/benchmarking/internal/setup/setup.go index cc2fa872227..1facbd3a15b 100644 --- a/feature/experimental/system/gnmi/benchmarking/internal/setup/setup.go +++ b/feature/experimental/system/gnmi/benchmarking/internal/setup/setup.go @@ -25,9 +25,11 @@ import ( "testing" "time" + "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" @@ -40,7 +42,6 @@ const ( ISISInstance = "DEFAULT" // PeerGrpName is BGP peer group name. PeerGrpName = "BGP-PEER-GROUP" - // DUTAs is DUT AS. DUTAs = 64500 // ATEAs is ATE AS. @@ -329,6 +330,69 @@ func ConfigureATE(t *testing.T, ate *ondatra.ATEDevice) { topo.StartProtocols(t) } +// ConfigureOTG function is to configure otg ports with ipv4, bgp and isis peers. +func ConfigureOTG(t *testing.T, ate *ondatra.ATEDevice) { + otg := ate.OTG() + topo := gosnappi.NewConfig() + + for i, dp := range ate.Ports() { + + topo.Ports().Add().SetName(dp.ID()) + dev := topo.Devices().Add().SetName(dp.ID() + "dev") + eth := dev.Ethernets().Add().SetName(dp.ID() + ".Eth") + eth.Connection().SetPortName(dp.ID()) + mac := fmt.Sprintf("02:00:01:01:01:%02x", byte(i&0xff)) + + eth.SetMac(mac) + + ip := eth.Ipv4Addresses().Add().SetName(dev.Name() + ".IPv4") + ip.SetAddress(ATEIPList[dp.ID()].String()).SetGateway(DUTIPList[dp.ID()].String()).SetPrefix(uint32(plenIPv4)) + + // Add BGP on ATE + bgpDut1 := dev.Bgp().SetRouterId(ip.Address()) + bgpDut1Peer := bgpDut1.Ipv4Interfaces().Add().SetIpv4Name(ip.Name()).Peers().Add().SetName(dp.ID() + ".BGP4.peer") + if dp.ID() == "port1" { + bgpDut1Peer.SetPeerAddress(DUTIPList[dp.ID()].String()).SetAsNumber(ATEAs2).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + } else { + bgpDut1Peer.SetPeerAddress(DUTIPList[dp.ID()].String()).SetAsNumber(ATEAs).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + } + bgpDut1Peer.Capability().SetIpv4Unicast(true) + bgpDut1Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) + + // Add ISIS on ATE + devIsis := dev.Isis().SetSystemId(strconv.FormatInt(int64(i), 16)).SetName("devIsis" + dp.Name()) + devIsis.Basic().SetHostname(devIsis.Name()).SetLearnedLspFilter(true) + devIsis.Advanced().SetAreaAddresses([]string{"490002"}) + devIsisInt := devIsis.Interfaces().Add(). + SetEthName(eth.Name()). + SetName("devIsisInt"). + SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). + SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2) + devIsisInt.Authentication().SetAuthType("md5") + devIsisInt.Authentication().SetMd5(authPassword) + devIsisInt.Advanced().SetAutoAdjustMtu(true).SetAutoAdjustArea(true).SetAutoAdjustSupportedProtocols(true) + + if dp.ID() == "port1" { + // Add BGP routes and ISIS routes , ate port1 is ingress port. + dstBgp4PeerRoutes := bgpDut1Peer.V4Routes().Add().SetName("bgpNeti1") + dstBgp4PeerRoutes.SetNextHopIpv4Address(ip.Address()). + SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). + SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) + dstBgp4PeerRoutes.Addresses().Add(). + SetAddress(AdvertiseBGPRoutesv4).SetPrefix(32).SetCount(RouteCount) + devIsisRoutes := devIsis.V4Routes().Add().SetName("isisnet1").SetLinkMetric(20) + devIsisRoutes.Addresses().Add(). + SetAddress(advertiseISISRoutesv4).SetPrefix(32).SetCount(RouteCount).SetStep(1) + } + } + + t.Log("Pushing config to ATE...") + otg.PushConfig(t, topo) + t.Log("Starting protocols to ATE...") + otg.StartProtocols(t) + otgutils.WaitForARP(t, otg, topo, "IPv4") +} + // VerifyISISTelemetry function to used verify ISIS telemetry on DUT // using OC isis telemetry path. func VerifyISISTelemetry(t *testing.T, dut *ondatra.DUTDevice) { diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md new file mode 100644 index 00000000000..80b76298f1e --- /dev/null +++ b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md @@ -0,0 +1,55 @@ +# gNMI-1.3: Benchmarking: Drained Configuration Convergence Time + +## Summary + +Measure performance of drained configuration being applied. + +## Procedure + +Configure DUT with maximum number of IS-IS adjacencies, and BGP +peers - with physical interfaces between ATE and DUT for IS-IS +peers. + +First port is used as ingress port to send routes from ATE to DUT. + +For each of the following configurations, generate complete device +configuration and measure time for the operation to complete (as +defined in the case): + * TODO: IS-IS overload: + * At t=0, send Set to DUT marking IS-IS overload bit. + * Measure time between t=0 and all IS-IS sessions on ATE to + report DUT as overloaded. + * IS-IS metric change: + * At t=0, send Set to DUT marking IS-IS metric as changed for + all IS-IS interfaces. + * Measure time between t=0 and all IS-IS sessions on ATE to + report changed metric. + * BGP AS_PATH prepend: + * At t=0, send Set to DUT changing BGP policy for each session + to prepend AS_PATH. + * Measure time between t=0 and all BGP received routes on ATE + to report change in as path. + * TODO: BGP MED manipulation. + * At t=0, send Set to DUT changing BGP policy for each session to + set MED to non-default value. + * Measure time between t=0 and all BGP received routes on ATE to + report changed metric. + +## Config Parameter coverage + + * BGP + * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med + * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n + * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/as-number + + * ISIS + * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric + * /network-instances/network-instance/protocols/protocol/isis/global/lsp-bit/overload-bit/state/set-bit + +## Telemetry Parameter coverage + + * ISIS + * /interfaces/interfaces/levels/level/adjacencies/adjacency/state/adjacency-state + * BGP + * /afi-safis/afi-safi/state/prefixes/sent + * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go new file mode 100644 index 00000000000..3b12bc1d5e5 --- /dev/null +++ b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go @@ -0,0 +1,335 @@ +// Copyright 2023 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. + +// drained_configuration_convergence_time_test is used to verify bgp test scenarios +// as given in gnmi1.3 testcase. +package drained_configuration_convergence_time_test + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/featureprofiles/feature/experimental/system/gnmi/benchmarking/internal/setup" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +const ( + asPathRepeatValue = 3 + aclStatement2 = "20" + aclStatement3 = "30" + setASpathPrependPolicy = "SET-ASPATH-PREPEND" + setMEDPolicy = "SET-MED" + setALLOWPolicy = "ALLOW" + bgpMED = 25 +) + +// setAllow is used to configure ALLOW routing policy on DUT. +func setAllow(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root) { + + // Configure Allow Policy on DUT. + rp := d.GetOrCreateRoutingPolicy() + pd := rp.GetOrCreatePolicyDefinition(setALLOWPolicy) + st, err := pd.AppendNewStatement("id-1") + if err != nil { + t.Fatal(err) + } + st.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) +} + +// setMED is used to configure routing policy to set BGP MED on DUT. +func setMED(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root) { + + // Configure SetMED on DUT. + rp := d.GetOrCreateRoutingPolicy() + pdef5 := rp.GetOrCreatePolicyDefinition(setMEDPolicy) + stmt, err := pdef5.AppendNewStatement(aclStatement3) + if err != nil { + t.Fatal(err) + } + actions5 := stmt.GetOrCreateActions() + setMedBGP := actions5.GetOrCreateBgpActions() + setMedBGP.SetMed = oc.UnionUint32(bgpMED) + actions5.PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + if deviations.BGPSetMedRequiresEqualOspfSetMetric(dut) { + actions5.GetOrCreateOspfActions().GetOrCreateSetMetric().SetMetric(bgpMED) + } + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) +} + +// setASPath is used to configure route policy set-as-path prepend on DUT. +func setASPath(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root) { + + // Configure SetASPATH routing policy on DUT. + rp := d.GetOrCreateRoutingPolicy() + pdef5 := rp.GetOrCreatePolicyDefinition(setASpathPrependPolicy) + stmt, err := pdef5.AppendNewStatement(aclStatement2) + if err != nil { + t.Fatal(err) + } + actions5 := stmt.GetOrCreateActions() + actions5.PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + aspend := actions5.GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend() + aspend.Asn = ygot.Uint32(setup.DUTAs) + aspend.RepeatN = ygot.Uint8(asPathRepeatValue) + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + bgp := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() + pg := bgp.GetOrCreatePeerGroup(setup.PeerGrpName) + rpl := pg.GetOrCreateApplyPolicy() + rpl.SetImportPolicy([]string{setALLOWPolicy}) + + gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).Config(), pg) + +} + +func setPolicyPeerGroup(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root, policy []string) { + + // Set BGP Import policy + netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + bgp := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() + pg := bgp.GetOrCreatePeerGroup(setup.PeerGrpName) + pg.PeerAs = ygot.Uint32(setup.ATEAs) + pg.PeerGroupName = ygot.String(setup.PeerGrpName) + afipg := pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + afipg.Enabled = ygot.Bool(true) + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + pgpolicy := pg.GetOrCreateApplyPolicy() + pgpolicy.ImportPolicy = policy + gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).Config(), pg) + + } else { + pgpolicy := afipg.GetOrCreateApplyPolicy() + pgpolicy.ImportPolicy = policy + gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).Config(), pg) + + } +} + +// isConverged function is used to check if ATE has received all the prefixes. +func isConverged(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice, ap *ondatra.Port) { + + // Add 10 second timer for BGP update to propagate + time.Sleep(10 * time.Second) + // Check if all prefixes are learned at ATE. + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). + Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() +prefixLoop: + for repeat := 4; repeat > 0; repeat-- { + prefixesv4 := statePath.Neighbor(setup.ATEIPList[ap.ID()].String()). + AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Prefixes() + gotSent := gnmi.Get(t, dut, prefixesv4.Sent().State()) + switch { + case gotSent == setup.RouteCount: + t.Logf("Prefixes sent from ingress port are learnt at ATE dst port : %v are %v", setup.ATEIPList[ap.ID()].String(), setup.RouteCount) + break prefixLoop + case repeat > 0 && gotSent < setup.RouteCount: + t.Logf("All the prefixes are not learnt , wait for 5 secs before retry.. got %v, want %v", gotSent, setup.RouteCount) + time.Sleep(time.Second * 5) + case repeat == 0 && gotSent < setup.RouteCount: + t.Errorf("sent prefixes from DUT to neighbor %v is mismatch: got %v, want %v", setup.ATEIPList[ap.ID()].String(), gotSent, setup.RouteCount) + } + } + +} + +// verifyBGPAsPath is to Validate AS Path attribute using bgp rib telemetry on ATE. +func verifyBGPAsPath(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + + // Start the timer. + start := time.Now() + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). + Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). + PeerGroup(setup.PeerGrpName).ApplyPolicy().ExportPolicy() + + gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setASpathPrependPolicy}) + } else { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). + Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). + PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setASpathPrependPolicy}) + } + t.Run("BGP-AS-PATH Verification", func(t *testing.T) { + for _, ap := range ate.Ports() { + if ap.ID() == "port1" { + // port1 is ingress, skip verification on ingress port. + continue + } + + // Validate if all prefixes are received by ATE. + isConverged(t, dut, ate, ap) + + prefixPath := gnmi.OTG().BgpPeer(ap.ID() + ".BGP4.peer").UnicastIpv4PrefixAny() + + gnmi.WatchAll(t, ate.OTG(), prefixPath.Address().State(), time.Minute, func(v *ygnmi.Value[string]) bool { + _, present := v.Val() + return present + }).Await(t) + + singlepath := []uint32{setup.DUTAs, setup.DUTAs, setup.DUTAs, setup.DUTAs, setup.ATEAs2} + _, ok := gnmi.WatchAll(t, ate.OTG(), prefixPath.AsPathAny().State(), 5*time.Minute, func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix_AsPath]) bool { + val, present := v.Val() + return present && cmp.Diff(val.AsNumbers, singlepath) == "" + }).Await(t) + if !ok { + t.Errorf("Obtained AS path on ATE is not as expected") + } + } + }) + + // End the timer and calculate time. + elapsed := time.Since(start) + t.Logf("Duration taken to apply as path prepend policy is %v", elapsed) +} + +// verifyBGPSetMED is to Validate MED attribute using bgp rib telemetry on ATE. +func verifyBGPSetMED(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + + // Start the timer. + start := time.Now() + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). + Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). + PeerGroup(setup.PeerGrpName).ApplyPolicy().ExportPolicy() + gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setMEDPolicy}) + } else { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). + Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). + PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setMEDPolicy}) + } + + t.Run("BGP-MED-Verification", func(t *testing.T) { + + for _, ap := range ate.Ports() { + if ap.ID() == "port1" { + continue + } + + // Validate if all prefixes are received by ATE. + isConverged(t, dut, ate, ap) + + bgpPrefixes := gnmi.GetAll(t, ate.OTG(), gnmi.OTG().BgpPeer(ap.ID()+".BGP4.peer").UnicastIpv4PrefixAny().State()) + for _, prefix := range bgpPrefixes { + if prefix.GetMultiExitDiscriminator() != bgpMED { + t.Errorf("Received Prefix Med %d Expected Med %d for Prefix %v", prefix.GetMultiExitDiscriminator(), bgpMED, prefix.GetAddress()) + } + } + + } + }) + // End the timer and calculate time taken to apply setMED. + elapsed := time.Since(start) + t.Logf("Duration taken to apply setMed routing policy is %v", elapsed) +} + +// TestEstablish is to configure Interface, BGP and ISIS configurations on DUT +// using gnmi set request. It also verifies for bgp and isis adjacencies. +func TestEstablish(t *testing.T) { + + dut := ondatra.DUT(t, "dut") + dutConfigPath := gnmi.OC() + + t.Log("Configure Network Instance type to DEFAULT on DUT.") + fptest.ConfigureDefaultNetworkInstance(t, dut) + + t.Log("Build Benchmarking BGP and ISIS test configs.") + dutBenchmarkConfig := setup.BuildBenchmarkingConfig(t) + if !deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.LogQuery(t, "Benchmarking configs to configure on DUT", dutConfigPath.Config(), dutBenchmarkConfig) + } + // Apply benchmarking configs on dut + gnmi.Update(t, dut, dutConfigPath.Config(), dutBenchmarkConfig) + + t.Log("Configure ATE with Interfaces, BGP, ISIS configs.") + ate := ondatra.ATE(t, "ate") + setup.ConfigureOTG(t, ate) + + t.Log("Verify BGP Session state , should be in ESTABLISHED State.") + setup.VerifyBgpTelemetry(t, dut) + + t.Log("Verify ISIS adjacency state, should be UP.") + setup.VerifyISISTelemetry(t, dut) +} + +// TestBGPBenchmarking is test time taken to apply set as path prepend and set med routing +// policies on routes in bgp rib. Verification of routing policy is done on ATE using bgp +// rib table. +func TestBGPBenchmarking(t *testing.T) { + + d := &oc.Root{} + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + // Cleanup existing policy details. + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).ApplyPolicy() + gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) + gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) + } else { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) + gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) + } + gnmi.Delete(t, dut, gnmi.OC().RoutingPolicy().Config()) + + t.Logf("Configure Allow policy.") + setAllow(t, dut, d) + + t.Logf("Configure MED routing policy.") + setMED(t, dut, d) + + t.Logf("Configure Allow Import routing policy in BGP.") + setPolicyPeerGroup(t, dut, d, []string{setALLOWPolicy}) + + t.Logf("Verify time taken to apply MED to all routes in bgp rib.") + verifyBGPSetMED(t, dut, ate) + + // Cleanup existing policy details. + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).ApplyPolicy() + gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) + gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) + } else { + dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) + gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) + } + gnmi.Delete(t, dut, gnmi.OC().RoutingPolicy().Config()) + + t.Logf("Configure SET-AS-PATH routing policy.") + setASPath(t, dut, d) + + t.Logf("Configure Allow Import routing policy in BGP.") + setPolicyPeerGroup(t, dut, d, []string{setALLOWPolicy}) + + t.Logf("Verify time taken to apply SET-AS-PATH to all routes in bgp rib.") + verifyBGPAsPath(t, dut, ate) +} diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go new file mode 100644 index 00000000000..e8bf2d5cfd2 --- /dev/null +++ b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go @@ -0,0 +1,149 @@ +// Copyright 2023 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. + +// drained_configuration_convergence_time_test is used to verify isis test scenarios +// as given in gnmi 1.3 testcase +package drained_configuration_convergence_time_test + +import ( + "testing" + "time" + + "github.com/openconfig/featureprofiles/feature/experimental/system/gnmi/benchmarking/internal/setup" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + "github.com/openconfig/ygnmi/ygnmi" +) + +// setISISOverloadBit is used to configure isis overload bit to true. +func setISISOverloadBit(t *testing.T, dut *ondatra.DUTDevice) { + + // ISIS Configs to set Overload Bit to true. + dutISISPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, setup.ISISInstance).Isis() + lspBit := dutISISPath.Global().LspBit().OverloadBit() + gnmi.Replace(t, dut, lspBit.SetBit().Config(), true) +} + +// setISISMetric is used to configure metric on isis interfaces. +func setISISMetric(t *testing.T, dut *ondatra.DUTDevice) { + + dutISISPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, setup.ISISInstance).Isis() + t.Logf("Configure ISIS metric to %v", setup.ISISMetric) + for _, dp := range dut.Ports() { + intfName := dp.Name() + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + intfName = dp.Name() + ".0" + } + dutISISPathIntfAF := dutISISPath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST) + if deviations.ISISRequireSameL1MetricWithL2Metric(dut) { + b := &gnmi.SetBatch{} + gnmi.BatchReplace(b, dutISISPathIntfAF.Metric().Config(), setup.ISISMetric) + l1AF := dutISISPath.Interface(intfName).Level(1).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST) + gnmi.BatchReplace(b, l1AF.Metric().Config(), setup.ISISMetric) + b.Set(t, dut) + } else { + gnmi.Replace(t, dut, dutISISPathIntfAF.Metric().Config(), setup.ISISMetric) + } + } +} + +// verifyISISMetric is used to verify on ATE to see how much time it +// has taken to apply changes in metric +func verifyISISMetric(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + + t.Run("ISIS Metric verification", func(t *testing.T) { + for _, ap := range ate.Ports() { + if ap.ID() == "port1" { + // Port1 is ingress, skip verification on ingress port + continue + } + + got, ok := gnmi.WatchAll(t, ate.OTG(), gnmi.OTG().IsisRouter("devIsis"+ap.Name()).LinkStateDatabase().LspsAny().Tlvs().ExtendedIpv4Reachability().PrefixAny().Metric().State(), time.Minute, func(v *ygnmi.Value[uint32]) bool { + metric, present := v.Val() + if present { + if metric == setup.ISISMetric { + return true + } + } + return false + }).Await(t) + + metricInReceivedLsp, _ := got.Val() + if !ok { + t.Fatalf("Metric not matched. Expected %d got %d ", setup.ISISMetric, metricInReceivedLsp) + } + } + }) +} + +// verifyISISOverloadBit is used to verify on ATE to see how much time it +// has taken to apply overload bit on isis adjacencies. +func verifyISISOverloadBit(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + + t.Run("ISIS Overload bit verification", func(t *testing.T) { + for _, ap := range ate.Ports() { + if ap.ID() == "port1" { + // port1 is ingress, skip verification on ingress port + continue + } + + otg := ate.OTG() + _, ok := gnmi.WatchAll(t, otg, gnmi.OTG().IsisRouter("devIsis"+ap.Name()).LinkStateDatabase().LspsAny().Flags().State(), time.Minute, func(v *ygnmi.Value[[]otgtelemetry.E_Lsps_Flags]) bool { + flags, present := v.Val() + if present { + for _, flag := range flags { + if flag == otgtelemetry.Lsps_Flags_OVERLOAD { + return true + } + } + } + return false + }).Await(t) + + if !ok { + t.Fatalf("OverLoad Bit not seen on learned lsp on ATE") + } + } + }) +} + +// TestISISBenchmarking is to test ISIS overload bit and metric change +// applied on all isis sessions. +func TestISISBenchmarking(t *testing.T) { + + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + t.Log("Start timer for ISIS overload bit verification test.") + start := time.Now() + t.Log("Configure ISIS overload bit on DUT.") + setISISOverloadBit(t, dut) + t.Log("Verify on ATE if ISIS overload bit is reflected on ATE.") + verifyISISOverloadBit(t, dut, ate) + t.Log("End the timer and calculate time taken to apply ISIS overload bit.") + elapsed := time.Since(start) + t.Logf("Duration taken to apply overload bit: %v", elapsed) + + t.Log("Start timer for ISIS Metric test.") + start = time.Now() + t.Log("Configure ISIS Metric on DUT.") + setISISMetric(t, dut) + t.Log("Verify on ATE if ISIS Metric changes are reflected.") + verifyISISMetric(t, dut, ate) + t.Log("End the timer and calculate time taken to apply ISIS Metric.") + elapsed = time.Since(start) + t.Logf("Duration taken to apply isis metric: %v", elapsed) +} diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto new file mode 100644 index 00000000000..e6104d7837a --- /dev/null +++ b/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto @@ -0,0 +1,43 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "44ec09b1-d985-4188-9f4a-ae542ad9d3a2" +plan_id: "gNMI-1.3" +description: "Benchmarking: Drained Configuration Convergence Time" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + isis_global_authentication_not_required: true + isis_explicit_level_authentication_config: true + missing_isis_interface_afi_safi_enable: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + interface_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + isis_level_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + route_policy_under_afi_unsupported: true + interface_enabled: true + default_network_instance: "default" + missing_isis_interface_afi_safi_enable: true + isis_interface_afi_unsupported: true + isis_require_same_l1_metric_with_l2_metric: true + bgp_set_med_requires_equal_ospf_set_metric: true + isis_instance_enabled_required: true + } +} From bb3379890b953fc1da99a1b4b1c2c8b971880387 Mon Sep 17 00:00:00 2001 From: anksaiki Date: Tue, 12 Mar 2024 15:23:27 -0400 Subject: [PATCH 12/97] Add operational mode since it is supported now. (#2800) --- .../zr_logical_channels_test.go | 3 ++- .../zr_tunable_parameters_test.go | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go b/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go index 8fd26627fee..97a810089c7 100644 --- a/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go +++ b/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go @@ -19,6 +19,7 @@ import ( const ( targetOutputPower = -9 frequency = 193100000 + dp16QAM = 1 ) var ( @@ -45,7 +46,6 @@ func Test400ZRLogicalChannels(t *testing.T) { p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") - fptest.ConfigureDefaultNetworkInstance(t, dut) fptest.ConfigureDefaultNetworkInstance(t, dut) gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) @@ -79,6 +79,7 @@ func configureLogicalChannels(t *testing.T, dut *ondatra.DUTDevice, ethernetChId gnmi.BatchReplace(b, gnmi.OC().Component(opticalChannel).OpticalChannel().Config(), &oc.Component_OpticalChannel{ TargetOutputPower: ygot.Float64(targetOutputPower), Frequency: ygot.Uint64(frequency), + OperationalMode: ygot.Uint16(dp16QAM), }) // Ethernet Logical Channel diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go index 05a08b02a1f..079425dbc76 100644 --- a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go @@ -18,6 +18,7 @@ import ( const ( samplingInterval = 10 * time.Second frequencyTolerance = 1800 + dp16QAM = 1 ) var ( @@ -41,7 +42,6 @@ func Test400ZRTunableFrequency(t *testing.T) { p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") fptest.ConfigureDefaultNetworkInstance(t, dut) - fptest.ConfigureDefaultNetworkInstance(t, dut) gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) oc1 := opticalChannelFromPort(t, dut, p1) @@ -83,10 +83,12 @@ func Test400ZRTunableFrequency(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Component(oc1).OpticalChannel().Config(), &oc.Component_OpticalChannel{ TargetOutputPower: ygot.Float64(tc.targetOutputPower), Frequency: ygot.Uint64(freq), + OperationalMode: ygot.Uint16(dp16QAM), }) gnmi.Replace(t, dut, gnmi.OC().Component(oc2).OpticalChannel().Config(), &oc.Component_OpticalChannel{ TargetOutputPower: ygot.Float64(tc.targetOutputPower), Frequency: ygot.Uint64(freq), + OperationalMode: ygot.Uint16(dp16QAM), }) validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, freq, tc.targetOutputPower) }) @@ -99,7 +101,6 @@ func Test400ZRTunableOutputPower(t *testing.T) { p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") fptest.ConfigureDefaultNetworkInstance(t, dut) - fptest.ConfigureDefaultNetworkInstance(t, dut) gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) oc1 := opticalChannelFromPort(t, dut, p1) @@ -132,10 +133,12 @@ func Test400ZRTunableOutputPower(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Component(oc1).OpticalChannel().Config(), &oc.Component_OpticalChannel{ TargetOutputPower: ygot.Float64(top), Frequency: ygot.Uint64(tc.frequency), + OperationalMode: ygot.Uint16(dp16QAM), }) gnmi.Replace(t, dut, gnmi.OC().Component(oc2).OpticalChannel().Config(), &oc.Component_OpticalChannel{ TargetOutputPower: ygot.Float64(top), Frequency: ygot.Uint64(tc.frequency), + OperationalMode: ygot.Uint16(dp16QAM), }) validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, tc.frequency, top) }) @@ -147,7 +150,6 @@ func Test400ZRInterfaceFlap(t *testing.T) { p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") fptest.ConfigureDefaultNetworkInstance(t, dut) - fptest.ConfigureDefaultNetworkInstance(t, dut) gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) oc1 := opticalChannelFromPort(t, dut, p1) @@ -161,10 +163,12 @@ func Test400ZRInterfaceFlap(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Component(oc1).OpticalChannel().Config(), &oc.Component_OpticalChannel{ TargetOutputPower: ygot.Float64(targetPower), Frequency: ygot.Uint64(frequency), + OperationalMode: ygot.Uint16(dp16QAM), }) gnmi.Replace(t, dut, gnmi.OC().Component(oc2).OpticalChannel().Config(), &oc.Component_OpticalChannel{ TargetOutputPower: ygot.Float64(targetPower), Frequency: ygot.Uint64(frequency), + OperationalMode: ygot.Uint16(dp16QAM), }) t.Run("Telemetry before flap", func(t *testing.T) { validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) @@ -205,10 +209,14 @@ func validateOpticsTelemetry(t *testing.T, dut *ondatra.DUTDevice, streams []*sa ocs = append(ocs, v.GetOpticalChannel()) } for _, oc := range ocs { + opm := oc.GetOperationalMode() inst := oc.GetCarrierFrequencyOffset().GetInstant() avg := oc.GetCarrierFrequencyOffset().GetAvg() min := oc.GetCarrierFrequencyOffset().GetMin() max := oc.GetCarrierFrequencyOffset().GetMax() + if got, want := opm, uint16(dp16QAM); got != want { + t.Errorf("Optical-Channel: operational-mode: got %v, want %v", got, want) + } // Laser frequency offset should not be more than +/- 1.8 GHz max from the // configured centre frequency. if inst < -1*frequencyTolerance || inst > frequencyTolerance { From 9dcb5e83c42c296f9a99bc6a724a924e73ae28a2 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Tue, 12 Mar 2024 21:40:41 -0700 Subject: [PATCH 13/97] Fix references to community-set in RT-7.2 (#2797) * Fix references to community-set * Update config paths --- .../otg_tests/community_test/README.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/community_test/README.md b/feature/bgp/policybase/otg_tests/community_test/README.md index e9aa94f7037..d3c2d2a496e 100644 --- a/feature/bgp/policybase/otg_tests/community_test/README.md +++ b/feature/bgp/policybase/otg_tests/community_test/README.md @@ -2,7 +2,7 @@ ## Summary -BGP policy configuration for AS Paths and Community Sets +BGP policy configuration for Community Sets ## Subtests @@ -38,16 +38,16 @@ BGP policy configuration for AS Paths and Community Sets * conditions/bgp-conditions/match-community-set/config/match-set-options = ANY * actions/config/policy-result = ACCEPT_ROUTE * statement[name='accept_all_3_comms']/ - * conditions/bgp-conditions/match-as-path-set/config/as-path-set = 'all_3_comms' - * conditions/bgp-conditions/match-as-path-set/config/match-set-options = ALL + * conditions/bgp-conditions/match-community-set/config/community-set = 'all_3_comms' + * conditions/bgp-conditions/match-community-set/config/match-set-options = ALL * actions/config/policy-result = ACCEPT_ROUTE * statement[name='accept_no_3_comms']/ - * conditions/bgp-conditions/match-as-path-set/config/as-path-set = 'no_3_comms' - * conditions/bgp-conditions/match-as-path-set/config/match-set-options = INVERT + * conditions/bgp-conditions/match-community-set/config/community-set = 'no_3_comms' + * conditions/bgp-conditions/match-community-set/config/match-set-options = INVERT * actions/config/policy-result = ACCEPT_ROUTE * statement[name='accept_any_my_regex_comms']/ - * conditions/bgp-conditions/match-as-path-set/config/as-path-set = 'all_3_comms' - * conditions/bgp-conditions/match-as-path-set/config/match-set-options = ANY + * conditions/bgp-conditions/match-community-set/config/community-set = 'all_3_comms' + * conditions/bgp-conditions/match-community-set/config/match-set-options = ANY * actions/config/policy-result = ACCEPT_ROUTE * Send traffic from ATE port-2 to all prefix-sets. @@ -63,8 +63,6 @@ BGP policy configuration for AS Paths and Community Sets | prefix-set-3 | reject | reject | accept | accept | | prefix-set-4 | reject | reject | accept | reject | -* TODO: add coverage for link-bandwidth community in separate test. - ## Config Parameter Coverage ### Policy definition @@ -77,7 +75,9 @@ BGP policy configuration for AS Paths and Community Sets * /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/config/community-set-name * /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/config/community-member * /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/config/match-set-options -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/config/community-set +* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/community-set +* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/match-set-options +* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/ import-policy From e7645bf29fc4e42a7a8742bef152fde2f723c526 Mon Sep 17 00:00:00 2001 From: Mohana Date: Wed, 13 Mar 2024 01:50:02 -0700 Subject: [PATCH 14/97] RT-1.29: Added deviation to skip BGP rib verification (#2760) * Added deviation for configuring bgp peer group and deviation to skip bgp rib verification * Update README.md Removed ACCEPT_ROUTE for asp-policy-v4 as the expectation of the test is to validate both asp-policy-v4 and med-policy-v4 gets applied. If ACCEPT_ROUTE is configured in asp-policy-v4, route will be accepted on applying this policy and the next policy configured in export 'med-policy-v4' will not be applied. Verification: Validate that the prefix ```ipv4-network-2``` i.e. ```192.168.20.0/24``` on ATE from BGP neighbor on DUT Port-1 has AS-PATH with the ASN of DUT occuring twice * /network-instances/network-instance/protocols/protocol/bgp/rib/attr-sets/attr-set/as-path/as-segment/state/member * Validate that the prefix ```ipv4-network-2``` i.e. ```192.168.20.0/24``` on ATE from BGP neighbor on DUT Port-1 has MED set to ```1000``` * /network-instances/network-instance/protocols/protocol/bgp/rib/attr-sets/attr-set/state/med * Updated with unique ateAS for port1 and port2 and updated v62Route to match with prefix received in ATE * Removed deviation bgp_neighbor_under_peer_group * Resolving merge conflicts --------- Co-authored-by: Pramod Maurya --- .../otg_tests/chained_policies_test/README.md | 4 - .../chained_policies_test.go | 174 ++++++++++++------ .../chained_policies_test/metadata.textproto | 8 + internal/deviations/deviations.go | 5 + proto/metadata.proto | 4 + proto/metadata_go_proto/metadata.pb.go | 94 ++++++---- 6 files changed, 187 insertions(+), 102 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/chained_policies_test/README.md b/feature/bgp/policybase/otg_tests/chained_policies_test/README.md index 0fcba8d6e16..eab34543721 100644 --- a/feature/bgp/policybase/otg_tests/chained_policies_test/README.md +++ b/feature/bgp/policybase/otg_tests/chained_policies_test/README.md @@ -98,8 +98,6 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * /routing-policy/policy-definitions/policy-definition/config/name * For routing-policy ```asp-policy-v4``` configure a statement with the name ```asp-statement-v4``` * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```asp-policy-v4``` statement ```asp-statement-v4``` set policy-result as ```ACCEPT_ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result ##### Configure BGP actions to prepend AS * For routing-policy ```asp-policy-v4``` statement ```asp-statement-v4``` set AS-PATH prepend to the ASN of the DUT * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/asn @@ -195,8 +193,6 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * /routing-policy/policy-definitions/policy-definition/config/name * For routing-policy ```asp-policy-v6``` configure a statement with the name ```asp-statement-v6``` * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```asp-policy-v6``` statement ```asp-statement-v6``` set policy-result as ```ACCEPT_ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result ##### Configure BGP actions to prepend AS * For routing-policy ```asp-policy-v6``` statement ```asp-statement-v6``` set AS-PATH prepend to the ASN of the DUT * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/asn diff --git a/feature/bgp/policybase/otg_tests/chained_policies_test/chained_policies_test.go b/feature/bgp/policybase/otg_tests/chained_policies_test/chained_policies_test.go index 847c8e3807f..a1d1d75183c 100644 --- a/feature/bgp/policybase/otg_tests/chained_policies_test/chained_policies_test.go +++ b/feature/bgp/policybase/otg_tests/chained_policies_test/chained_policies_test.go @@ -43,13 +43,14 @@ const ( v42Route = "198.51.100.0" v42TrafficStart = "198.51.100.1" v4RoutePrefix = uint32(24) - v61Route = "2001:db8:128:128::0" + v61Route = "2001:db8:128:128::" v61TrafficStart = "2001:db8:128:128::1" - v62Route = "2001:db8:128:129::0" + v62Route = "2001:db8:128:129::" v62TrafficStart = "2001:db8:128:129::1" v6RoutePrefix = uint32(64) dutAS = uint32(65656) - ateAS = uint32(65657) + ateAS1 = uint32(65657) + ateAS2 = uint32(65658) bgpName = "BGP" maskLenExact = "exact" localPref = 200 @@ -74,6 +75,8 @@ const ( v6ASPStatement = "asp-statement-v6" v6MedPolicy = "med-policy-v6" v6MedStatement = "med-statement-v6" + peerGrpNamev4 = "BGP-PEER-GROUP-V4" + peerGrpNamev6 = "BGP-PEER-GROUP-V6" ) var ( @@ -145,7 +148,7 @@ type testData struct { type testCase struct { name string desc string - applyPolicy func(t *testing.T, dut *ondatra.DUTDevice) + applyPolicy func(t *testing.T, dut *ondatra.DUTDevice, operation string) validate func(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) ipv4 bool flowConfig flowConfig @@ -218,8 +221,10 @@ func TestBGPChainedPolicies(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Logf("Description: %s", tc.desc) - tc.applyPolicy(t, dut) + tc.applyPolicy(t, dut, "set") + defer tc.applyPolicy(t, dut, "delete") tc.validate(t, dut, ate) + if tc.ipv4 { createFlow(t, td, tc.flowConfig) checkTraffic(t, td, v4Flow) @@ -231,7 +236,8 @@ func TestBGPChainedPolicies(t *testing.T) { } } -func configureImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { +func configureImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, operation string) { + batch := &gnmi.SetBatch{} root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() pdef1 := rp.GetOrCreatePolicyDefinition(v4PrefixPolicy) @@ -257,14 +263,23 @@ func configureImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { } stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) stmt2.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(localPref) - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + if operation == "set" { + gnmi.BatchReplace(batch, gnmi.OC().RoutingPolicy().Config(), rp) + } else if operation == "delete" { + gnmi.BatchDelete(batch, gnmi.OC().RoutingPolicy().Config()) + } dni := deviations.DefaultNetworkInstance(dut) path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() policy.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetImportPolicy([]string{v4PrefixPolicy, v4LPPolicy}) - gnmi.Replace(t, dut, path.Config(), policy) + if operation == "set" { + gnmi.BatchReplace(batch, path.Config(), policy) + } else if operation == "delete" { + gnmi.BatchDelete(batch, path.Config()) + } + batch.Set(t, dut) } func validateImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { @@ -276,27 +291,30 @@ func validateImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *onda t.Errorf("ImportPolicy = %v, want %v", importPolicies, []string{v4PrefixPolicy, v4LPPolicy}) } - bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() - locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv4Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast().LocRib().State()) - found := false - for k, lr := range locRib.Route { - if lr.GetPrefix() == advertisedIPv41.address { - found = true - t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) - attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) - if attrSet == nil || attrSet.GetLocalPref() != localPref { - t.Errorf("No local pref found for prefix %s", advertisedIPv41.address) + if !deviations.BGPRibOcPathUnsupported(dut) { + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv4Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast().LocRib().State()) + found := false + for k, lr := range locRib.Route { + if lr.GetPrefix() == advertisedIPv41.address { + found = true + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) + attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) + if attrSet == nil || attrSet.GetLocalPref() != localPref { + t.Errorf("No local pref found for prefix %s", advertisedIPv41.address) + } + break } - break } - } - if !found { - t.Errorf("No Route found for prefix %s", advertisedIPv41.address) + if !found { + t.Errorf("No Route found for prefix %s", advertisedIPv41.address) + } } } -func configureExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { +func configureExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, operation string) { + batch := &gnmi.SetBatch{} root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() pdef1 := rp.GetOrCreatePolicyDefinition(v4ASPPolicy) @@ -304,7 +322,6 @@ func configureExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", v4ASPStatement, err) } - stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend().SetAsn(dutAS) pdef2 := rp.GetOrCreatePolicyDefinition(v4MedPolicy) @@ -314,14 +331,23 @@ func configureExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { } stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) stmt2.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(oc.UnionUint32(med)) - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + if operation == "set" { + gnmi.BatchReplace(batch, gnmi.OC().RoutingPolicy().Config(), rp) + } else if operation == "delete" { + gnmi.BatchDelete(batch, gnmi.OC().RoutingPolicy().Config()) + } dni := deviations.DefaultNetworkInstance(dut) path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() policy.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetExportPolicy([]string{v4ASPPolicy, v4MedPolicy}) - gnmi.Replace(t, dut, path.Config(), policy) + if operation == "set" { + gnmi.BatchReplace(batch, path.Config(), policy) + } else if operation == "delete" { + gnmi.BatchDelete(batch, path.Config()) + } + batch.Set(t, dut) } func validateExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { @@ -333,7 +359,7 @@ func validateExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *onda t.Errorf("ExportPolicy = %v, want %v", exportPolicies, []string{v4PrefixPolicy, v4LPPolicy}) } - bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv4Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("v4-bgpNet-dev2").UnicastIpv4PrefixAny().State()) + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv4Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("atePort1.BGP4.peer").UnicastIpv4PrefixAny().State()) found := false for _, bgpPrefix := range bgpPrefixes { if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == v42Route && @@ -364,7 +390,8 @@ func validateExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *onda } } -func configureImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { +func configureImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, operation string) { + batch := &gnmi.SetBatch{} root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() pdef1 := rp.GetOrCreatePolicyDefinition(v6PrefixPolicy) @@ -390,14 +417,23 @@ func configureImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { } stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) stmt2.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(localPref) - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + if operation == "set" { + gnmi.BatchReplace(batch, gnmi.OC().RoutingPolicy().Config(), rp) + } else if operation == "delete" { + gnmi.BatchDelete(batch, gnmi.OC().RoutingPolicy().Config()) + } dni := deviations.DefaultNetworkInstance(dut) path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() policy.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetImportPolicy([]string{v6PrefixPolicy, v6LPPolicy}) - gnmi.Replace(t, dut, path.Config(), policy) + if operation == "set" { + gnmi.BatchReplace(batch, path.Config(), policy) + } else if operation == "delete" { + gnmi.BatchDelete(batch, path.Config()) + } + batch.Set(t, dut) } func validateImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { @@ -408,28 +444,30 @@ func validateImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *on if len(importPolicies) != 2 { t.Errorf("ImportPolicy = %v, want %v", importPolicies, []string{v6PrefixPolicy, v6LPPolicy}) } - - bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() - locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv6Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast().LocRib().State()) - found := false - for k, lr := range locRib.Route { - if lr.GetPrefix() == advertisedIPv61.address { - found = true - t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) - attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) - if attrSet == nil || attrSet.GetLocalPref() != localPref { - t.Errorf("No local pref found for prefix %s", advertisedIPv61.address) + if !deviations.BGPRibOcPathUnsupported(dut) { + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv6Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast().LocRib().State()) + found := false + for k, lr := range locRib.Route { + if lr.GetPrefix() == advertisedIPv61.address { + found = true + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) + attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) + if attrSet == nil || attrSet.GetLocalPref() != localPref { + t.Errorf("No local pref found for prefix %s", advertisedIPv61.address) + } + break } - break } - } - if !found { - t.Errorf("No Route found for prefix %s", advertisedIPv61.address) + if !found { + t.Errorf("No Route found for prefix %s", advertisedIPv61.address) + } } } -func configureExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { +func configureExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, operation string) { + batch := &gnmi.SetBatch{} root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() pdef1 := rp.GetOrCreatePolicyDefinition(v6ASPPolicy) @@ -437,7 +475,6 @@ func configureExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", v6ASPStatement, err) } - stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend().SetAsn(dutAS) pdef2 := rp.GetOrCreatePolicyDefinition(v6MedPolicy) @@ -447,14 +484,23 @@ func configureExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { } stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) stmt2.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(oc.UnionUint32(med)) - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + if operation == "set" { + gnmi.BatchReplace(batch, gnmi.OC().RoutingPolicy().Config(), rp) + } else if operation == "delete" { + gnmi.BatchDelete(batch, gnmi.OC().RoutingPolicy().Config()) + } dni := deviations.DefaultNetworkInstance(dut) path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() policy.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetExportPolicy([]string{v6ASPPolicy, v6MedPolicy}) - gnmi.Replace(t, dut, path.Config(), policy) + if operation == "set" { + gnmi.BatchReplace(batch, path.Config(), policy) + } else if operation == "delete" { + gnmi.BatchDelete(batch, path.Config()) + } + batch.Set(t, dut) } func validateExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { @@ -466,7 +512,7 @@ func validateExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *on t.Errorf("ExportPolicy = %v, want %v", exportPolicies, []string{v6PrefixPolicy, v6LPPolicy}) } - bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv6Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("v6-bgpNet-dev2").UnicastIpv6PrefixAny().State()) + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv6Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("atePort1.BGP6.peer").UnicastIpv6PrefixAny().State()) found := false for _, bgpPrefix := range bgpPrefixes { if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == v62Route && @@ -578,30 +624,40 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + pgv4 := bgp.GetOrCreatePeerGroup(peerGrpNamev4) + pgv4.PeerGroupName = ygot.String(peerGrpNamev4) + pgv6 := bgp.GetOrCreatePeerGroup(peerGrpNamev6) + pgv6.PeerGroupName = ygot.String(peerGrpNamev6) nV41 := bgp.GetOrCreateNeighbor(atePort1.IPv4) - nV41.SetPeerAs(ateAS) + nV41.SetPeerAs(ateAS1) nV41.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV41.PeerGroup = ygot.String(peerGrpNamev4) nV42 := bgp.GetOrCreateNeighbor(atePort2.IPv4) - nV42.SetPeerAs(ateAS) + nV42.SetPeerAs(ateAS2) nV42.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV42.PeerGroup = ygot.String(peerGrpNamev4) nV61 := bgp.GetOrCreateNeighbor(atePort1.IPv6) - nV61.SetPeerAs(ateAS) + nV61.SetPeerAs(ateAS1) nV61.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nV61.PeerGroup = ygot.String(peerGrpNamev6) nV62 := bgp.GetOrCreateNeighbor(atePort2.IPv6) - nV62.SetPeerAs(ateAS) + nV62.SetPeerAs(ateAS2) nV62.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nV62.PeerGroup = ygot.String(peerGrpNamev6) gnmi.Update(t, td.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Config(), ni) // configure eBGP on OTG port1 ipv41 := td.otgP1.Ethernets().Items()[0].Ipv4Addresses().Items()[0] dev1BGP := td.otgP1.Bgp().SetRouterId(atePort1.IPv4) bgp4Peer1 := dev1BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv41.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP4.peer") - bgp4Peer1.SetPeerAddress(dutPort1.IPv4).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer1.SetPeerAddress(dutPort1.IPv4).SetAsNumber(ateAS1).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer1.LearnedInformationFilter().SetUnicastIpv4Prefix(true) ipv61 := td.otgP1.Ethernets().Items()[0].Ipv6Addresses().Items()[0] bgp6Peer1 := dev1BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv61.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP6.peer") - bgp6Peer1.SetPeerAddress(dutPort1.IPv6).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer1.SetPeerAddress(dutPort1.IPv6).SetAsNumber(ateAS1).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer1.LearnedInformationFilter().SetUnicastIpv6Prefix(true) // configure emulated network on ATE port1 netv41 := bgp4Peer1.V4Routes().Add().SetName("v4-bgpNet-dev1") @@ -613,11 +669,13 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { ipv42 := td.otgP2.Ethernets().Items()[0].Ipv4Addresses().Items()[0] dev2BGP := td.otgP2.Bgp().SetRouterId(atePort2.IPv4) bgp4Peer2 := dev2BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv42.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP4.peer") - bgp4Peer2.SetPeerAddress(dutPort2.IPv4).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer2.SetPeerAddress(dutPort2.IPv4).SetAsNumber(ateAS2).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer2.LearnedInformationFilter().SetUnicastIpv4Prefix(true) ipv62 := td.otgP2.Ethernets().Items()[0].Ipv6Addresses().Items()[0] bgp6Peer2 := dev2BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv62.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP6.peer") - bgp6Peer2.SetPeerAddress(dutPort2.IPv6).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer2.SetPeerAddress(dutPort2.IPv6).SetAsNumber(ateAS2).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer2.LearnedInformationFilter().SetUnicastIpv6Prefix(true) // configure emulated network on ATE port2 netv42 := bgp4Peer2.V4Routes().Add().SetName("v4-bgpNet-dev2") diff --git a/feature/bgp/policybase/otg_tests/chained_policies_test/metadata.textproto b/feature/bgp/policybase/otg_tests/chained_policies_test/metadata.textproto index 1210b24610d..11bbfd9320d 100644 --- a/feature/bgp/policybase/otg_tests/chained_policies_test/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/chained_policies_test/metadata.textproto @@ -17,3 +17,11 @@ platform_exceptions: { skip_set_rp_match_set_options: true } } +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + bgp_rib_oc_path_unsupported: true + } +} diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 008a5ae0cc3..c334e54beb4 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -825,3 +825,8 @@ func AddMissingBaseConfigViaCli(dut *ondatra.DUTDevice) bool { func SkipMacaddressCheck(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetSkipMacaddressCheck() } + +// BGPRibOcPathUnsupported returns true if BGP RIB OC telemetry path is not supported. +func BGPRibOcPathUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetBgpRibOcPathUnsupported() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index b8f53519fab..f9efbc2866a 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -439,6 +439,10 @@ message Metadata { // skip_macaddress_check returns true if mac address for an interface via gNMI needs to be skipped. // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 bool skip_macaddress_check = 154; + // Devices are having native telemetry paths for BGP RIB verification. + // Juniper : b/306144372 + bool bgp_rib_oc_path_unsupported = 155; + // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 5efd1976ab2..d3bd55eb024 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -710,6 +710,9 @@ type Metadata_Deviations struct { // skip_macaddress_check returns true if mac address for an interface via gNMI needs to be skipped. // Cisco: https://partnerissuetracker.corp.google.com/issues/322291556 SkipMacaddressCheck bool `protobuf:"varint,154,opt,name=skip_macaddress_check,json=skipMacaddressCheck,proto3" json:"skip_macaddress_check,omitempty"` + // Devices are having native telemetry paths for BGP RIB verification. + // Juniper : b/306144372 + BgpRibOcPathUnsupported bool `protobuf:"varint,155,opt,name=bgp_rib_oc_path_unsupported,json=bgpRibOcPathUnsupported,proto3" json:"bgp_rib_oc_path_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1710,6 +1713,13 @@ func (x *Metadata_Deviations) GetSkipMacaddressCheck() bool { return false } +func (x *Metadata_Deviations) GetBgpRibOcPathUnsupported() bool { + if x != nil { + return x.BgpRibOcPathUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1773,7 +1783,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf9, 0x55, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb8, 0x56, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1804,7 +1814,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xfa, 0x4d, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xb9, 0x4e, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2424,44 +2434,48 @@ var file_metadata_proto_rawDesc = []byte{ 0x66, 0x69, 0x67, 0x56, 0x69, 0x61, 0x43, 0x6c, 0x69, 0x12, 0x33, 0x0a, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x9a, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x4d, - 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4a, 0x04, - 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, - 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, - 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, - 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, - 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, - 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, - 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, - 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, - 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, - 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, - 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, - 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, - 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, - 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, - 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, - 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, - 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, - 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x3d, + 0x0a, 0x1b, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x69, 0x62, 0x5f, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x74, + 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x9b, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, 0x67, 0x70, 0x52, 0x69, 0x62, 0x4f, 0x63, 0x50, 0x61, + 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, + 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, + 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, + 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, + 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, + 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, + 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, + 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, + 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, + 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, + 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, + 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, + 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, + 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, + 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, + 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, + 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, + 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 64089e5d7a6776f8c3999f741e1c38caccee10db Mon Sep 17 00:00:00 2001 From: prinikasn <117314826+prinikasn@users.noreply.github.com> Date: Wed, 13 Mar 2024 09:49:16 -0700 Subject: [PATCH 15/97] adding test for low_power_mode (#2785) * adding test for low_power_mode * correct message * correct message * update for comments --- .../zr_low_power_mode_test/metadata.textproto | 7 + .../zr_low_power_mode_test.go | 180 ++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 feature/platform/transceiver/tests/zr_low_power_mode_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go diff --git a/feature/platform/transceiver/tests/zr_low_power_mode_test/metadata.textproto b/feature/platform/transceiver/tests/zr_low_power_mode_test/metadata.textproto new file mode 100644 index 00000000000..8236fb587cf --- /dev/null +++ b/feature/platform/transceiver/tests/zr_low_power_mode_test/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "92fbb383-47b3-40e6-ab33-77be99e450b3" +plan_id: "TRANSCEIVER-13" +description: "Configuration: 400ZR Transceiver Low Power Mode Setting." +testbed: TESTBED_DUT_400ZR diff --git a/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go b/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go new file mode 100644 index 00000000000..47c6ea4e1c4 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go @@ -0,0 +1,180 @@ +// 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 zr_low_power_mode_test + +import ( + "fmt" + "math" + "reflect" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" +) + +const ( + samplingInterval = 10 * time.Second + targetOutputPowerdBm = -10 + targetOutputPowerTolerancedBm = 1 + targetFrequencyHz = 193100000 + targetFrequencyToleranceHz = 100000 +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// validateStreamOutput validates that the OC path is streamed in the most recent subscription interval. +func validateStreamOutput(t *testing.T, dut *ondatra.DUTDevice, streams map[string]*samplestream.SampleStream[string]) { + for key, stream := range streams { + output := stream.Next(t) + if output == nil { + t.Fatalf("OC path for %s not streamed in the most recent subscription interval", key) + } + value, ok := output.Val() + if !ok { + t.Fatalf("Error capturing streaming value for %s", key) + } + if reflect.TypeOf(value).Kind() != reflect.String { + t.Fatalf("Return value is not type string for key :%s", key) + } + if value == "" { + t.Fatalf("OC path empty for %s", key) + } + t.Logf("Value for OC path %s: %s", key, value) + } +} + +// validateOutputPower validates that the output power is streamed in the most recent subscription interval. +func validateOutputPower(t *testing.T, dut *ondatra.DUTDevice, streams map[string]*samplestream.SampleStream[float64]) { + for key, stream := range streams { + outputStream := stream.Next(t) + if outputStream == nil { + t.Fatalf("OC path for %s not streamed in the most recent subscription interval", key) + } + outputPower, ok := outputStream.Val() + if !ok { + t.Fatalf("Error capturing streaming value for %s", key) + } + // Check output power value is of correct type + if reflect.TypeOf(outputPower).Kind() != reflect.Float64 { + t.Fatalf("Return value is not type float64 for key :%s", key) + } + t.Logf("Output power for %s: %f", key, outputPower) + } +} + +func TestLowPowerMode(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + for _, port := range []string{"port1", "port2"} { + t.Run(fmt.Sprintf("Port:%s", port), func(t *testing.T) { + dp := dut.Port(t, port) + + gnmi.Update(t, dut, gnmi.OC().Interface(dp.Name()).Enabled().Config(), bool(false)) + + // Derive transceiver names from ports. + tr := gnmi.Get(t, dut, gnmi.OC().Interface(dp.Name()).Transceiver().State()) + + // Stream all inventory information. + streamSerialNo := samplestream.New(t, dut, gnmi.OC().Component(tr).SerialNo().State(), samplingInterval) + defer streamSerialNo.Close() + streamPartNo := samplestream.New(t, dut, gnmi.OC().Component(tr).PartNo().State(), samplingInterval) + defer streamPartNo.Close() + streamType := samplestream.New(t, dut, gnmi.OC().Component(tr).Type().State(), samplingInterval) + defer streamType.Close() + streamDescription := samplestream.New(t, dut, gnmi.OC().Component(tr).Description().State(), samplingInterval) + defer streamDescription.Close() + streamMfgName := samplestream.New(t, dut, gnmi.OC().Component(tr).MfgName().State(), samplingInterval) + defer streamMfgName.Close() + streamMfgDate := samplestream.New(t, dut, gnmi.OC().Component(tr).MfgDate().State(), samplingInterval) + defer streamMfgDate.Close() + streamHwVersion := samplestream.New(t, dut, gnmi.OC().Component(tr).HardwareVersion().State(), samplingInterval) + defer streamHwVersion.Close() + streamFirmwareVersion := samplestream.New(t, dut, gnmi.OC().Component(tr).FirmwareVersion().State(), samplingInterval) + defer streamFirmwareVersion.Close() + + allStream := map[string]*samplestream.SampleStream[string]{ + "serialNo": streamSerialNo, + "partNo": streamPartNo, + "description": streamDescription, + "mfgName": streamMfgName, + "mfgDate": streamMfgDate, + "hwVersion": streamHwVersion, + "firmwareVersion": streamFirmwareVersion, + } + validateStreamOutput(t, dut, allStream) + + opInst := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Instant().State(), samplingInterval) + defer opInst.Close() + if opInstN := opInst.Next(t); opInstN != nil { + if _, ok := opInstN.Val(); ok { + t.Fatalf("streaming /components/component/optical-channel/state/output-power/instant is not expected to be reported") + } + } + + opAvg := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Avg().State(), samplingInterval) + defer opAvg.Close() + if opAvgN := opAvg.Next(t); opAvgN != nil { + if _, ok := opAvgN.Val(); ok { + t.Fatalf("streaming /components/component/optical-channel/state/output-power/avg is not expected to be reported") + } + } + + opMin := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Min().State(), samplingInterval) + defer opMin.Close() + if opMinN := opMin.Next(t); opMinN != nil { + if _, ok := opMinN.Val(); ok { + t.Fatalf("streaming /components/component/optical-channel/state/output-power/min is not expected to be reported") + } + } + + opMax := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Max().State(), samplingInterval) + defer opMax.Close() + if opMaxN := opMax.Next(t); opMaxN != nil { + if _, ok := opMaxN.Val(); ok { + t.Fatalf("streaming /components/component/optical-channel/state/output-power/max is not expected to be reported") + } + } + + gnmi.Update(t, dut, gnmi.OC().Interface(dp.Name()).Enabled().Config(), bool(true)) + + powerStreamMap := map[string]*samplestream.SampleStream[float64]{ + "inst": opInst, + "avg": opAvg, + "min": opMin, + "max": opMax, + } + + validateOutputPower(t, dut, powerStreamMap) + + // Derive transceiver names from ports. + component := gnmi.OC().Component(tr) + + outputPower := gnmi.Get(t, dut, component.OpticalChannel().TargetOutputPower().State()) + if math.Abs(float64(outputPower)-float64(targetOutputPowerdBm)) > targetOutputPowerTolerancedBm { + t.Fatalf("Output power is not within expected tolerance, got: %v want: %v tolerance: %v", outputPower, targetOutputPowerdBm, targetOutputPowerTolerancedBm) + } + + frequency := gnmi.Get(t, dut, component.OpticalChannel().Frequency().State()) + if math.Abs(float64(frequency)-float64(targetFrequencyHz)) > targetFrequencyToleranceHz { + t.Fatalf("Frequency is not within expected tolerance, got: %v want: %v tolerance: %v", frequency, targetFrequencyHz, targetFrequencyToleranceHz) + } + }) + } +} From 1b84a6d04bc78a2b79ea3ebef6e2a92d728d1824 Mon Sep 17 00:00:00 2001 From: anksaiki Date: Wed, 13 Mar 2024 13:44:02 -0400 Subject: [PATCH 16/97] Weighted ECMP for ISIS test (#2801) * Weighted ECMP test * fix numbering * Add 100G-FR logic to be able to choose FR ports if required --- .../vrf_policy_driven_te_test.go | 34 +- .../otg_tests/encap_frr/encap_frr_test.go | 21 +- .../weighted_balancing_test/setup_test.go | 17 + .../otg_tests/weighted_ecmp_test/README.md | 187 +++++ .../weighted_ecmp_test/metadata.textproto | 23 + .../weighted_ecmp_test/weighted_ecmp_test.go | 636 ++++++++++++++++++ feature/isis/weighted_ECMP/README.md | 93 --- 7 files changed, 909 insertions(+), 102 deletions(-) create mode 100644 feature/isis/otg_tests/weighted_ecmp_test/README.md create mode 100644 feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto create mode 100644 feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go delete mode 100644 feature/isis/weighted_ECMP/README.md diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go index 2d5f1cff9e1..c89bcc016f2 100644 --- a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go +++ b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go @@ -500,14 +500,17 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { portList := []*ondatra.Port{p1, p2, p3, p4, p5, p6, p7, p8} portNameList := []string{"port1", "port2", "port3", "port4", "port5", "port6", "port7", "port8"} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p3.Name()).Config(), dutPort3.NewOCInterface(p3.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p4.Name()).Config(), dutPort4.NewOCInterface(p4.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p5.Name()).Config(), dutPort5.NewOCInterface(p5.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p6.Name()).Config(), dutPort6.NewOCInterface(p6.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p7.Name()).Config(), dutPort7.NewOCInterface(p7.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p8.Name()).Config(), dutPort8.NewOCInterface(p8.Name(), dut)) + for idx, a := range []attrs.Attributes{dutPort1, dutPort2, dutPort3, dutPort4, dutPort5, dutPort6, dutPort7, dutPort8} { + p := portList[idx] + intf := a.NewOCInterface(p.Name(), dut) + if p.PMD() == ondatra.PMD100GBASEFR { + e := intf.GetOrCreateEthernet() + e.AutoNegotiate = ygot.Bool(false) + e.DuplexMode = oc.Ethernet_DuplexMode_FULL + e.PortSpeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB + } + gnmi.Replace(t, dut, d.Interface(p.Name()).Config(), intf) + } // Configure loopback interface. loopbackIntfName = netutil.LoopbackInterface(t, dut, 0) @@ -1072,6 +1075,21 @@ func configureOTG(t *testing.T, otg *otg.OTG, ate *ondatra.ATEDevice) gosnappi.C port7 := config.Ports().Add().SetName("port7") port8 := config.Ports().Add().SetName("port8") + pmd100GFRPorts := []string{} + for _, p := range config.Ports().Items() { + port := ate.Port(t, p.Name()) + if port.PMD() == ondatra.PMD100GBASEFR { + pmd100GFRPorts = append(pmd100GFRPorts, port.ID()) + } + } + // Disable FEC for 100G-FR ports because Novus does not support it. + if len(pmd100GFRPorts) > 0 { + l1Settings := config.Layer1().Add().SetName("L1").SetPortNames(pmd100GFRPorts) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } + iDut1Dev := config.Devices().Add().SetName(atePort1.Name) iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1.Name + ".Eth").SetMac(atePort1.MAC) iDut1Eth.Connection().SetPortName(port1.Name()) diff --git a/feature/gribi/otg_tests/encap_frr/encap_frr_test.go b/feature/gribi/otg_tests/encap_frr/encap_frr_test.go index 089dcf58a11..135ecc28b7b 100644 --- a/feature/gribi/otg_tests/encap_frr/encap_frr_test.go +++ b/feature/gribi/otg_tests/encap_frr/encap_frr_test.go @@ -267,6 +267,13 @@ func dutInterface(p *ondatra.Port, dut *ondatra.DUTDevice) *oc.Interface { i.Enabled = ygot.Bool(true) } + if p.PMD() == ondatra.PMD100GBASEFR { + e := i.GetOrCreateEthernet() + e.AutoNegotiate = ygot.Bool(false) + e.DuplexMode = oc.Ethernet_DuplexMode_FULL + e.PortSpeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB + } + ipv4, ok := portsIPv4[id] if !ok { return nil @@ -740,8 +747,11 @@ func verifyBgpTelemetry(t *testing.T, dut *ondatra.DUTDevice) { func configureOTG(t testing.TB, otg *otg.OTG, atePorts []*ondatra.Port) gosnappi.Config { t.Helper() config := gosnappi.NewConfig() - // ate := ondatra.ATE(t, "ate") + pmd100GFRPorts := []string{} for i, ap := range atePorts { + if ap.PMD() == ondatra.PMD100GBASEFR { + pmd100GFRPorts = append(pmd100GFRPorts, ap.ID()) + } // DUT and ATE ports are connected by the same names. dutid := fmt.Sprintf("dut:%s", ap.ID()) ateid := fmt.Sprintf("ate:%s", ap.ID()) @@ -800,6 +810,15 @@ func configureOTG(t testing.TB, otg *otg.OTG, atePorts []*ondatra.Port) gosnappi SetPortNames([]string{atePortNamelist[1], atePortNamelist[2], atePortNamelist[3], atePortNamelist[4], atePortNamelist[5], atePortNamelist[6], atePortNamelist[7]}). SetFormat(gosnappi.CaptureFormat.PCAP) + + // Disable FEC for 100G-FR ports because Novus does not support it. + if len(pmd100GFRPorts) > 0 { + l1Settings := config.Layer1().Add().SetName("L1").SetPortNames(pmd100GFRPorts) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } + otg.PushConfig(t, config) time.Sleep(30 * time.Second) otg.StartProtocols(t) diff --git a/feature/gribi/otg_tests/weighted_balancing_test/setup_test.go b/feature/gribi/otg_tests/weighted_balancing_test/setup_test.go index 26cc43e6fda..7552b9339c9 100644 --- a/feature/gribi/otg_tests/weighted_balancing_test/setup_test.go +++ b/feature/gribi/otg_tests/weighted_balancing_test/setup_test.go @@ -187,6 +187,12 @@ func configureDUT(t testing.TB, dut *ondatra.DUTDevice) { dc := gnmi.OC() for _, dp := range dut.Ports() { if i := dutInterface(dp, dut); i != nil { + if dp.PMD() == ondatra.PMD100GBASEFR { + e := i.GetOrCreateEthernet() + e.AutoNegotiate = ygot.Bool(false) + e.DuplexMode = oc.Ethernet_DuplexMode_FULL + e.PortSpeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB + } gnmi.Replace(t, dut, dc.Interface(dp.Name()).Config(), i) } else { t.Fatalf("No address found for port %v", dp) @@ -208,7 +214,11 @@ func configureDUT(t testing.TB, dut *ondatra.DUTDevice) { func configureATE(t testing.TB, ate *ondatra.ATEDevice) gosnappi.Config { t.Helper() config := gosnappi.NewConfig() + pmd100GFRPorts := []string{} for i, ap := range ate.Ports() { + if ap.PMD() == ondatra.PMD100GBASEFR { + pmd100GFRPorts = append(pmd100GFRPorts, ap.ID()) + } // DUT and ATE ports are connected by the same names. dutid := fmt.Sprintf("dut:%s", ap.ID()) ateid := fmt.Sprintf("ate:%s", ap.ID()) @@ -222,6 +232,13 @@ func configureATE(t testing.TB, ate *ondatra.ATEDevice) gosnappi.Config { SetAddress(portsIPv4[ateid]).SetGateway(portsIPv4[dutid]). SetPrefix(plen) } + // Disable FEC for 100G-FR ports because Novus does not support it. + if len(pmd100GFRPorts) > 0 { + l1Settings := config.Layer1().Add().SetName("L1").SetPortNames(pmd100GFRPorts) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } ate.OTG().PushConfig(t, config) return config } diff --git a/feature/isis/otg_tests/weighted_ecmp_test/README.md b/feature/isis/otg_tests/weighted_ecmp_test/README.md new file mode 100644 index 00000000000..11c38537efc --- /dev/null +++ b/feature/isis/otg_tests/weighted_ecmp_test/README.md @@ -0,0 +1,187 @@ +# RT-2.13: Weighted-ECMP for IS-IS + +## Summary + +This is to ensure that, + +* Implementations can be configured for weighted equal cost multipath (ECMP) + routing for IS-IS neighbors that are one hop away. + +* When WECMP is enabled, traffic destined to an IS-IS route represented by a + multipath set of next-hop interfaces will be unequally distributed across + the interfaces based on their bandwidth. + +## Testbed type + +[TESTBED_DUT_ATE_8LINKS](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_8.testbed) + +## Topolgy + +Each LAG bundle below is made up of 2x100G ports. + +```mermaid +graph LR; +A[ATE1:LAG1] <-- IBGP+IS-IS --> B[LAG1:DUT]; +C[DUT:LAG2] <-- IBGP+IS-IS --> D[LAG1:ATE2]; +E[DUT:LAG3] <-- IBGP+IS-IS --> F[LAG2:ATE2]; +G[DUT:LAG4] <-- IBGP+IS-IS --> H[LAG3:ATE2]; +``` + +## Procedure + +In the topology above, + +* Configure 1xLAG interface between ATE1<->DUT and 3xLAG interfaces between + DUT and ATE2. Each LAG interface is expected to be of 2x100Gbps + +* Configure IPv4 and IPv6 L2 adjacencies between DUT and ATE LAG bundles. + Therefore, DUT will have 1xIS-IS adjacency with ATE1 i.e. + DUT:LAG1<->ATE1:LAG1, and 3xIS-IS adjacencies with ATE2 i.e. + DUT:LAG2<->ATE2:LAG1, DUT:LAG3<->ATE2:LAG2 and DUT:LAG4<->ATE2:LAG3 + + * /network-instances/network-instance/protocols/protocol/isis/global/afi-safi + + * /network-instances/network-instance/protocols/protocol/isis/global/config/level-capability, + set to LEVEL_2 + + * /network-instances/network-instance/protocols/protocol/isis/levels/level/config/metric-style + set to WIDE_METRIC + +* Configure IPv4 and IPv6 IBGP peering between both ATEs and the DUT using + their loopback addresses for both IPv4 and IPv6 address families. + + * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/config + +* Attach a network with an IPv4 and an IPv6 prefix to ATE2 and have it + advertise these prefixes over its IBGP peering with the DUT. The DUT in turn + should advertise these prefixes over its IBGP peering with ATE1 + + * Please use `IPv4 prefix = 100.0.1.0/24` and `IPv6 prefix = + 2001:db8:64:64::/64` + +* Similarly, attach a different network to ATE1 with IPv4 and IPv6 prefixes + and advertise the same over its IBGP peering with the DUT. + + * Please use `IPv4 prefix = 100.0.2.0/24` and `IPv6 prefix = + 2001:db8:64:65::/64` + +* On the DUT, enable WECMP loadbalancing for multipath IS-IS routes and set + the load-balancing-weight to use LAG bandwidth. + + * /network-instances/network-instance/protocols/protocol/isis/global/config/weighted-ecmp + set to Enabled + + * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/config/load-balancing-weight + set to Auto + +## RT-9.1: Equal distribution of traffic + +* Start 1024 flows from IPv4 addresses in 100.0.2.0/24 to 100.0.1.0/24 + +* Start 1024 flows from IPv6 addresses in 2001:db8:64:65::/64 to + 2001:db8:64:64::/64 + +* Ensure that the total traffic of all flows combined is ~20Gbps + +### Verification + +* Ensure that the DUT has learnt the routes for prefixes 100.0.1.0/24 and + 2001:db8:64:64::/64 over IBGP. Following paths + + * /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address + +* Ensure that the DUT has learnt routes to the IPv4 and IPv6 loopback + addresses of ATE2. It is expected that these prefixes are reachable via 3 + different Next-Hop addresses corresponding to the LAG1, LAG2 and LAG3 + interfaces on ATE2. + +* It is expected that the IS-IS instance in DUT will equally distribute the + traffic received on DUT:LAG1 over the LAG bundles corresponding to + ATE2:LAG1, ATE2:LAG2 and ATE2:LAG3 when the 3 LAG bundles have the same + bandwidth available. + + * Traffic distribution between DUT:LAG2, DUT:LAG3 and DUT:LAG4 is expected + to be ~33% each of the total traffic received on DUT:LAG1. + + * Check for the following paths + + * /network-instances/network-instance/protocols/protocol/isis/global/state/weighted-ecmp, + should be true + + * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/state/load-balancing-weight, + should be auto + + * /interfaces/interface/state/counters/out-pkts + + * /interfaces/interface/state/counters/in-pkts + +## RT-9.2: Unequal distribution of traffic + +* Stop traffic from RT-9.1 and introduce a failure by disabling one of the + member interfaces in ATE2:LAG1. + +* Restart 1024 flows from IPv4 addresses in 100.0.2.0/24 to 100.0.1.0/24 + +* Restart 1024 flows from IPv6 addresses in 2001:db8:64:65::/64 to + 2001:db8:64:64::/64 + +* Ensure that the total traffic of all flows combined is ~20Gbps + +### Verification + +* It is expected that the IS-IS instance in DUT will unequally distribute the + traffic received from ATE1:LAG1 over the LAG bundles corresponding to + ATE2:LAG1, ATE2:LAG2 and ATE3:LAG3. + + * Traffic on DUT:LAG2 is expected to be ~20% while traffic on DUT:LAG3 and + DUT:LAG4 is expected to be ~40% each of the total traffic received on + DUT:LAG1. If the traffic is not unequally shared between the DUT LAG + bundles towards ATE2 then this test is a failure. + + * Check for the following paths + + * /interfaces/interface/state/counters/out-pkts + + * /interfaces/interface/state/counters/in-pkts + +### Config paths + +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/config + +* /network-instances/network-instance/protocols/protocol/isis/global/afi-safi + +* /network-instances/network-instance/protocols/protocol/isis/global/config/level-capability + +* /network-instances/network-instance/protocols/protocol/isis/levels/level/config/metric-style + +* /network-instances/network-instance/protocols/protocol/isis/global/config/weighted-ecmp + +* /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/config/load-balancing-weight + +* /routing-policy/defined-sets/prefix-sets/prefix-set/ + +* /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/ip-prefix + +* /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/masklength-range/exact + +* /routing-policy/policy-definitions/policy-definition/config/name + +* /routing-policy/policy-definitions/policy-definition/statements/statement/config/name + +* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set + +* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options + +* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result/ACCEPT_ROUTE + +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/peer-group/afi-safis/afi-safi/apply-policy/config/import-policy + +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/peer-group/afi-safis/afi-safi/apply-policy/config/export-policy + +### Telemetry Parameter Coverage + +* /network-instances/network-instance/protocols/protocol/isis/global/state/weighted-ecmp +* /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/state/load-balancing-weight +* /interfaces/interface/state/counters/out-pkts +* /interfaces/interface/state/counters/in-pkts diff --git a/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto b/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto new file mode 100644 index 00000000000..560a8eb30ed --- /dev/null +++ b/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto @@ -0,0 +1,23 @@ +# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "2beaac46-9b7b-49c4-9bde-62ad530aa5c4" +plan_id: "RT-2.13" +description: "Weighted-ECMP for IS-IS" +testbed: TESTBED_DUT_ATE_8LINKS +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + omit_l2_mtu: true + isis_instance_enabled_required: true + isis_interface_afi_unsupported: true + missing_isis_interface_afi_safi_enable: true + isis_require_same_l1_metric_with_l2_metric: true + route_policy_under_afi_unsupported: true + static_protocol_name: "STATIC" + } +} diff --git a/feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go b/feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go new file mode 100644 index 00000000000..22edb4514ec --- /dev/null +++ b/feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go @@ -0,0 +1,636 @@ +package weighted_ecmp_test + +import ( + "fmt" + "testing" + "time" + + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/cfgplugins" + "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/ondatra/netutil" + "github.com/openconfig/ygot/ygot" +) + +const ( + ipv4PLen = 30 + ipv6PLen = 126 + isisInstance = "DEFAULT" + dutAreaAddress = "49.0001" + ateAreaAddress = "49" + dutSysID = "1920.0000.2001" + asn = 64501 + acceptRoutePolicy = "PERMIT-ALL" + trafficPPS = 5000000 + srcTrafficV4 = "100.0.2.1" + srcTrafficV6 = "2001:db8:64:65::1" + dstTrafficV4 = "100.0.1.1" + dstTrafficV6 = "2001:db8:64:64::1" + v4Count = 254 + v6Count = 100000000 +) + +type aggPortData struct { + dutIPv4 string + ateIPv4 string + dutIPv6 string + ateIPv6 string + ateAggName string + ateAggMAC string + atePort1MAC string + atePort2MAC string + ateISISSysID string + ateLoopbackV4 string + ateLoopbackV6 string +} + +type ipAddr struct { + ip string + prefix uint32 +} + +var ( + agg1 = &aggPortData{ + dutIPv4: "192.0.2.1", + ateIPv4: "192.0.2.2", + dutIPv6: "2001:db8::1", + ateIPv6: "2001:db8::2", + ateAggName: "lag1", + ateAggMAC: "02:00:01:01:01:01", + atePort1MAC: "02:00:01:01:01:02", + atePort2MAC: "02:00:01:01:01:03", + ateISISSysID: "640000000002", + ateLoopbackV4: "192.0.2.17", + ateLoopbackV6: "2001:db8::17", + } + agg2 = &aggPortData{ + dutIPv4: "192.0.2.5", + ateIPv4: "192.0.2.6", + dutIPv6: "2001:db8::5", + ateIPv6: "2001:db8::6", + ateAggName: "lag2", + ateAggMAC: "02:00:01:01:01:04", + atePort1MAC: "02:00:01:01:01:05", + atePort2MAC: "02:00:01:01:01:06", + ateISISSysID: "640000000003", + ateLoopbackV4: "192.0.2.18", + ateLoopbackV6: "2001:db8::18", + } + agg3 = &aggPortData{ + dutIPv4: "192.0.2.9", + ateIPv4: "192.0.2.10", + dutIPv6: "2001:db8::9", + ateIPv6: "2001:db8::10", + ateAggName: "lag3", + ateAggMAC: "02:00:01:01:01:07", + atePort1MAC: "02:00:01:01:01:08", + atePort2MAC: "02:00:01:01:01:09", + ateISISSysID: "640000000004", + ateLoopbackV4: "192.0.2.18", + ateLoopbackV6: "2001:db8::18", + } + agg4 = &aggPortData{ + dutIPv4: "192.0.2.13", + ateIPv4: "192.0.2.14", + dutIPv6: "2001:db8::13", + ateIPv6: "2001:db8::14", + ateAggName: "lag4", + ateAggMAC: "02:00:01:01:01:10", + atePort1MAC: "02:00:01:01:01:11", + atePort2MAC: "02:00:01:01:01:12", + ateISISSysID: "640000000005", + ateLoopbackV4: "192.0.2.18", + ateLoopbackV6: "2001:db8::18", + } + + dutLoopback = attrs.Attributes{ + Desc: "Loopback ip", + IPv4: "192.0.2.21", + IPv6: "2001:db8::21", + IPv4Len: 32, + IPv6Len: 128, + } + ate1AdvV4 = &ipAddr{ip: "100.0.2.0", prefix: 24} + ate1AdvV6 = &ipAddr{ip: "2001:db8:64:65::0", prefix: 64} + ate2AdvV4 = &ipAddr{ip: "100.0.1.0", prefix: 24} + ate2AdvV6 = &ipAddr{ip: "2001:db8:64:64::0", prefix: 64} + + equalDistributionWeights = []uint64{33, 33, 33} + unequalDistributionWeights = []uint64{20, 40, 40} + + ecmpTolerance = uint64(1) +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestWeightedECMPForISIS(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + aggIDs := configureDUT(t, dut) + + // Enable weighted ECMP and set LoadBalancing to Auto + b := &gnmi.SetBatch{} + isisPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance).Isis() + gnmi.BatchReplace(b, isisPath.Global().WeightedEcmp().Config(), true) + for _, aggID := range aggIDs { + gnmi.BatchReplace(b, isisPath.Interface(aggID).WeightedEcmp().Config(), &oc.NetworkInstance_Protocol_Isis_Interface_WeightedEcmp{ + LoadBalancingWeight: oc.NetworkInstance_Protocol_Isis_Interface_WeightedEcmp_LoadBalancingWeight_Union(oc.WeightedEcmp_LoadBalancingWeight_auto), + }) + } + b.Set(t, dut) + + top := configureATE(t, ate) + flows := configureFlows(t, top, ate1AdvV4, ate1AdvV6, ate2AdvV4, ate2AdvV6) + + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + for _, agg := range []*aggPortData{agg1, agg2} { + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + gnmi.Await(t, dut, bgpPath.Neighbor(agg.ateLoopbackV4).SessionState().State(), time.Minute, oc.Bgp_Neighbor_SessionState_ESTABLISHED) + gnmi.Await(t, dut, bgpPath.Neighbor(agg.ateLoopbackV6).SessionState().State(), time.Minute, oc.Bgp_Neighbor_SessionState_ESTABLISHED) + } + + startTraffic(t, ate, top) + + t.Run("Equal_Distribution_Of_Traffic", func(t *testing.T) { + for _, flow := range flows { + loss := otgutils.GetFlowLossPct(t, ate.OTG(), flow.Name(), 5*time.Second) + if got, want := loss, 0.0; got != want { + t.Errorf("Flow %s loss: got %f, want %f", flow.Name(), got, want) + } + } + weights := trafficRXWeights(t, ate, []string{agg2.ateAggName, agg3.ateAggName, agg4.ateAggName}) + for idx, weight := range equalDistributionWeights { + if got, want := weights[idx], weight; got < want-ecmpTolerance || got > want+ecmpTolerance { + t.Errorf("ECMP Percentage for Aggregate Index: %d: got %d, want %d", idx+1, got, want) + } + } + }) + + // Disable ATE2:Port1 + if deviations.ATEPortLinkStateOperationsUnsupported(ate) { + p3 := dut.Port(t, "port3") + gnmi.Replace(t, dut, gnmi.OC().Interface(p3.Name()).Enabled().Config(), false) + } else { + p3 := ate.Port(t, "port3") // ATE:port3 is ATE2:port1 + psa := gosnappi.NewControlState() + psa.Port().Link().SetPortNames([]string{p3.ID()}).SetState(gosnappi.StatePortLinkState.DOWN) + ate.OTG().SetControlState(t, psa) + + defer func() { + psa := gosnappi.NewControlState() + psa.Port().Link().SetPortNames([]string{p3.ID()}).SetState(gosnappi.StatePortLinkState.UP) + ate.OTG().SetControlState(t, psa) + }() + } + p3 := dut.Port(t, "port3") + gnmi.Await(t, dut, gnmi.OC().Interface(p3.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_LOWER_LAYER_DOWN) + + startTraffic(t, ate, top) + + t.Run("Unequal_Distribution_Of_Traffic", func(t *testing.T) { + for _, flow := range flows { + loss := otgutils.GetFlowLossPct(t, ate.OTG(), flow.Name(), 5*time.Second) + if got, want := loss, 0.0; got != want { + t.Errorf("Flow %s loss: got %f, want %f", flow.Name(), got, want) + } + } + weights := trafficRXWeights(t, ate, []string{agg2.ateAggName, agg3.ateAggName, agg4.ateAggName}) + for idx, weight := range unequalDistributionWeights { + if got, want := weights[idx], weight; got < want-ecmpTolerance || got > want+ecmpTolerance { + t.Errorf("ECMP Percentage for Aggregate Index: %d: got %d, want %d", idx+1, got, want) + } + } + }) +} + +func trafficRXWeights(t *testing.T, ate *ondatra.ATEDevice, aggNames []string) []uint64 { + t.Helper() + var rxs []uint64 + for _, aggName := range aggNames { + metrics := gnmi.Get(t, ate.OTG(), gnmi.OTG().Lag(aggName).State()) + rxs = append(rxs, metrics.GetCounters().GetInFrames()) + } + var total uint64 + for _, rx := range rxs { + total += rx + } + for idx, rx := range rxs { + rxs[idx] = (rx * 100) / total + } + return rxs +} + +func startTraffic(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) { + t.Helper() + ate.OTG().StartTraffic(t) + time.Sleep(time.Minute) + ate.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, ate.OTG(), top) + otgutils.LogLAGMetrics(t, ate.OTG(), top) +} + +func configureFlows(t *testing.T, top gosnappi.Config, srcV4, srcV6, dstV4, dstV6 *ipAddr) []gosnappi.Flow { + t.Helper() + fV4 := top.Flows().Add().SetName("flowV4") + fV4.Metrics().SetEnable(true) + fV4.TxRx().Device(). + SetTxNames([]string{agg1.ateAggName + ".IPv4"}). + SetRxNames([]string{agg2.ateAggName + ".IPv4", agg3.ateAggName + ".IPv4", agg4.ateAggName + ".IPv4"}) + fV4.Size().SetFixed(1500) + fV4.Rate().SetPps(trafficPPS) + eV4 := fV4.Packet().Add().Ethernet() + eV4.Src().SetValue(agg1.ateAggMAC) + v4 := fV4.Packet().Add().Ipv4() + v4.Src().Increment().SetStart(srcTrafficV4).SetCount(v4Count) + v4.Dst().Increment().SetStart(dstTrafficV4).SetCount(v4Count) + + fV6 := top.Flows().Add().SetName("flowV6") + fV6.Metrics().SetEnable(true) + fV6.TxRx().Device(). + SetTxNames([]string{agg1.ateAggName + ".IPv6"}). + SetRxNames([]string{agg2.ateAggName + ".IPv6", agg3.ateAggName + ".IPv6", agg4.ateAggName + ".IPv6"}) + fV6.Size().SetFixed(1500) + fV6.Rate().SetPps(trafficPPS) + eV6 := fV6.Packet().Add().Ethernet() + eV6.Src().SetValue(agg1.ateAggMAC) + + v6 := fV6.Packet().Add().Ipv6() + v6.Src().Increment().SetStart(srcTrafficV6).SetCount(v6Count) + v6.Dst().Increment().SetStart(dstTrafficV6).SetCount(v6Count) + + return []gosnappi.Flow{fV4, fV6} +} + +func configureATE(t *testing.T, ate *ondatra.ATEDevice) gosnappi.Config { + t.Helper() + top := gosnappi.NewConfig() + pmd100GFRPorts := []string{} + + for aggIdx, a := range []*aggPortData{agg1, agg2, agg3, agg4} { + p1 := ate.Port(t, fmt.Sprintf("port%d", (aggIdx*2)+1)) + p2 := ate.Port(t, fmt.Sprintf("port%d", (aggIdx*2)+2)) + top.Ports().Add().SetName(p1.ID()) + top.Ports().Add().SetName(p2.ID()) + if p1.PMD() == ondatra.PMD100GBASEFR { + pmd100GFRPorts = append(pmd100GFRPorts, p1.ID()) + } + if p2.PMD() == ondatra.PMD100GBASEFR { + pmd100GFRPorts = append(pmd100GFRPorts, p2.ID()) + } + + agg := top.Lags().Add().SetName(a.ateAggName) + agg.Protocol().Static().SetLagId(uint32(aggIdx + 1)) + + lagDev := top.Devices().Add().SetName(agg.Name() + ".Dev") + lagEth := lagDev.Ethernets().Add().SetName(agg.Name() + ".Eth").SetMac(a.ateAggMAC) + lagEth.Connection().SetLagName(agg.Name()) + lagEth.Ipv4Addresses().Add().SetName(agg.Name() + ".IPv4").SetAddress(a.ateIPv4).SetGateway(a.dutIPv4).SetPrefix(ipv4PLen) + lagEth.Ipv6Addresses().Add().SetName(agg.Name() + ".IPv6").SetAddress(a.ateIPv6).SetGateway(a.dutIPv6).SetPrefix(ipv6PLen) + lagDev.Ipv4Loopbacks().Add().SetName(agg.Name() + ".Loopback4").SetEthName(lagEth.Name()).SetAddress(a.ateLoopbackV4) + lagDev.Ipv6Loopbacks().Add().SetName(agg.Name() + ".Loopback6").SetEthName(lagEth.Name()).SetAddress(a.ateLoopbackV6) + + agg.Ports().Add().SetPortName(p1.ID()).Ethernet().SetMac(a.atePort1MAC).SetName(a.ateAggName + ".1") + agg.Ports().Add().SetPortName(p2.ID()).Ethernet().SetMac(a.atePort2MAC).SetName(a.ateAggName + ".2") + + configureOTGISIS(t, lagDev, a) + if aggIdx == 0 { + configureOTGBGP(t, lagDev, a, ate1AdvV4, ate1AdvV6) + } else { + configureOTGBGP(t, lagDev, a, ate2AdvV4, ate2AdvV6) + } + } + + // Disable FEC for 100G-FR ports because Novus does not support it. + if len(pmd100GFRPorts) > 0 { + l1Settings := top.Layer1().Add().SetName("L1").SetPortNames(pmd100GFRPorts) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } + return top +} + +func configureOTGBGP(t *testing.T, dev gosnappi.Device, agg *aggPortData, advV4, advV6 *ipAddr) { + t.Helper() + v4 := dev.Ipv4Loopbacks().Items()[0] + v6 := dev.Ipv6Loopbacks().Items()[0] + + iDutBgp := dev.Bgp().SetRouterId(agg.ateIPv4) + iDutBgp4Peer := iDutBgp.Ipv4Interfaces().Add().SetIpv4Name(v4.Name()).Peers().Add().SetName(agg.ateAggName + ".BGP4.peer") + iDutBgp4Peer.SetPeerAddress(dutLoopback.IPv4).SetAsNumber(asn).SetAsType(gosnappi.BgpV4PeerAsType.IBGP) + iDutBgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(false) + iDutBgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(false) + + iDutBgp6Peer := iDutBgp.Ipv6Interfaces().Add().SetIpv6Name(v6.Name()).Peers().Add().SetName(agg.ateAggName + ".BGP6.peer") + iDutBgp6Peer.SetPeerAddress(dutLoopback.IPv6).SetAsNumber(asn).SetAsType(gosnappi.BgpV6PeerAsType.IBGP) + iDutBgp6Peer.Capability().SetIpv4UnicastAddPath(false).SetIpv6UnicastAddPath(true) + iDutBgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(false).SetUnicastIpv6Prefix(true) + + bgpNeti1Bgp4PeerRoutes := iDutBgp4Peer.V4Routes().Add().SetName(agg.ateAggName + ".BGP4.Route") + bgpNeti1Bgp4PeerRoutes.SetNextHopIpv4Address(agg.ateLoopbackV4). + SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). + SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) + bgpNeti1Bgp4PeerRoutes.Addresses().Add().SetAddress(advV4.ip).SetPrefix(advV4.prefix).SetCount(1) + bgpNeti1Bgp4PeerRoutes.AddPath().SetPathId(1) + + bgpNeti1Bgp6PeerRoutes := iDutBgp6Peer.V6Routes().Add().SetName(agg.ateAggName + ".BGP6.Route") + bgpNeti1Bgp6PeerRoutes.Addresses().Add().SetAddress(advV6.ip).SetPrefix(advV6.prefix).SetCount(1) + bgpNeti1Bgp6PeerRoutes.AddPath().SetPathId(1) +} + +func configureOTGISIS(t *testing.T, dev gosnappi.Device, agg *aggPortData) { + t.Helper() + isis := dev.Isis().SetSystemId(agg.ateISISSysID).SetName(agg.ateAggName + ".ISIS") + isis.Basic().SetHostname(isis.Name()) + isis.Advanced().SetAreaAddresses([]string{ateAreaAddress}) + + isisInt := isis.Interfaces().Add(). + SetEthName(dev.Ethernets().Items()[0].Name()).SetName(agg.ateAggName + ".ISISInt"). + SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). + SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2).SetMetric(10) + isisInt.Advanced().SetAutoAdjustMtu(true).SetAutoAdjustArea(true).SetAutoAdjustSupportedProtocols(true) +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) []string { + t.Helper() + fptest.ConfigureDefaultNetworkInstance(t, dut) + + configureDUTLoopback(t, dut) + + var aggIDs []string + for aggIdx, a := range []*aggPortData{agg1, agg2, agg3, agg4} { + b := &gnmi.SetBatch{} + d := &oc.Root{} + + aggID := netutil.NextAggregateInterface(t, dut) + aggIDs = append(aggIDs, aggID) + + agg := d.GetOrCreateInterface(aggID) + agg.GetOrCreateAggregation().LagType = oc.IfAggregate_AggregationType_STATIC + agg.Type = oc.IETFInterfaces_InterfaceType_ieee8023adLag + agg.Description = ygot.String(a.ateAggName) + if deviations.InterfaceEnabled(dut) { + agg.Enabled = ygot.Bool(true) + } + s := agg.GetOrCreateSubinterface(0) + s4 := s.GetOrCreateIpv4() + if deviations.InterfaceEnabled(dut) { + s4.Enabled = ygot.Bool(true) + } + a4 := s4.GetOrCreateAddress(a.dutIPv4) + a4.PrefixLength = ygot.Uint8(ipv4PLen) + + s6 := s.GetOrCreateIpv6() + if deviations.InterfaceEnabled(dut) { + s6.Enabled = ygot.Bool(true) + } + a6 := s6.GetOrCreateAddress(a.dutIPv6) + a6.PrefixLength = ygot.Uint8(ipv6PLen) + + gnmi.BatchDelete(b, gnmi.OC().Interface(aggID).Aggregation().MinLinks().Config()) + gnmi.BatchReplace(b, gnmi.OC().Interface(aggID).Config(), agg) + + p1 := dut.Port(t, fmt.Sprintf("port%d", (aggIdx*2)+1)) + p2 := dut.Port(t, fmt.Sprintf("port%d", (aggIdx*2)+2)) + for _, port := range []*ondatra.Port{p1, p2} { + gnmi.BatchDelete(b, gnmi.OC().Interface(port.Name()).Ethernet().AggregateId().Config()) + + i := d.GetOrCreateInterface(port.Name()) + i.Description = ygot.String(fmt.Sprintf("LAG - Member -%s", port.Name())) + e := i.GetOrCreateEthernet() + e.AggregateId = ygot.String(aggID) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + + if deviations.InterfaceEnabled(dut) { + i.Enabled = ygot.Bool(true) + } + if port.PMD() == ondatra.PMD100GBASEFR { + e.AutoNegotiate = ygot.Bool(false) + e.DuplexMode = oc.Ethernet_DuplexMode_FULL + e.PortSpeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB + } + + gnmi.BatchReplace(b, gnmi.OC().Interface(port.Name()).Config(), i) + } + b.Set(t, dut) + } + // Wait for LAG interfaces to be UP + for _, aggID := range aggIDs { + gnmi.Await(t, dut, gnmi.OC().Interface(aggID).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_UP) + } + configureStaticRouteToATELoopbacks(t, dut) + configureRoutingPolicy(t, dut) + configureDUTISIS(t, dut, aggIDs) + configureDUTBGP(t, dut) + return aggIDs +} + +func configureRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + + d := &oc.Root{} + rp := d.GetOrCreateRoutingPolicy() + pdef := rp.GetOrCreatePolicyDefinition(acceptRoutePolicy) + stmt, _ := pdef.AppendNewStatement("20") + stmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().PolicyDefinition(acceptRoutePolicy).Config(), pdef) +} + +func configureDUTLoopback(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + lb := netutil.LoopbackInterface(t, dut, 0) + lo0 := gnmi.OC().Interface(lb).Subinterface(0) + ipv4Addrs := gnmi.LookupAll(t, dut, lo0.Ipv4().AddressAny().State()) + ipv6Addrs := gnmi.LookupAll(t, dut, lo0.Ipv6().AddressAny().State()) + foundV4 := false + for _, ip := range ipv4Addrs { + if v, ok := ip.Val(); ok { + foundV4 = true + dutLoopback.IPv4 = v.GetIp() + break + } + } + foundV6 := false + for _, ip := range ipv6Addrs { + if v, ok := ip.Val(); ok { + foundV6 = true + dutLoopback.IPv6 = v.GetIp() + break + } + } + if !foundV4 || !foundV6 { + lo1 := dutLoopback.NewOCInterface(lb, dut) + lo1.Type = oc.IETFInterfaces_InterfaceType_softwareLoopback + gnmi.Update(t, dut, gnmi.OC().Interface(lb).Config(), lo1) + } +} + +func configureStaticRouteToATELoopbacks(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + + sr4ATE1 := &cfgplugins.StaticRouteCfg{ + NetworkInstance: deviations.DefaultNetworkInstance(dut), + Prefix: agg1.ateLoopbackV4 + "/32", + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(agg1.ateIPv4), + }, + } + sr6ATE1 := &cfgplugins.StaticRouteCfg{ + NetworkInstance: deviations.DefaultNetworkInstance(dut), + Prefix: agg1.ateLoopbackV6 + "/128", + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(agg1.ateIPv6), + }, + } + sr4ATE2 := &cfgplugins.StaticRouteCfg{ + NetworkInstance: deviations.DefaultNetworkInstance(dut), + Prefix: agg2.ateLoopbackV4 + "/32", + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(agg2.ateIPv4), + "1": oc.UnionString(agg3.ateIPv4), + "2": oc.UnionString(agg4.ateIPv4), + }, + } + sr6ATE2 := &cfgplugins.StaticRouteCfg{ + NetworkInstance: deviations.DefaultNetworkInstance(dut), + Prefix: agg2.ateLoopbackV6 + "/128", + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(agg2.ateIPv6), + "1": oc.UnionString(agg3.ateIPv6), + "2": oc.UnionString(agg4.ateIPv6), + }, + } + b := &gnmi.SetBatch{} + for _, cfg := range []*cfgplugins.StaticRouteCfg{sr4ATE1, sr6ATE1, sr4ATE2, sr6ATE2} { + if _, err := cfgplugins.NewStaticRouteCfg(b, cfg, dut); err != nil { + t.Fatalf("Failed to configure static route to ATE Loopback: %v", err) + } + } + b.Set(t, dut) +} + +func configureDUTISIS(t *testing.T, dut *ondatra.DUTDevice, aggIDs []string) { + t.Helper() + d := &oc.Root{} + netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + prot := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance) + prot.Enabled = ygot.Bool(true) + isis := prot.GetOrCreateIsis() + + globalISIS := isis.GetOrCreateGlobal() + if deviations.ISISInstanceEnabledRequired(dut) { + globalISIS.Instance = ygot.String(isisInstance) + } + globalISIS.LevelCapability = oc.Isis_LevelType_LEVEL_2 + globalISIS.Net = []string{fmt.Sprintf("%v.%v.00", dutAreaAddress, dutSysID)} + globalISIS.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + globalISIS.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + + lspBit := globalISIS.GetOrCreateLspBit().GetOrCreateOverloadBit() + lspBit.SetBit = ygot.Bool(false) + + isisLevel2 := isis.GetOrCreateLevel(2) + isisLevel2.MetricStyle = oc.Isis_MetricStyle_WIDE_METRIC + + for _, aggID := range aggIDs { + isisIntf := isis.GetOrCreateInterface(aggID) + isisIntf.GetOrCreateInterfaceRef().Interface = ygot.String(aggID) + isisIntf.GetOrCreateInterfaceRef().Subinterface = ygot.Uint32(0) + if deviations.InterfaceRefConfigUnsupported(dut) { + isisIntf.InterfaceRef = nil + } + isisIntf.Enabled = ygot.Bool(true) + isisIntf.CircuitType = oc.Isis_CircuitType_POINT_TO_POINT + isisIntf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + isisIntf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + if deviations.ISISInterfaceAfiUnsupported(dut) { + isisIntf.Af = nil + } + + isisIntfLevel := isisIntf.GetOrCreateLevel(2) + isisIntfLevel.Enabled = ygot.Bool(true) + + isisIntfLevelAfiv4 := isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST) + isisIntfLevelAfiv4.Metric = ygot.Uint32(10) + isisIntfLevelAfiv4.Enabled = ygot.Bool(true) + isisIntfLevelAfiv6 := isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST) + isisIntfLevelAfiv6.Metric = ygot.Uint32(10) + isisIntfLevelAfiv6.Enabled = ygot.Bool(true) + if deviations.MissingIsisInterfaceAfiSafiEnable(dut) { + isisIntfLevelAfiv4.Enabled = nil + isisIntfLevelAfiv6.Enabled = nil + } + } + gnmi.Update(t, dut, gnmi.OC().Config(), d) +} + +func configureDUTBGP(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + + d := &oc.Root{} + ni := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + niProto := ni.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() + + global := bgp.GetOrCreateGlobal() + global.RouterId = ygot.String(dutLoopback.IPv4) + global.As = ygot.Uint32(asn) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + pgName := "BGP-PEER-GROUP1" + pg := bgp.GetOrCreatePeerGroup(pgName) + pg.PeerAs = ygot.Uint32(asn) + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + rpl := pg.GetOrCreateApplyPolicy() + rpl.SetExportPolicy([]string{acceptRoutePolicy}) + rpl.SetImportPolicy([]string{acceptRoutePolicy}) + } else { + af4 := pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(true) + rpl := af4.GetOrCreateApplyPolicy() + rpl.SetExportPolicy([]string{acceptRoutePolicy}) + rpl.SetImportPolicy([]string{acceptRoutePolicy}) + + af6 := pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(true) + rpl = af6.GetOrCreateApplyPolicy() + rpl.SetExportPolicy([]string{acceptRoutePolicy}) + rpl.SetImportPolicy([]string{acceptRoutePolicy}) + } + + for _, a := range []*aggPortData{agg1, agg2, agg3, agg4} { + bgpNbrV4 := bgp.GetOrCreateNeighbor(a.ateLoopbackV4) + bgpNbrV4.PeerGroup = ygot.String(pgName) + bgpNbrV4.PeerAs = ygot.Uint32(asn) + bgpNbrV4.Enabled = ygot.Bool(true) + bgpNbrV4T := bgpNbrV4.GetOrCreateTransport() + bgpNbrV4T.LocalAddress = ygot.String(dutLoopback.IPv4) + af4 := bgpNbrV4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(true) + af6 := bgpNbrV4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(false) + + bgpNbrV6 := bgp.GetOrCreateNeighbor(a.ateLoopbackV6) + bgpNbrV6.PeerGroup = ygot.String(pgName) + bgpNbrV6.PeerAs = ygot.Uint32(asn) + bgpNbrV6.Enabled = ygot.Bool(true) + bgpNbrV6T := bgpNbrV6.GetOrCreateTransport() + bgpNbrV6T.LocalAddress = ygot.String(dutLoopback.IPv6) + af4 = bgpNbrV6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(false) + af6 = bgpNbrV6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(true) + } + + gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config(), niProto) +} diff --git a/feature/isis/weighted_ECMP/README.md b/feature/isis/weighted_ECMP/README.md deleted file mode 100644 index db975a0e1fd..00000000000 --- a/feature/isis/weighted_ECMP/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# RT-2.13: Weighted-ECMP for IS-IS - -## Summary -This is to ensure that, -* Implementations can be configured for weighted equal cost multipath (ECMP) routing for IS-IS neighbors that are one hop away. -* When WECMP is enabled, traffic destined to an IS-IS route represented by a multipath set of next-hop interfaces will be unequally distributed across the interfaces based on their bandwidth. - -## Testbed type -[TESTBED_DUT_ATE_8LINKS](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_8.testbed) - -## Topolgy -Each LAG bundle below is made up of 2x10G ports. -```mermaid -graph LR; -A[ATE1:LAG1] <-- IBGP+IS-IS --> B[LAG1:DUT]; -C[DUT:LAG2] <-- IBGP+IS-IS --> D[LAG1:ATE2]; -E[DUT:LAG3] <-- IBGP+IS-IS --> F[LAG2:ATE2]; -G[DUT:LAG4] <-- IBGP+IS-IS --> H[LAG3:ATE2]; -``` - -## Procedure -In the topology above, -* Configure 1xLAG interface between ATE1<->DUT and 3xLAG interfaces between DUT and ATE2. Each LAG interface is expected to be of 2x10Gbps -* Configure IPv4 and IPv6 L2 adjacencies between DUT and ATE LAG bundles. Therefore, DUT will have 1xIS-IS adjacency with ATE1 i.e. DUT:LAG1<->ATE1:LAG1, and 3xIS-IS adjacencies with ATE2 i.e. DUT:LAG2<->ATE2:LAG1, DUT:LAG3<->ATE2:LAG2 and DUT:LAG4<->ATE2:LAG3 - * /network-instances/network-instance/protocols/protocol/isis/global/afi-safi - * /network-instances/network-instance/protocols/protocol/isis/global/config/level-capability, set to LEVEL_2 - * /network-instances/network-instance/protocols/protocol/isis/levels/level/config/metric-style set to WIDE_METRIC -* Configure IPv4 and IPv6 IBGP peering between both ATEs and the DUT using their loopback addresses for both IPv4 and IPv6 address families. - * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/config -* Attach a network with an IPv4 and an IPv6 prefix to ATE2 and have it advertise these prefixes over its IBGP peering with the DUT. The DUT in turn should advertise these prefixes over its IBGP peering with ATE1 - * Please use `IPv4 prefix = 100.0.1.0/24` and `IPv6 prefix = 2001:db8:64:64::/64` -* Similarly, attach a different network to ATE1 with IPv4 and IPv6 prefixes and advertise the same over its IBGP peering with the DUT. - * Please use `IPv4 prefix = 100.0.2.0/24` and `IPv6 prefix = 2001:db8:64:65::/64` -* On the DUT, enable WECMP loadbalancing for multipath IS-IS routes and set the load-balancing-weight to use LAG bandwidth. - * /network-instances/network-instance/protocols/protocol/isis/global/config/weighted-ecmp set to Enabled - * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/config/load-balancing-weight set to Auto - -## RT-9.1: Equal distribution of traffic -* Start 1024 flows from IPv4 addresses in 100.0.2.0/24 to 100.0.1.0/24 -* Start 1024 flows from IPv6 addresses in 2001:db8:64:65::/64 to 2001:db8:64:64::/64 -* Ensure that the total traffic of all flows combined is ~20Gbps -### Verification -* Ensure that the DUT has learnt the routes for prefixes 100.0.1.0/24 and 2001:db8:64:64::/64 over IBGP. Following paths - * /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address -* Ensure that the DUT has learnt routes to the IPv4 and IPv6 loopback addresses of ATE2. It is expected that these prefixes are reachable via 3 different Next-Hop addresses corresponding to the LAG1, LAG2 and LAG3 interfaces on ATE2. -* It is expected that the IS-IS instance in DUT will equally distribute the traffic received on DUT:LAG1 over the LAG bundles corresponding to ATE2:LAG1, ATE2:LAG2 and ATE2:LAG3 when the 3 LAG bundles have the same bandwidth available. - * Traffic distribution between DUT:LAG2, DUT:LAG3 and DUT:LAG4 is expected to be ~33% each of the total traffic received on DUT:LAG1. - * Check for the following paths - * /network-instances/network-instance/protocols/protocol/isis/global/state/weighted-ecmp, should be true - * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/state/load-balancing-weight, should be auto - * /interfaces/interface/state/counters/out-pkts - * /interfaces/interface/state/counters/in-pkts - -## RT-9.2: Unequal distribution of traffic -* Stop traffic from RT-9.1 and introduce a failure by disabling one of the member interfaces in ATE2:LAG1. -* Restart 1024 flows from IPv4 addresses in 100.0.2.0/24 to 100.0.1.0/24 -* Restart 1024 flows from IPv6 addresses in 2001:db8:64:65::/64 to 2001:db8:64:64::/64 -* Ensure that the total traffic of all flows combined is ~20Gbps -### Verification -* It is expected that the IS-IS instance in DUT will unequally distribute the traffic received from ATE1:LAG1 over the LAG bundles corresponding to ATE2:LAG1, ATE2:LAG2 and ATE3:LAG3. - * Traffic on DUT:LAG2 is expected to be ~20% while traffic on DUT:LAG3 and DUT:LAG4 is expected to be ~40% each of the total traffic received on DUT:LAG1. If the traffic is not unequally shared between the DUT LAG bundles towards ATE2 then this test is a failure. - * Check for the following paths - * /interfaces/interface/state/counters/out-pkts - * /interfaces/interface/state/counters/in-pkts - -### Config paths -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/config - -* /network-instances/network-instance/protocols/protocol/isis/global/afi-safi -* /network-instances/network-instance/protocols/protocol/isis/global/config/level-capability -* /network-instances/network-instance/protocols/protocol/isis/levels/level/config/metric-style -* /network-instances/network-instance/protocols/protocol/isis/global/config/weighted-ecmp -* /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/config/load-balancing-weight - -* /routing-policy/defined-sets/prefix-sets/prefix-set/ -* /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/ip-prefix -* /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/masklength-range/exact - -* /routing-policy/policy-definitions/policy-definition/config/name -* /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options -* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result/ACCEPT_ROUTE - -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/peer-group/afi-safis/afi-safi/apply-policy/config/import-policy -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/peer-group/afi-safis/afi-safi/apply-policy/config/export-policy - -### Telemetry Parameter Coverage -* /network-instances/network-instance/protocols/protocol/isis/global/state/weighted-ecmp -* /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/state/load-balancing-weight -* /interfaces/interface/state/counters/out-pkts -* /interfaces/interface/state/counters/in-pkts From 1bd54e2b66181259398c4ce82ba31eb48be3a9b8 Mon Sep 17 00:00:00 2001 From: rezachit <39000986+rezachit@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:32:55 -0700 Subject: [PATCH 17/97] adding pm test (#2779) * adding pm test * adding pm test * fixing metadata file * rundata to fix metadata * rundata to fix metadata for default netwrok instance * deleting redundant running of fptest.ConfigureDefaultNetworkInstance(t, dut) * renaming minESNR/maxESNR to minAllowedESNR/maxAllowedESNR * deleting tests that are part of pm now and modifying testregistry * add pmd check. * minor fix in error text. * fixing readme issues, addresing @Darren's comments --- .../README.MD | 37 +-- .../tests/zr_db_q_value_test/README.md | 67 ----- .../transceiver/tests/zr_pm_test/README.md | 90 ++++++ .../tests/zr_pm_test/metadata.textproto | 15 + .../tests/zr_pm_test/zr_pm_test.go | 282 ++++++++++++++++++ .../tests/zr_pre_fec_ber_test/README.md | 48 --- testregistry.textproto | 14 +- 7 files changed, 403 insertions(+), 150 deletions(-) rename feature/platform/transceiver/tests/{zr_esnr_and_cd_test => zr_cd_test}/README.MD (63%) delete mode 100644 feature/platform/transceiver/tests/zr_db_q_value_test/README.md create mode 100644 feature/platform/transceiver/tests/zr_pm_test/README.md create mode 100644 feature/platform/transceiver/tests/zr_pm_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go delete mode 100644 feature/platform/transceiver/tests/zr_pre_fec_ber_test/README.md diff --git a/feature/platform/transceiver/tests/zr_esnr_and_cd_test/README.MD b/feature/platform/transceiver/tests/zr_cd_test/README.MD similarity index 63% rename from feature/platform/transceiver/tests/zr_esnr_and_cd_test/README.MD rename to feature/platform/transceiver/tests/zr_cd_test/README.MD index cbf4a6e25d7..46b563badf7 100644 --- a/feature/platform/transceiver/tests/zr_esnr_and_cd_test/README.MD +++ b/feature/platform/transceiver/tests/zr_cd_test/README.MD @@ -1,11 +1,8 @@ -# TRANSCEIVER-1: Telemetry: 400ZR Electrical Signal to Noise Ratio(eSNR) and Chromatic Dispersion(CD) telemetry values streaming +# TRANSCEIVER-1: Telemetry: 400ZR Chromatic Dispersion(CD) telemetry values streaming ## Summary -Validate 400ZR optics module reports accurate eSNR and CD telemetry values. - -eSNR is defined as the electrical Signal to Noise ratio at the decision -sampling point in dB +Validate 400ZR optics module reports accurate CD telemetry values. Chromatic Dispersion is frequency dependent change in signal phase velocity due to fiber measured in ps/nm @@ -25,10 +22,6 @@ to fiber measured in ps/nm * With the ZR link is established as explained above, verify that the following ZR transceiver telemetry paths exist and are streamed for both the ZR optics - * /terminal-device/logical-channels/channel/otn/state/esnr/instant - * /terminal-device/logical-channels/channel/otn/state/esnr/avg - * /terminal-device/logical-channels/channel/otn/state/esnr/min - * /terminal-device/logical-channels/channel/otn/state/esnr/max * /platform/components/component/optical-channel/state/chromatic-dispersion/instant * /platform/components/component/optical-channel/state/chromatic-dispersion/avg * /platform/components/component/optical-channel/state/chromatic-dispersion/min @@ -38,7 +31,7 @@ to fiber measured in ps/nm stream any invalid string values like "nil" or "-inf" until valid values are available for streaming. -* eSNR and CD streamed values must always be of type Decimal64. +* CD streamed values must always be of type Decimal64. When link interfaces are in down state 0 must be reported as a valid value. @@ -47,34 +40,30 @@ to fiber measured in ps/nm communicated. -* Verify that the optics eSNR and CD is updated after the interface flaps. +* Verify that the optics CD is updated after the interface flaps. * Enable a pair of ZR interfaces on the DUT as explained above. - * Verify the ZR optics eSNR and CD telemetry values are in the normal range. + * Verify the ZR optics CD telemetry values are in the normal range. * Disable or shut down the interface on the DUT. * Verify with interfaces in down state both optics are streaming Decimal64 0 - value for both eSNR and CD. + value for CD. * Re-enable the interfaces on the DUT. - * Verify the ZR optics eSNR and CD telemetry values are updated to the + * Verify the ZR optics CD telemetry values are updated to the value in the normal range again. - * Typical expected value range for eSNR is 13.5 to - 18 dB +/-0.1 dB. * Typical CD expected value range is 0 to 2400 ps/nm. -* Verify that the optics eSNR and CD is updated after a fiber cut. +* Verify that the optics CD is updated after a fiber cut. * Enable a pair of ZR interfaces on the DUT as explained above. - * Verify the ZR optics eSNR and CD telemetry values are in the normal + * Verify the ZR optics CD telemetry values are in the normal range. * Simulate a fiber cut using the optical switch that sits in-between the DUT ports. * Verify with link in down state due to fiber cut both optics are streaming - Decimal64 0 value for both eSNR and CD. + Decimal64 0 value for CD. * Re-enable the optical switch connection to clear the fiber cut fault. - * Verify the ZR optics eSNR and CD telemetry values are updated to the value in the normal + * Verify the ZR optics CD telemetry values are updated to the value in the normal range again. - * Typical expected value range for eSNR is 13.5 to - 18 dB +/-0.1 dB. * Typical CD expected value range is 0 to 2400 ps/nm. ## Config Parameter coverage @@ -83,10 +72,6 @@ to fiber measured in ps/nm ## Telemetry Parameter coverage -* /terminal-device/logical-channels/channel/otn/state/esnr/instant -* /terminal-device/logical-channels/channel/otn/state/esnr/avg -* /terminal-device/logical-channels/channel/otn/state/esnr/min -* /terminal-device/logical-channels/channel/otn/state/esnr/max * /platform/components/component/optical-channel/state/chromatic-dispersion/instant * /platform/components/component/optical-channel/state/chromatic-dispersion/avg * /platform/components/component/optical-channel/state/chromatic-dispersion/min diff --git a/feature/platform/transceiver/tests/zr_db_q_value_test/README.md b/feature/platform/transceiver/tests/zr_db_q_value_test/README.md deleted file mode 100644 index b62da10dba8..00000000000 --- a/feature/platform/transceiver/tests/zr_db_q_value_test/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# TRANSCEIVER-6: Telemetry: 400ZR Optics Q-value streaming. - -## Summary - -Validate 400ZR optics module reports Q-value performance data as defined in -module CMIS VDM(Versatile Diagnostics Monitor). -Q-value is the decibel (dB) value representing signal BER. - -## Procedure - -* Connect two ZR interfaces using a duplex LC fiber jumper such that TX - output power of one is the RX input power of the other module. - -* To establish a point to point ZR link ensure the following: - * Both transceivers state is enabled - * Both transceivers are set to a valid target TX output power - example -10 dBm. - * Both transceivers are tuned to a valid centre frequency - example 193.1 THz. - -* With the link ZR link established as explained above, verify that the - following ZR transceiver telemetry paths exist and are streamed for both - the ZR optics. - * /terminal-device/logical-channels/channel/otn/state/q-value/instant - * /terminal-device/logical-channels/channel/otn/state/q-value/avg - * /terminal-device/logical-channels/channel/otn/state/q-value/min - * /terminal-device/logical-channels/channel/otn/state/q-value/max - -* For reported data check for validity min <= avg/instant <= max - -* When the modules or the devices are still in a boot stage, they must not - stream any invalid string values like "nil" or "-inf" until valid values - are available for streaming. - -* Q-value must always be of type decimal64. When link interfaces are in down - state 0.0 must be reported as a valid default value. - - -**Note:** For min, max, and avg values, 10 second sampling is preferred. If - 10 seconds is not supported, the sampling interval used must be - specified by adding a deviation to the test. - - -* Verify that the optics Q-value is updated after the interface flaps. - - * Enable a pair of ZR interfaces on the DUT as explained above. - * Subscribe SAMPLE to the above q-value leafs with a sample rate of 10 - seconds. - * Verify the ZR optics Q-value PMs are in the normal range. - * Use /components/component/transceiver/config/enabled to disable the - transceiver, wait 20 seconds and then re-enable the transceiver. - * Verify that the q-value leafs report '0' during the reboot and no value - of nil or -inf is reported. - * Re-enable the interfaces on the DUT. - * Verify the ZR optics pre FEC PM is updated to the value in the normal - range again. Typical expected value should be greater than 7 dB. - -## Config Parameter coverage - -* /components/component/oc-transceiver:transceiver/oc-transceiver/config/enabled - -## Telemetry Parameter coverage - -* /terminal-device/logical-channels/channel/otn/state/q-value/instant -* /terminal-device/logical-channels/channel/otn/state/q-value/avg -* /terminal-device/logical-channels/channel/otn/state/q-value/min -* /terminal-device/logical-channels/channel/otn/state/q-value/max diff --git a/feature/platform/transceiver/tests/zr_pm_test/README.md b/feature/platform/transceiver/tests/zr_pm_test/README.md new file mode 100644 index 00000000000..fc3f96c7e05 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_pm_test/README.md @@ -0,0 +1,90 @@ +# TRANSCEIVER-6: Telemetry: 400ZR Optics performance metrics (pm) streaming. + +## Summary + +Validate 400ZR optics module reports performance metric (PM) data as defined in +module CMIS VDM(Versatile Diagnostics Monitor): +* eSNR is defined as the electrical Signal to Noise ratio at the decision sampling point in dB +* Q-value is the decibel (dB) value representing signal BER. +* pre-FEC BER bit error rate. + +## Procedure + +* Connect two ZR interfaces using a duplex LC fiber jumper such that TX + output power of one is the RX input power of the other module. + +* To establish a point to point ZR link ensure the following: + * Both transceivers state is enabled + * Both transceivers are set to a valid target TX output power + example -10 dBm. + * Both transceivers are tuned to a valid centre frequency + example 193.1 THz. + +* With the link ZR link established as explained above, verify that the + following ZR transceiver telemetry paths exist and are streamed for both + the ZR optics. + * /terminal-device/logical-channels/channel/otn/state/esnr/instant + * /terminal-device/logical-channels/channel/otn/state/esnr/avg + * /terminal-device/logical-channels/channel/otn/state/esnr/min + * /terminal-device/logical-channels/channel/otn/state/esnr/max + * /terminal-device/logical-channels/channel/otn/state/q-value/instant + * /terminal-device/logical-channels/channel/otn/state/q-value/avg + * /terminal-device/logical-channels/channel/otn/state/q-value/min + * /terminal-device/logical-channels/channel/otn/state/q-value/max + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/instant + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/avg + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/min + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/max + + +* For reported data check for validity min <= avg/instant <= max + +* When the modules or the devices are still in a boot stage, they must not + stream any invalid string values like "nil" or "-inf" until valid values + are available for streaming. + +* Q-value, eSNR and pre-Fec BER must always be of type decimal64. When link + interfaces are in down state 0.0 must be reported as a valid default value. + * Typical expected value range for eSNR is 13.5 to 18 dB +/-0.1 dB. + * Typical expected value for Pre-FEC BER should be less than 1.2E-2. + * Typical expected Q-value should be greater than 7 dB. + + +**Note:** For min, max, and avg values, 10 second sampling is preferred. If + 10 seconds is not supported, the sampling interval used must be + specified by adding a deviation to the test. + + +* Verify that the optics PM data is updated after the interface flaps. + + * Enable a pair of ZR interfaces on the DUT as explained above. + * Subscribe SAMPLE to the above PM leafs with a sample rate of 10 + seconds. + * Verify the ZR optics PMs are in the normal range. + * Use /components/component/transceiver/config/enabled to disable the + transceiver, wait 10 seconds and then re-enable the transceiver. + * Verify that the PM leafs report '0' during the reboot and no value + of nil or -inf is reported. + * Re-enable the interfaces on the DUT. + * Verify the ZR optics pre FEC PM is updated to the value in the normal + range again. + +## Config Parameter coverage + +* /components/component/transceiver/config/enabled + +## Telemetry Parameter coverage + + * /terminal-device/logical-channels/channel/otn/state/esnr/instant + * /terminal-device/logical-channels/channel/otn/state/esnr/avg + * /terminal-device/logical-channels/channel/otn/state/esnr/min + * /terminal-device/logical-channels/channel/otn/state/esnr/max + * /terminal-device/logical-channels/channel/otn/state/q-value/instant + * /terminal-device/logical-channels/channel/otn/state/q-value/avg + * /terminal-device/logical-channels/channel/otn/state/q-value/min + * /terminal-device/logical-channels/channel/otn/state/q-value/max + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/instant + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/avg + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/min + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/max +FFF - Fixed form factor \ No newline at end of file diff --git a/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto b/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto new file mode 100644 index 00000000000..91557f86ff6 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto @@ -0,0 +1,15 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "f5d5c225-8900-42fd-8771-8614895ae036" +plan_id: "TRANSCEIVER-6" +description: "Telemetry: 400ZR Optics performance metrics (pm) streaming." +testbed: TESTBED_DUT_400ZR +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + default_network_instance: "default" + } +} diff --git a/feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go b/feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go new file mode 100644 index 00000000000..e505e600139 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go @@ -0,0 +1,282 @@ +package zr_pm_test + +import ( + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +const ( + dp16QAM = uint16(16) + samplingInterval = 10 * time.Second + minAllowedQValue = 7.0 + maxAllowedQValue = 14.0 + minAllowedPreFECBER = 1e-9 + maxAllowedPreFECBER = 1e-2 + minAllowedESNR = 10.0 + maxAllowedESNR = 25.0 + inactiveQValue = 0.0 + inactivePreFECBER = 0.0 + inactiveESNR = 0.0 + timeout = 10 * time.Minute + flapInterval = 30 * time.Second + otnIndexBase = uint32(4000) + ethernetIndexBase = uint32(40000) +) + +var ( + frequencies = []uint64{191400000, 196100000} + targetOpticalPowers = []float64{-6, -10} + + dutPorts = []attrs.Attributes{ + { + Desc: "dutPort1", + IPv4: "192.0.2.1", + IPv4Len: 30, + }, + { + Desc: "dutPort2", + IPv4: "192.0.2.5", + IPv4Len: 30, + }, + } +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestPM(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + fptest.ConfigureDefaultNetworkInstance(t, dut) + + var ( + trs = make(map[string]string) + ochs = make(map[string]string) + otnIndexes = make(map[string]uint32) + ethIndexes = make(map[string]uint32) + ) + + for i, p := range dut.Ports() { + // Check the port PMD is 400ZR. + if p.PMD() != ondatra.PMD400GBASEZR { + t.Fatalf("%s PMD is %v, not 400ZR", p.Name(), p.PMD()) + } + + // Configure interfaces. + gnmi.Replace(t, dut, gnmi.OC().Interface(p.Name()).Config(), dutPorts[i].NewOCInterface(p.Name(), dut)) + + // Get transceiver and optical channel. + trs[p.Name()] = gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).Transceiver().State()) + ochs[p.Name()] = gnmi.Get(t, dut, gnmi.OC().Component(trs[p.Name()]).Transceiver().Channel(0).AssociatedOpticalChannel().State()) + + // Assign OTN and ethernet indexes. + otnIndexes[p.Name()] = otnIndexBase + uint32(i) + ethIndexes[p.Name()] = ethernetIndexBase + uint32(i) + } + + for _, frequency := range frequencies { + for _, targetOpticalPower := range targetOpticalPowers { + // Configure OCH component and OTN and ETH logical channels. + for _, p := range dut.Ports() { + configOpticalChannel(t, dut, ochs[p.Name()], frequency, targetOpticalPower) + configOTNChannel(t, dut, ochs[p.Name()], otnIndexes[p.Name()]) + configETHChannel(t, dut, otnIndexes[p.Name()], ethIndexes[p.Name()]) + } + + // Create OTN channel sample steam for each port. + otnStreams := make(map[string]*samplestream.SampleStream[*oc.TerminalDevice_Channel]) + for portName, otnIndex := range otnIndexes { + otnStreams[portName] = samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(otnIndex).State(), samplingInterval) + defer otnStreams[portName].Close() + } + + // Enable transceivers. + for _, tr := range trs { + gnmi.Replace(t, dut, gnmi.OC().Component(tr).Transceiver().Enabled().Config(), true) + } + + // Wait for streaming telemetry to report the channels as up. + for _, otnIndex := range otnIndexes { + gnmi.Await(t, dut, gnmi.OC().TerminalDevice().Channel(otnIndex).LinkState().State(), timeout, oc.Channel_LinkState_UP) + } + time.Sleep(samplingInterval) // Wait an extra sample interval to ensure the device has time to process the change. + + // Disable transceivers. + for _, tr := range trs { + gnmi.Replace(t, dut, gnmi.OC().Component(tr).Transceiver().Enabled().Config(), false) + } + + // Wait for streaming telemetry to report the channels as down. + for _, otnIndex := range otnIndexes { + gnmi.Await(t, dut, gnmi.OC().TerminalDevice().Channel(otnIndex).LinkState().State(), timeout, oc.Channel_LinkState_DOWN) + } + time.Sleep(samplingInterval) // Wait an extra sample interval to ensure the device has time to process the change. + + // Re-enable transceivers. + for _, tr := range trs { + gnmi.Replace(t, dut, gnmi.OC().Component(tr).Transceiver().Enabled().Config(), true) + } + + // Wait for streaming telemetry to report the channels as up. + for _, otnIndex := range otnIndexes { + gnmi.Await(t, dut, gnmi.OC().TerminalDevice().Channel(otnIndex).LinkState().State(), timeout, oc.Channel_LinkState_UP) + } + time.Sleep(samplingInterval) // Wait an extra sample interval to ensure the device has time to process the change. + + // Now validate OTN streams didn't return any invalid values. + for portName, stream := range otnStreams { + var linkStates []oc.E_Channel_LinkState + for _, val := range stream.All(t) { + linkStates = append(linkStates, validateStream(t, val, portName)) + } + validateLinkStateTransitions(t, linkStates, portName) + } + } + } +} + +// validateStream validates the stream data. +func validateStream(t *testing.T, data *ygnmi.Value[*oc.TerminalDevice_Channel], portName string) oc.E_Channel_LinkState { + if data == nil { + t.Errorf("Data not received for port %v.", portName) + return oc.Channel_LinkState_UNSET + } + v, ok := data.Val() + if !ok { + t.Errorf("Channel data is empty for port %v.", portName) + return oc.Channel_LinkState_UNSET + } + linkState := v.GetLinkState() + if linkState == oc.Channel_LinkState_UNSET { + t.Errorf("Link state data is empty for port %v", portName) + return oc.Channel_LinkState_UNSET + } + otn := v.GetOtn() + if otn == nil { + t.Errorf("OTN data is empty for port %v", portName) + return linkState + } + if b := otn.GetPreFecBer(); b == nil { + t.Errorf("PreFECBER data is empty for port %v", portName) + } else { + validatePMValue(t, portName, "PreFECBER", b.GetMin(), b.GetMax(), b.GetAvg(), b.GetInstant(), minAllowedPreFECBER, maxAllowedPreFECBER, inactivePreFECBER, linkState) + } + if e := otn.GetEsnr(); e == nil { + t.Errorf("ESNR data is empty for port %v", portName) + } else { + validatePMValue(t, portName, "esnr", e.GetMin(), e.GetMax(), e.GetAvg(), e.GetInstant(), minAllowedESNR, maxAllowedESNR, inactiveESNR, linkState) + } + if q := otn.GetQValue(); q == nil { + t.Errorf("QValue data is empty for port %v", portName) + } else { + validatePMValue(t, portName, "QValue", q.GetMin(), q.GetMax(), q.GetAvg(), q.GetInstant(), minAllowedQValue, maxAllowedQValue, inactiveQValue, linkState) + } + return linkState +} + +// validatePMValue validates the pm value. +func validatePMValue(t *testing.T, portName, pm string, instant, min, max, avg, minAllowed, maxAllowed, inactiveValue float64, linkState oc.E_Channel_LinkState) { + switch linkState { + case oc.Channel_LinkState_UP: + if instant < min || instant > max || avg < min || avg > max || min < minAllowed || max > maxAllowed { + t.Errorf("Invalid %v sample when %v is UP --> min : %v, max : %v, avg : %v, instant : %v", pm, portName, min, max, avg, instant) + return + } + case oc.Channel_LinkState_DOWN: + if instant != inactiveValue || avg != inactiveValue || min != inactiveValue || max != inactiveValue { + t.Errorf("Invalid %v sample when %v is DOWN --> min : %v, max : %v, avg : %v, instant : %v", pm, portName, min, max, avg, instant) + return + } + } + t.Logf("Valid %v sample when %v is %v --> min : %v, max : %v, avg : %v, instant : %v", pm, portName, linkState, min, max, avg, instant) +} + +// validateLinkStateTransitions validates the link state transitions. +func validateLinkStateTransitions(t *testing.T, linkStates []oc.E_Channel_LinkState, portName string) { + if len(linkStates) < 3 { + t.Errorf("Invalid %v link state transitions: want at least 3 samples, got %v", portName, len(linkStates)) + return + } + if linkStates[0] != oc.Channel_LinkState_DOWN { + t.Errorf("Invalid %v link state transitions: want DOWN for initial link state, got %v ", portName, linkStates[0]) + return + } + var transitionIndexes []int + for i := range linkStates { + if i == 0 { + continue + } + if linkStates[i-1] != linkStates[i] { + transitionIndexes = append(transitionIndexes, i) + } + } + if len(transitionIndexes) != 2 { + t.Errorf("Invalid %v link state transitions: want 2 transitions, got %v ", portName, len(transitionIndexes)) + return + } + if linkStates[transitionIndexes[0]] != oc.Channel_LinkState_UP { + t.Errorf("Invalid %v link state transitions: want DOWN-->UP, got %v-->%v", portName, linkStates[transitionIndexes[0]-1], linkStates[transitionIndexes[0]]) + return + } + if linkStates[transitionIndexes[1]] != oc.Channel_LinkState_DOWN { + t.Errorf("Invalid %v link state transitions: want UP-->DOWN, got %v-->%v", portName, linkStates[transitionIndexes[1]-1], linkStates[transitionIndexes[1]]) + } +} + +// configOpticalChannel configures the optical channel. +func configOpticalChannel(t *testing.T, dut *ondatra.DUTDevice, och string, frequency uint64, targetOpticalPower float64) { + gnmi.Replace(t, dut, gnmi.OC().Component(och).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + Frequency: ygot.Uint64(frequency), + TargetOutputPower: ygot.Float64(targetOpticalPower), + }) +} + +// configOTNChannel configures the OTN channel. +func configOTNChannel(t *testing.T, dut *ondatra.DUTDevice, och string, otnIndex uint32) { + gnmi.Replace(t, dut, gnmi.OC().TerminalDevice().Channel(otnIndex).Config(), &oc.TerminalDevice_Channel{ + LogicalChannelType: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_OTN, + AdminState: oc.TerminalDevice_AdminStateType_ENABLED, + Description: ygot.String("OTN Logical Channel"), + Index: ygot.Uint32(otnIndex), + Assignment: map[uint32]*oc.TerminalDevice_Channel_Assignment{ + 1: { + Index: ygot.Uint32(1), + OpticalChannel: ygot.String(och), + Description: ygot.String("OTN to Optical"), + Allocation: ygot.Float64(400), + AssignmentType: oc.Assignment_AssignmentType_OPTICAL_CHANNEL, + }, + }, + }) +} + +// configETHChannel configures the ETH channel. +func configETHChannel(t *testing.T, dut *ondatra.DUTDevice, otnIndex, ethIndex uint32) { + gnmi.Replace(t, dut, gnmi.OC().TerminalDevice().Channel(ethIndex).Config(), &oc.TerminalDevice_Channel{ + LogicalChannelType: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_ETHERNET, + AdminState: oc.TerminalDevice_AdminStateType_ENABLED, + Description: ygot.String("ETH Logical Channel"), + Index: ygot.Uint32(ethIndex), + RateClass: oc.TransportTypes_TRIBUTARY_RATE_CLASS_TYPE_TRIB_RATE_400G, + TribProtocol: oc.TransportTypes_TRIBUTARY_PROTOCOL_TYPE_PROT_400GE, + Assignment: map[uint32]*oc.TerminalDevice_Channel_Assignment{ + 1: { + Index: ygot.Uint32(1), + LogicalChannel: ygot.Uint32(otnIndex), + Description: ygot.String("ETH to OTN"), + Allocation: ygot.Float64(400), + AssignmentType: oc.Assignment_AssignmentType_LOGICAL_CHANNEL, + }, + }, + }) +} diff --git a/feature/platform/transceiver/tests/zr_pre_fec_ber_test/README.md b/feature/platform/transceiver/tests/zr_pre_fec_ber_test/README.md deleted file mode 100644 index 968b57ae70f..00000000000 --- a/feature/platform/transceiver/tests/zr_pre_fec_ber_test/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# TRANSCEIVER-2: Telemetry: 400ZR Optics Pre-FEC(Forward Error Correction) BER(Bit Error Rate) - -## Summary - -Validate 400ZR optics module reports pre-FEC bit error rate performance data. - -## Procedure - -* Connect two ZR interfaces using a duplex LC fiber jumper such that TX - output power of one is the RX input power of the other module. -* To establish a point to point ZR link ensure the following: - * Both transceivers state is enabled - * Both transceivers are set to a valid target TX output power - example -10 dBm - * Both transceivers are tuned to a valid centre frequency - example 193.1 THz -* With the link ZR link established as explained above, verify that the - following ZR transceiver telemetry paths exist and are streamed for both - the ZR optics - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/instant - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/avg - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/min - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/max - -**Note:** For min, max, and avg values, 10 second sampling is preferred. If - 10 seconds is not supported, the sampling interval used must be - communicated. - - -* Verify that the optics pre-FEC BER is updated after the interface flaps. - - * Enable a pair of ZR interfaces on the DUT as explained above. - * Verify the ZR optics pre FEC BER PMs are in the normal range. - * Disable or shut down the interface on the DUT. - * Re-enable the interfaces on the DUT. - * Verify the ZR optics pre FEC PM is updated to the value in the normal - range again. Typical expected value should be less than 1.2E-2 - -## Config Parameter coverage - -* /components/component/oc-transceiver:transceiver/oc-transceiver/config/enabled - -## Telemetry Parameter coverage - - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/instant - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/avg - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/min - * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/max diff --git a/testregistry.textproto b/testregistry.textproto index 95f0f5d539c..3234ce41fbc 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -1331,14 +1331,8 @@ test: { } test: { id: "TRANSCEIVER-1" - description: "400ZR Electrical Signal to Noise Ratio(eSNR) and Chromatic Dispersion(CD) telemetry values streaming" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/platform/transceiver/zr_esnr_and_cd_test/README.md" - exec: " " -} -test: { - id: "TRANSCEIVER-2" - description: "400ZR Optics Pre-FEC(Forward Error Correction) BER(Bit Error Rate)" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/platform/transceiver/ZR_pre-fec_ber_test/README.md" + description: "400ZR Chromatic Dispersion(CD) telemetry values streaming" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/platform/transceiver/zr_cd_test/README.md" exec: " " } test: { @@ -1361,7 +1355,9 @@ test: { } test: { id: "TRANSCEIVER-6" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/platform/transceiver/zr_db_q_value_test/README.md" + description: "400ZR Optics performance metrics (pm) streaming." + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/platform/transceiver/zr_pm_test/README.md" + exec: " " } test: { id: "TRANSCEIVER-8" From d4f87c8aad7f162484f91f578516ffbe7e0fc1e9 Mon Sep 17 00:00:00 2001 From: Arul Kumar Sekar <128646204+arulkumarsekar@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:28:03 -0700 Subject: [PATCH 18/97] Adding a new test - BGP Nested_Policies_Test (#2730) * adding a new test * Update nested_policies_test.go * adding a new metadata file * message for your commit * messages for your commit * messagess for your commit * adding a new test * Update nested_policies_test.go * adding a new metadata file * message for your commit * messages for your commit * messagess for your commit * Update nested_policies_test.go updated to Prefix * Update nested_policies_test.go * Update nested_policies_test.go * Update nested_policies_test.go * messsagesss for your commit * Update nested_policies_test.go --- .../nested_policies/metadata.textproto | 20 + .../nested_policies/nested_policies_test.go | 774 ++++++++++++++++++ 2 files changed, 794 insertions(+) create mode 100644 feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto create mode 100644 feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go diff --git a/feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto b/feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto new file mode 100644 index 00000000000..aa30373eed8 --- /dev/null +++ b/feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto @@ -0,0 +1,20 @@ +# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata +uuid: "aa9b83cb-fd87-4098-ab3d-db05c66fc3c0" +plan_id: "RT-1.30" +description: "BGP nested import/export policy attachment" +testbed: TESTBED_DUT_ATE_2LINKS +tags: TAGS_DATACENTER_EDGE +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + interface_enabled: true + default_network_instance: "default" + missing_value_for_defaults: true + skip_set_rp_match_set_options: true + } +} + diff --git a/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go b/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go new file mode 100644 index 00000000000..abbe6c49ab7 --- /dev/null +++ b/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go @@ -0,0 +1,774 @@ +// 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 nested_policies_test + +import ( + "fmt" + "net" + "testing" + "time" + + "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" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +const ( + ipv4PrefixLen = 30 + ipv6PrefixLen = 126 + v41Route = "203.0.113.0" + v41TrafficStart = "203.0.113.1" + v42Route = "198.51.100.0" + v42TrafficStart = "198.51.100.1" + v4RoutePrefix = uint32(24) + v61Route = "2001:db8:128:128::0" + v61TrafficStart = "2001:db8:128:128::1" + v62Route = "2001:db8:128:129::0" + v62TrafficStart = "2001:db8:128:129::1" + v6RoutePrefix = uint32(64) + dutAS = uint32(65656) + ateAS = uint32(65657) + bgpName = "BGP" + maskLenExact = "exact" + localPref = 200 + med = 1000 + v4Flow = "flow-v4" + v4PrefixPolicy = "prefix-policy-v4" + v4PrefixStatement = "prefix-statement-v4" + v4PrefixSet = "prefix-set-v4" + v4LPPolicy = "lp-policy-v4" + v4LPStatement = "lp-statement-v4" + v4ASPPolicy = "asp-policy-v4" + v4ASPStatement = "asp-statement-v4" + v4MedPolicy = "med-policy-v4" + v4MedStatement = "med-statement-v4" + v6Flow = "flow-v6" + v6PrefixPolicy = "prefix-policy-v6" + v6PrefixStatement = "prefix-statement-v6" + v6PrefixSet = "prefix-set-v6" + v6LPPolicy = "lp-policy-v6" + v6LPStatement = "lp-statement-v6" + v6ASPPolicy = "asp-policy-v6" + v6ASPStatement = "asp-statement-v6" + v6MedPolicy = "med-policy-v6" + v6MedStatement = "med-statement-v6" +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "dutPort1", + IPv4: "192.0.2.1", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:1", + IPv6Len: ipv6PrefixLen, + } + + atePort1 = attrs.Attributes{ + Name: "atePort1", + MAC: "02:00:01:01:01:01", + IPv4: "192.0.2.2", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:2", + IPv6Len: ipv6PrefixLen, + } + + dutPort2 = attrs.Attributes{ + Desc: "dutPort2", + IPv4: "192.0.2.5", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:5", + IPv6Len: ipv6PrefixLen, + } + + atePort2 = attrs.Attributes{ + Name: "atePort2", + MAC: "02:00:01:01:01:02", + IPv4: "192.0.2.6", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:6", + IPv6Len: ipv6PrefixLen, + } + + advertisedIPv41 = Prefix{address: v41Route, prefix: v4RoutePrefix} + advertisedIPv42 = Prefix{address: v42Route, prefix: v4RoutePrefix} + advertisedIPv61 = Prefix{address: v61Route, prefix: v6RoutePrefix} + advertisedIPv62 = Prefix{address: v62Route, prefix: v6RoutePrefix} +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +type Prefix struct { + address string + prefix uint32 +} + +func (ip *Prefix) cidr(t *testing.T) string { + _, net, err := net.ParseCIDR(fmt.Sprintf("%s/%d", ip.address, ip.prefix)) + if err != nil { + t.Fatal(err) + } + return net.String() +} + +type testData struct { + dut *ondatra.DUTDevice + ate *ondatra.ATEDevice + top gosnappi.Config + otgP1 gosnappi.Device + otgP2 gosnappi.Device +} + +type testCase struct { + name string + desc string + applyPolicy func(t *testing.T, dut *ondatra.DUTDevice) + validate func(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) + ipv4 bool + flowConfig flowConfig +} + +type flowConfig struct { + src attrs.Attributes + dstNw string + dstIP string +} + +func TestBGPNestedPolicies(t *testing.T) { + dut := ondatra.DUT(t, "dut") + configureDUT(t, dut) + + ate := ondatra.ATE(t, "ate") + top := gosnappi.NewConfig() + devs := configureOTG(t, ate, top) + td := testData{ + dut: dut, + ate: ate, + top: top, + otgP1: devs[0], + otgP2: devs[1], + } + td.advertiseRoutesWithEBGP(t) + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + defer ate.OTG().StopProtocols(t) + otgutils.WaitForARP(t, ate.OTG(), top, "IPv4") + otgutils.WaitForARP(t, ate.OTG(), top, "IPv6") + td.verifyDUTBGPEstablished(t) + td.verifyOTGBGPEstablished(t) + td.verifyNestedImportPolicyAttachedv4(t) + td.verifyNestedImportPolicyAttachedv6(t) + td.verifyNestedExportPolicyAttachedv4(t) + td.verifyNestedExportPolicyAttachedv6(t) + + testCases := []testCase{ + { + name: "IPv4BGPNestedmportPolicy", + desc: "IPv4 BGP Nested import policy test", + applyPolicy: configureImportRoutingPolicy, + validate: validateImportRoutingPolicy, + ipv4: true, + flowConfig: flowConfig{src: atePort2, dstNw: "v4-bgpNet-dev1", dstIP: v41TrafficStart}, + }, + { + name: "IPv4BGPNestedExportPolicy", + desc: "IPv4 BGP Nested export policy test", + applyPolicy: configureExportRoutingPolicy, + validate: validateExportRoutingPolicy, + ipv4: true, + flowConfig: flowConfig{src: atePort1, dstNw: "v4-bgpNet-dev2", dstIP: v42TrafficStart}, + }, + { + name: "IPv6BGPNestedImportPolicy", + desc: "IPv6 BGP Nested import policy test", + applyPolicy: configureImportRoutingPolicyV6, + validate: validateImportRoutingPolicyV6, + ipv4: false, + flowConfig: flowConfig{src: atePort2, dstNw: "v6-bgpNet-dev1", dstIP: v61TrafficStart}, + }, + { + name: "IPv6BGPNestedExportPolicy", + desc: "IPv6 BGP Nested export policy test", + applyPolicy: configureExportRoutingPolicyV6, + validate: validateExportRoutingPolicyV6, + ipv4: false, + flowConfig: flowConfig{src: atePort1, dstNw: "v6-bgpNet-dev2", dstIP: v62TrafficStart}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Logf("Description: %s", tc.desc) + tc.applyPolicy(t, dut) + tc.validate(t, dut, ate) + if tc.ipv4 { + createFlow(t, td, tc.flowConfig) + checkTraffic(t, td, v4Flow) + } else { + createFlowV6(t, td, tc.flowConfig) + checkTraffic(t, td, v6Flow) + } + }) + } +} + +// configureImportRoutingPolicy configures the dut for IPv4 BGP nested import policy test. +func configureImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + + // Configure a route-policy to set the local preference. + pdef1 := rp.GetOrCreatePolicyDefinition(v4LPPolicy) + stmt1, err := pdef1.AppendNewStatement(v4LPStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v4LPStatement, err) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + stmt1.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(localPref) + + // Configure a route-policy to match the prefix. + pdef2 := rp.GetOrCreatePolicyDefinition(v4PrefixPolicy) + stmt2, err := pdef2.AppendNewStatement(v4PrefixStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v4PrefixStatement, err) + } + stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + // Configure a prefix-set for route filtering/matching. + prefixSet := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(v4PrefixSet) + prefixSet.SetMode(oc.PrefixSet_Mode_IPV4) + prefixSet.GetOrCreatePrefix(advertisedIPv41.cidr(t), maskLenExact) + + if !deviations.SkipSetRpMatchSetOptions(dut) { + stmt2.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + stmt2.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet(v4PrefixSet) + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + // Configure the nested policy. + dni := deviations.DefaultNetworkInstance(dut) + rpPolicy := root.GetOrCreateRoutingPolicy() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v4LPPolicy).GetStatement(v4LPStatement).GetConditions() + statPath.SetCallPolicy(v4PrefixPolicy) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) + + // Configure the parent BGP import policy. + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() + policy.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + policy.SetImportPolicy([]string{v4LPPolicy}) + gnmi.Update(t, dut, path.Config(), policy) + +} + +func validateImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) + importPolicies := policy.GetImportPolicy() + if len(importPolicies) != 2 { + t.Errorf("ImportPolicy = %v, want %v", importPolicies, []string{v4PrefixPolicy, v4LPPolicy}) + } + + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv4Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast().LocRib().State()) + found := false + for k, lr := range locRib.Route { + if lr.GetPrefix() == advertisedIPv41.address { + found = true + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) + attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) + if attrSet == nil || attrSet.GetLocalPref() != localPref { + t.Errorf("No local pref found for prefix %s", advertisedIPv41.address) + } + break + } + } + + if !found { + t.Errorf("No Route found for prefix %s", advertisedIPv41.address) + } +} + +// configureExportRoutingPolicy configures the dut for IPv4 BGP nested export policy test. +func configureExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + pdef1 := rp.GetOrCreatePolicyDefinition(v4ASPPolicy) + stmt1, err := pdef1.AppendNewStatement(v4ASPStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v4ASPStatement, err) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend().SetAsn(dutAS) + + pdef2 := rp.GetOrCreatePolicyDefinition(v4MedPolicy) + stmt2, err := pdef2.AppendNewStatement(v4MedStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v4MedStatement, err) + } + stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + stmt2.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(oc.UnionUint32(med)) + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + // Configure the nested policy. + dni := deviations.DefaultNetworkInstance(dut) + rpPolicy := root.GetOrCreateRoutingPolicy() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v4ASPPolicy).GetStatement(v4ASPStatement).GetConditions() + statPath.SetCallPolicy(v4MedPolicy) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) + + // Configure the parent BGP import policy. + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() + policy.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + policy.SetExportPolicy([]string{v4ASPPolicy}) + gnmi.Update(t, dut, path.Config(), policy) +} + +func validateExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) + exportPolicies := policy.GetExportPolicy() + if len(exportPolicies) != 2 { + t.Errorf("ExportPolicy = %v, want %v", exportPolicies, []string{v4PrefixPolicy, v4LPPolicy}) + } + + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv4Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("v4-bgpNet-dev2").UnicastIpv4PrefixAny().State()) + found := false + for _, bgpPrefix := range bgpPrefixes { + if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == v42Route && + bgpPrefix.PrefixLength != nil && bgpPrefix.GetPrefixLength() == v4RoutePrefix { + found = true + t.Logf("Prefix recevied on OTG is correct, got prefix %v, want prefix %v", bgpPrefix, v42Route) + if bgpPrefix.GetMultiExitDiscriminator() != med { + t.Errorf("For Prefix %v, got MED %d want MED %d", bgpPrefix.GetAddress(), bgpPrefix.GetMultiExitDiscriminator(), med) + } + asPaths := bgpPrefix.AsPath + for _, ap := range asPaths { + count := 0 + for _, an := range ap.AsNumbers { + if an == dutAS { + count++ + } + } + if count == 2 { + t.Logf("ASP for prefix %v is correct, got ASP %v", bgpPrefix.GetAddress(), ap.AsNumbers) + } + } + break + } + } + + if !found { + t.Errorf("No Route found for prefix %s", v42Route) + } +} + +// configureImportRoutingPolicyV6 configures the dut for IPv6 BGP nested import policy test. +func configureImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + + pdef1 := rp.GetOrCreatePolicyDefinition(v6LPPolicy) + stmt1, err := pdef1.AppendNewStatement(v6LPStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v6LPStatement, err) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + stmt1.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(localPref) + + pdef2 := rp.GetOrCreatePolicyDefinition(v6PrefixPolicy) + stmt2, err := pdef2.AppendNewStatement(v6PrefixStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v6PrefixStatement, err) + } + stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + prefixSet := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(v6PrefixSet) + prefixSet.SetMode(oc.PrefixSet_Mode_IPV6) + prefixSet.GetOrCreatePrefix(advertisedIPv61.cidr(t), maskLenExact) + + if !deviations.SkipSetRpMatchSetOptions(dut) { + stmt2.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + stmt2.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet(v6PrefixSet) + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + // Configure the nested policy. + dni := deviations.DefaultNetworkInstance(dut) + rpPolicy := root.GetOrCreateRoutingPolicy() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v6LPPolicy).GetStatement(v6LPStatement).GetConditions() + statPath.SetCallPolicy(v6PrefixPolicy) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) + + // Configure the parent BGP import policy. + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policy.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + policy.SetImportPolicy([]string{v6LPPolicy}) + gnmi.Update(t, dut, path.Config(), policy) +} + +func validateImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) + importPolicies := policy.GetImportPolicy() + if len(importPolicies) != 2 { + t.Errorf("ImportPolicy = %v, want %v", importPolicies, []string{v6PrefixPolicy, v6LPPolicy}) + } + + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv6Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast().LocRib().State()) + found := false + for k, lr := range locRib.Route { + if lr.GetPrefix() == advertisedIPv61.address { + found = true + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) + attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) + if attrSet == nil || attrSet.GetLocalPref() != localPref { + t.Errorf("No local pref found for prefix %s", advertisedIPv61.address) + } + break + } + } + + if !found { + t.Errorf("No Route found for prefix %s", advertisedIPv61.address) + } +} + +// configureExportRoutingPolicyV6 configures the dut for IPv6 BGP nested export policy test. +func configureExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + pdef1 := rp.GetOrCreatePolicyDefinition(v6ASPPolicy) + stmt1, err := pdef1.AppendNewStatement(v6ASPStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v6ASPStatement, err) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend().SetAsn(dutAS) + + pdef2 := rp.GetOrCreatePolicyDefinition(v6MedPolicy) + stmt2, err := pdef2.AppendNewStatement(v6MedStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", v6MedStatement, err) + } + stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + stmt2.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(oc.UnionUint32(med)) + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + // Configure the nested policy. + dni := deviations.DefaultNetworkInstance(dut) + rpPolicy := root.GetOrCreateRoutingPolicy() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v6ASPPolicy).GetStatement(v6ASPStatement).GetConditions() + statPath.SetCallPolicy(v6MedPolicy) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) + + // Configure the parent BGP export policy. + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policy.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + policy.SetExportPolicy([]string{v6ASPPolicy}) + gnmi.Update(t, dut, path.Config(), policy) +} + +func validateExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) + exportPolicies := policy.GetExportPolicy() + if len(exportPolicies) != 2 { + t.Errorf("ExportPolicy = %v, want %v", exportPolicies, []string{v6PrefixPolicy, v6LPPolicy}) + } + + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv6Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("v6-bgpNet-dev2").UnicastIpv6PrefixAny().State()) + found := false + for _, bgpPrefix := range bgpPrefixes { + if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == v62Route && + bgpPrefix.PrefixLength != nil && bgpPrefix.GetPrefixLength() == v6RoutePrefix { + found = true + t.Logf("Prefix recevied on OTG is correct, got prefix %v, want prefix %v", bgpPrefix, v62Route) + if bgpPrefix.GetMultiExitDiscriminator() != med { + t.Errorf("For Prefix %v, got MED %d want MED %d", bgpPrefix.GetAddress(), bgpPrefix.GetMultiExitDiscriminator(), med) + } + asPaths := bgpPrefix.AsPath + for _, ap := range asPaths { + count := 0 + for _, an := range ap.AsNumbers { + if an == dutAS { + count++ + } + } + if count == 2 { + t.Logf("ASP for prefix %v is correct, got ASP %v", bgpPrefix.GetAddress(), ap.AsNumbers) + } + } + break + } + } + + if !found { + t.Errorf("No Route found for prefix %s", v62Route) + } +} + +func createFlow(t *testing.T, td testData, fc flowConfig) { + td.top.Flows().Clear() + + t.Log("Configuring v4 traffic flow") + v4Flow := td.top.Flows().Add().SetName(v4Flow) + v4Flow.Metrics().SetEnable(true) + v4Flow.TxRx().Device(). + SetTxNames([]string{fc.src.Name + ".IPv4"}). + SetRxNames([]string{fc.dstNw}) + v4Flow.Size().SetFixed(512) + v4Flow.Rate().SetPps(100) + v4Flow.Duration().Continuous() + e1 := v4Flow.Packet().Add().Ethernet() + e1.Src().SetValue(fc.src.MAC) + v4 := v4Flow.Packet().Add().Ipv4() + v4.Src().SetValue(fc.src.IPv4) + v4.Dst().Increment().SetStart(fc.dstIP).SetCount(1) + + td.ate.OTG().PushConfig(t, td.top) + td.ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, td.ate.OTG(), td.top, "IPv4") +} + +func createFlowV6(t *testing.T, td testData, fc flowConfig) { + td.top.Flows().Clear() + + t.Log("Configuring v6 traffic flow") + v6Flow := td.top.Flows().Add().SetName(v6Flow) + v6Flow.Metrics().SetEnable(true) + v6Flow.TxRx().Device(). + SetTxNames([]string{fc.src.Name + ".IPv6"}). + SetRxNames([]string{fc.dstNw}) + v6Flow.Size().SetFixed(512) + v6Flow.Rate().SetPps(100) + v6Flow.Duration().Continuous() + e1 := v6Flow.Packet().Add().Ethernet() + e1.Src().SetValue(fc.src.MAC) + v6 := v6Flow.Packet().Add().Ipv6() + v6.Src().SetValue(fc.src.IPv6) + v6.Dst().Increment().SetStart(fc.dstIP).SetCount(1) + + td.ate.OTG().PushConfig(t, td.top) + td.ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, td.ate.OTG(), td.top, "IPv6") +} + +func checkTraffic(t *testing.T, td testData, flowName string) { + td.ate.OTG().StartTraffic(t) + time.Sleep(time.Second * 30) + td.ate.OTG().StopTraffic(t) + + otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) + otgutils.LogPortMetrics(t, td.ate.OTG(), td.top) + + t.Log("Checking flow telemetry...") + recvMetric := gnmi.Get(t, td.ate.OTG(), gnmi.OTG().Flow(flowName).State()) + txPackets := recvMetric.GetCounters().GetOutPkts() + rxPackets := recvMetric.GetCounters().GetInPkts() + lostPackets := txPackets - rxPackets + lossPct := lostPackets * 100 / txPackets + + if lossPct > 1 { + t.Errorf("FAIL- got %v%% packet loss for %s ; want < 1%%", lossPct, flowName) + } +} + +func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { + t.Helper() + + root := &oc.Root{} + ni := root.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(td.dut)) + bgpP := ni.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName) + bgpP.SetEnabled(true) + bgp := bgpP.GetOrCreateBgp() + + g := bgp.GetOrCreateGlobal() + g.SetAs(dutAS) + g.SetRouterId(dutPort1.IPv4) + g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + + nV41 := bgp.GetOrCreateNeighbor(atePort1.IPv4) + nV41.SetPeerAs(ateAS) + nV41.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV42 := bgp.GetOrCreateNeighbor(atePort2.IPv4) + nV42.SetPeerAs(ateAS) + nV42.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + + nV61 := bgp.GetOrCreateNeighbor(atePort1.IPv6) + nV61.SetPeerAs(ateAS) + nV61.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nV62 := bgp.GetOrCreateNeighbor(atePort2.IPv6) + nV62.SetPeerAs(ateAS) + nV62.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + gnmi.Update(t, td.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Config(), ni) + + // Configure eBGP on OTG port1. + ipv41 := td.otgP1.Ethernets().Items()[0].Ipv4Addresses().Items()[0] + dev1BGP := td.otgP1.Bgp().SetRouterId(atePort1.IPv4) + bgp4Peer1 := dev1BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv41.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP4.peer") + bgp4Peer1.SetPeerAddress(dutPort1.IPv4).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + + ipv61 := td.otgP1.Ethernets().Items()[0].Ipv6Addresses().Items()[0] + bgp6Peer1 := dev1BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv61.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP6.peer") + bgp6Peer1.SetPeerAddress(dutPort1.IPv6).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + + // Configure emulated network on ATE port1. + netv41 := bgp4Peer1.V4Routes().Add().SetName("v4-bgpNet-dev1") + netv41.Addresses().Add().SetAddress(advertisedIPv41.address).SetPrefix(advertisedIPv41.prefix) + netv61 := bgp6Peer1.V6Routes().Add().SetName("v6-bgpNet-dev1") + netv61.Addresses().Add().SetAddress(advertisedIPv61.address).SetPrefix(advertisedIPv61.prefix) + + // Configure eBGP on OTG port2. + ipv42 := td.otgP2.Ethernets().Items()[0].Ipv4Addresses().Items()[0] + dev2BGP := td.otgP2.Bgp().SetRouterId(atePort2.IPv4) + bgp4Peer2 := dev2BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv42.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP4.peer") + bgp4Peer2.SetPeerAddress(dutPort2.IPv4).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + + ipv62 := td.otgP2.Ethernets().Items()[0].Ipv6Addresses().Items()[0] + bgp6Peer2 := dev2BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv62.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP6.peer") + bgp6Peer2.SetPeerAddress(dutPort2.IPv6).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + + // Configure emulated network on ATE port2. + netv42 := bgp4Peer2.V4Routes().Add().SetName("v4-bgpNet-dev2") + netv42.Addresses().Add().SetAddress(advertisedIPv42.address).SetPrefix(advertisedIPv42.prefix) + netv62 := bgp6Peer2.V6Routes().Add().SetName("v6-bgpNet-dev2") + netv62.Addresses().Add().SetAddress(advertisedIPv62.address).SetPrefix(advertisedIPv62.prefix) +} + +// verifyDUTBGPEstablished verifies on dut for BGP peer establishment. +func (td *testData) verifyDUTBGPEstablished(t *testing.T) { + sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().NeighborAny().SessionState().State() + watch := gnmi.WatchAll(t, td.dut, sp, 2*time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + if !ok || state != oc.Bgp_Neighbor_SessionState_ESTABLISHED { + return false + } + return true + }) + if val, ok := watch.Await(t); !ok { + t.Fatalf("BGP sessions not established: got %v", val) + } + t.Log("DUT BGP sessions established") +} + +// VerifyOTGBGPEstablished verifies on OTG for BGP peer establishment. +func (td *testData) verifyOTGBGPEstablished(t *testing.T) { + sp := gnmi.OTG().BgpPeerAny().SessionState().State() + watch := gnmi.WatchAll(t, td.ate.OTG(), sp, 2*time.Minute, func(val *ygnmi.Value[otgtelemetry.E_BgpPeer_SessionState]) bool { + state, ok := val.Val() + if !ok || state != otgtelemetry.BgpPeer_SessionState_ESTABLISHED { + return false + } + return true + }) + if val, ok := watch.Await(t); !ok { + t.Fatalf("BGP sessions not established: got %v", val) + } + t.Log("OTG BGP sessions established") +} + +// verifyNestedImportPolicyAttachedv4 verifies on dut for IPV4 BGP parent import policy v4LPPolicy has a child policy attached. +func (td *testData) verifyNestedImportPolicyAttachedv4(t *testing.T) { + rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v4LPPolicy).State() + subResponse := gnmi.Get(t, td.dut, rpDefPath) + callPolicy := subResponse.GetStatement(v4LPStatement).Conditions.GetCallPolicy() + if callPolicy != v4PrefixPolicy { + t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v4PrefixPolicy) + } + t.Log("Nested policy 'v4PrefixPolicy' verified successfully") +} + +// verifyNestedExportPolicyAttachedv4 verifies on dut for IPV4 BGP parent export policy v4ASPPolicy has a child policy attached. +func (td *testData) verifyNestedExportPolicyAttachedv4(t *testing.T) { + rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v4ASPPolicy).State() + subResponse := gnmi.Get(t, td.dut, rpDefPath) + callPolicy := subResponse.GetStatement(v4ASPStatement).Conditions.GetCallPolicy() + if callPolicy != v4MedPolicy { + t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v4MedPolicy) + } + t.Log("Nested policy 'v4MedPolicy' verified successfully") +} + +// verifyNestedImportPolicyAttachedv6 verifies on dut for IPV6 BGP parent import policy v6LPPolicy has a child policy attached. +func (td *testData) verifyNestedImportPolicyAttachedv6(t *testing.T) { + rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v6LPPolicy).State() + subResponse := gnmi.Get(t, td.dut, rpDefPath) + callPolicy := subResponse.GetStatement(v6LPStatement).Conditions.GetCallPolicy() + if callPolicy != v6PrefixPolicy { + t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v6PrefixPolicy) + } + t.Log("Nested policy 'v6PrefixPolicy' verified successfully") +} + +// verifyNestedExportPolicyAttachedv6 verifies on dut for IPV6 BGP parent export policy v6ASPPolicy has a child policy attached. +func (td *testData) verifyNestedExportPolicyAttachedv6(t *testing.T) { + rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v6ASPPolicy).State() + subResponse := gnmi.Get(t, td.dut, rpDefPath) + callPolicy := subResponse.GetStatement(v6ASPStatement).Conditions.GetCallPolicy() + if callPolicy != v6MedPolicy { + t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v6MedPolicy) + } + t.Log("Nested policy 'v6MedPolicy' verified successfully") +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + b := &gnmi.SetBatch{} + gnmi.BatchReplace(b, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) + gnmi.BatchReplace(b, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) + b.Set(t, dut) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, p1) + fptest.SetPortSpeed(t, p2) + } + + fptest.ConfigureDefaultNetworkInstance(t, dut) + + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) + } +} + +func configureOTG(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) []gosnappi.Device { + t.Helper() + p1 := ate.Port(t, "port1") + p2 := ate.Port(t, "port2") + + d1 := atePort1.AddToOTG(top, p1, &dutPort1) + d2 := atePort2.AddToOTG(top, p2, &dutPort2) + return []gosnappi.Device{d1, d2} +} From 7bc3e6132c2e98a1056a737aa2ad57dcf168f3aa Mon Sep 17 00:00:00 2001 From: divyarema <134387379+divyarema@users.noreply.github.com> Date: Thu, 14 Mar 2024 11:03:36 +0530 Subject: [PATCH 19/97] Adding deviation ISISLevelEnabled to RT2.12 isis_drain_test.go (#2575) * Adding deviation,ISISLevelEnabled * running gofmt --- .../isis/otg_tests/isis_drain_test/isis_drain_test.go | 4 +++- .../isis/otg_tests/isis_drain_test/metadata.textproto | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/feature/experimental/isis/otg_tests/isis_drain_test/isis_drain_test.go b/feature/experimental/isis/otg_tests/isis_drain_test/isis_drain_test.go index d2ec54af22e..13ba419a8da 100644 --- a/feature/experimental/isis/otg_tests/isis_drain_test/isis_drain_test.go +++ b/feature/experimental/isis/otg_tests/isis_drain_test/isis_drain_test.go @@ -252,7 +252,9 @@ func configureISISDUT(t *testing.T, dut *ondatra.DUTDevice, intfs []string) { isisLevel2 := isis.GetOrCreateLevel(2) isisLevel2.MetricStyle = oc.Isis_MetricStyle_WIDE_METRIC - + if deviations.ISISLevelEnabled(dut) { + isisLevel2.Enabled = ygot.Bool(true) + } for _, intfName := range intfs { isisIntf := isis.GetOrCreateInterface(intfName) isisIntf.GetOrCreateInterfaceRef().Interface = ygot.String(intfName) diff --git a/feature/experimental/isis/otg_tests/isis_drain_test/metadata.textproto b/feature/experimental/isis/otg_tests/isis_drain_test/metadata.textproto index 5f7e30cc941..e704ecde9cb 100644 --- a/feature/experimental/isis/otg_tests/isis_drain_test/metadata.textproto +++ b/feature/experimental/isis/otg_tests/isis_drain_test/metadata.textproto @@ -39,3 +39,11 @@ platform_exceptions: { isis_require_same_l1_metric_with_l2_metric: true } } +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + isis_level_enabled: true + } +} From 8856fd89b1b3f9ff0c1f7430741dabe6a3a9ad1b Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Thu, 14 Mar 2024 07:20:12 -0700 Subject: [PATCH 20/97] remove RT-7.9 (#2799) Co-authored-by: rszarecki <46606165+rszarecki@users.noreply.github.com> --- .../otg_tests/extcomm_action_test/README.md | 364 ------------------ .../extcomm_action_test/metadata.textproto | 7 - testregistry.textproto | 6 - 3 files changed, 377 deletions(-) delete mode 100644 feature/bgp/policybase/otg_tests/extcomm_action_test/README.md delete mode 100644 feature/bgp/policybase/otg_tests/extcomm_action_test/metadata.textproto diff --git a/feature/bgp/policybase/otg_tests/extcomm_action_test/README.md b/feature/bgp/policybase/otg_tests/extcomm_action_test/README.md deleted file mode 100644 index 92a022c2544..00000000000 --- a/feature/bgp/policybase/otg_tests/extcomm_action_test/README.md +++ /dev/null @@ -1,364 +0,0 @@ -# RT-7.9: BGP Policy - Import/Export Policy Action Using Extended Communities - -## Summary - -Configure bgp policy to import/export routes by matching on extended communities. - -Matches should be performed against a subset of extended community types - -* <2b AS>:<4b value> per RFC4360 section 3.1 -* <4b AS>:<2b value> per RFC5668 section 2. -* link-bandwidth:<2 byte asn>: - per draft-ietf-idr-link-bandwidth-07 -* TODO: Additional match types can be added here. Currently these match types - cover the use cases needed for RT-7.9 - -## Testbed type - -* https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed - -* Testbed configuration - Setup BGP sessions and prefixes - * Generate config for 2 DUT and ATE ports where - * DUT port 1 to ATE port 1. - * DUT port 2 to ATE port 2. - * Configure ATE port 1 with a BGP session to DUT port 1 - * Advertise ipv4 and ipv6 prefixes to DUT port 1 using the following communities: - * prefix-set-1 with 2 routes with communities `[100:95000, 200000:2, 300000:300000]` - * prefix-set-2 with 2 routes with communities `[100000:1, 101000:1, 200000:1]` - * prefix-set-3 with 2 routes with communities `[109000:1]` - * prefix-set-4 with 2 routes with communities `[400000:1]` - * prefix-set-5 with 2 routes with communities `[400000:1, link-bandwidth:100:1500000` - * prefix-set-6 with 2 routes with communities `[400000:1, link-bandwidth:100:1M` - -## Subtests - -* RT-7.9.1 - Validate bgp sessions and traffic - * For IPv4 and IPv6 prefixes: - * Observe received prefixes at ATE port-2. - * Generate traffic from ATE port-2 to ATE port-1. - * Validate that traffic can be received on ATE port-1 for all installed - routes. - -* RT-7.9.2 - Validate ext-community-sets and routing-policy using OC - release 2.x or earlier - * Configure the following community sets - (prefix: `routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set`) - on the DUT. - * Create a community-set named 'any_my_3_ext_comms' with members as follows: - * community-member = [ "100:95000", "200000:2", "300000:300000" ] - * match-set-options = ANY - * Create a community-set named 'all_3_ext_comms' with members as follows: - * community-member = [ "100:95000", "200000:2", "300000:300000" ] - * match-set-options = ALL - * Create a community-set named 'no_3_ext_comms' with members as follows: - * community-member = [ "100000:99", "200000:2", "300000:300000" ] - * match-set-options = INVERT - * Create a community-set named 'any_my_regex_ext_comms' with members as follows: - * community-member = [ "10[0-9]000:1" ] - * match-set-options = ANY - * Create a community-set named 'any_ext_comms' with members as follows: - * community-member = [ "^.*$" ] - * match-set-options = ANY - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'any_3_comms' with the following `statements` - * statement[name='any_3_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_my_3_ext_comms' - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'all_3_comms' with the following `statements` - * statement[name='all_3_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'all_3_ext_comms' - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'no_3_comms' with the following `statements` - * statement[name='no_3_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'no_3_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = INVERT - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'any_my_regex_comms' with the following `statements` - * statement[name='any_my_regex_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_my_regex_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = REJECT_ROUTE - - * For each policy-definition created - * Use gnmi Set REPLACE option for: - * `/routing-policy/policy-definitions` to configure the policy - * Use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/apply-policy/config/import-policy` - to configure the policy on the DUT to the ATE port 1 bgp neighbor - * Send traffic from ATE port-2 to all prefix-sets-1,2,3,4. - * Verify traffic is received on ATE port 1 for accepted prefixes. - * Verify traffic is not received on ATE port 1 for rejected prefixes. - * Stop traffic - - * Expected matches for each policy - | | any_my_3_comms | all_3_comms | no_3_comms | any_my_regex_comms | - | ------------ | -------------- | ----------- | ---------- | ------------------ | - | prefix-set-1 | accept | accept | reject | accept | - | prefix-set-2 | accept | reject | reject | accept | - | prefix-set-3 | reject | reject | accept | accept | - | prefix-set-4 | reject | reject | accept | reject | - -* RT-7.9.3 - Validate ext-community-sets and routing-policy using OC release 3.x - * Note, this is the same at RT-7.9.2, but with a change in the location of the - `match-set-options` leaf which moved to - `/routing-policy/policy-definitions/policy-definition/policy-definition/bgp-conditions/match-ext-community-set/config/match-set-options` - * Configure the following community sets - (prefix: `routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set`) - on the DUT. - * Create a community-set named 'any_my_3_ext_comms' with members as follows: - * community-member = [ "100:95000", "200000:2", "300000:300000" ] - * Create a community-set named 'all_3_ext_comms' with members as follows: - * community-member = [ "100:95000", "200000:2", "300000:300000" ] - * Create a community-set named 'no_3_ext_comms' with members as follows: - * community-member = [ "100000:99", "200000:2", "300000:300000" ] - * Create a community-set named 'any_my_regex_ext_comms' with members as follows: - * community-member = [ "10[0-9]000:1" ] - * Create a community-set named 'any_ext_comms' with members as follows: - * community-member = [ "^.*$" ] - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'any_3_comms' with the following `statements` - * statement[name='any_3_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_my_3_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'all_3_comms' with the following `statements` - * statement[name='all_3_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'all_3_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ALL - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'no_3_comms' with the following `statements` - * statement[name='no_3_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'no_3_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = INVERT - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'any_my_regex_comms' with the following `statements` - * statement[name='any_my_regex_comms']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_my_regex_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * conditions/bgp-conditions/match-ext-community-set/config/ext-community-set = 'any_ext_comms' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = REJECT_ROUTE - - * For each policy-definition - * Use gnmi Set REPLACE option for: - * `/routing-policy/policy-definitions` to configure the policy - * Use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/apply-policy/config/import-policy` - to configure the policy on the DUT to the ATE port 1 bgp neighbor - * Send traffic from ATE port-2 to all prefix-sets-1,2,3,4. - * Verify traffic is received on ATE port 1 for accepted prefixes. - * Verify traffic is not received on ATE port 1 for rejected prefixes. - * Stop traffic - - * Expected matches for each policy - | | any_my_3_comms | all_3_comms | no_3_comms | any_my_regex_comms | - | ------------ | -------------- | ----------- | ---------- | ------------------ | - | prefix-set-1 | accept | accept | reject | accept | - | prefix-set-2 | accept | reject | reject | accept | - | prefix-set-3 | reject | reject | accept | accept | - | prefix-set-4 | reject | reject | accept | reject | - -* RT-7.9.4 - Validate link-bandwidth ext-community-sets and matching policy - using OC model revision 2.x - * Add prefixes with link-bandwidth community to ATE port 1 to advertise ipv4 - and ipv6 prefixes to DUT port 1 using the following communities: - * prefix-set-5 with 2 routes with communities `[ link-bandwidth:500000:0, ]` - * prefix-set-6 with 2 routes with communities `[ link-bandwidth:600000:1M, ]` - - * Configure the following community sets - (prefix: `routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set`) - on the DUT. - * Create an ext-community-set named 'linkbw_ext_comms_0' with: - * ext-community-member = [ "^link-bandwidth:.*:0$" ] - * match-set-options = ANY - * Create an ext-community-set named 'linkbw_ext_comms_1M' with members as follows: - * ext-community-member = [ "^link-bandwidth:.*:1M$" ] - * config/match-set-options = ANY - * Create an ext-community-set named 'linkbw_ext_comms_2G' with members as follows: - * ext-community-member = [ "^link-bandwidth:.*:2G$" ] - * match-set-options = ANY - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'zero-bandwidth-reject' with the following `statements` - * statement[name='zero-bandwidth-reject']/ - * conditions/bgp-conditions/match-ext-community-set/config/community-set = 'linkbw_ext_comms_0' - * actions/config/policy-result = REJECT_ROUTE - * statement[name='accept_all']/ - * actions/config/policy-result = ACCEPT_ROUTE - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named '1-megabit-match' with the following `statements` - * statement[name='1-megabit-match']/ - * conditions/bgp-conditions/match-ext-community-set/config/community-set = 'linkbw_ext_comms_1M' - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'link-bandwidth-match' with the following `statements` - * statement[name='2-gigabit-match']/ - * conditions/bgp-conditions/match-ext-community-set/config/community-set = 'linkbw_ext_comms_2G' - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * actions/config/policy-result = REJECT_ROUTE - - * For each policy-definition - * Use gnmi Set REPLACE option for: - * `/routing-policy/policy-definitions` to configure the policy - * Use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/apply-policy/config/import-policy` - to configure the policy on the DUT to the ATE port 1 bgp neighbor - * Send traffic from ATE port-2 to all prefix-sets-5,6. - * Verify traffic is received on ATE port 1 for accepted prefixes. - * Verify traffic is not received on ATE port 1 for rejected prefixes. - * Stop traffic - - * Expected matches for each policy - | | zero-bandwidth-reject | 1-megabit | 2-gigabit-match | - | ------------ | --------------------- | --------- | --------------- | - | prefix-set-5 | reject | reject | reject | - | prefix-set-6 | accept | accept | reject | - -* RT-7.9.5 - Validate ext-community-sets and matching policy using OC - release 3.x - * Note, this is the same at RT-7.9.4, but with a change in the location of the - `match-set-options` leaf which moved to - `/routing-policy/policy-definitions/policy-definition/policy-definition/bgp-conditions/match-ext-community-set/config/match-set-options` - * Add prefixes with link-bandwidth community to ATE port 1 to advertise ipv4 - and ipv6 prefixes to DUT port 1 using the following communities: - * prefix-set-5 with 2 routes with communities `[ link-bandwidth:500000:0, ]` - * prefix-set-6 with 2 routes with communities `[ link-bandwidth:600000:1M, ]` - - * Configure the following community sets - (prefix: `routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set`) - on the DUT. - * Create a community-set named 'linkbw_ext_comms_0' with members as follows: - * `community-member = [ "^link-bandwidth:.*:0$" ]` - * Create a community-set named 'linkbw_ext_comms_1M' with members as follows: - * `community-member = [ "^link-bandwidth:.*:1M$" ]` - * Create a community-set named 'linkbw_ext_comms_2G' with members as follows: - * `community-member = [ "^link-bandwidth:.*:2G$" ]` - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'zero-bandwidth-reject' with the following `statements` - * statement[name='zero-bandwidth-reject']/ - * conditions/bgp-conditions/match-ext-community-set/config/community-set = 'linkbw_ext_comms_0' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = REJECT_ROUTE - * statement[name='accept_all']/ - * actions/config/policy-result = ACCEPT_ROUTE - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named '1-megabit-match' with the following `statements` - * statement[name='1-megabit-match']/ - * conditions/bgp-conditions/match-ext-community-set/config/community-set = 'linkbw_ext_comms_1M' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * actions/config/policy-result = REJECT_ROUTE - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'link-bandwidth-match' with the following `statements` - * statement[name='2-gigabit-match']/ - * conditions/bgp-conditions/match-ext-community-set/config/community-set = 'linkbw_ext_comms_2G' - * conditions/bgp-conditions/match-ext-community-set/config/match-set-options = ANY - * actions/config/policy-result = ACCEPT_ROUTE - * statement[name='reject_all']/ - * actions/config/policy-result = REJECT_ROUTE - - * For each policy-definition - * Use gnmi Set REPLACE option for: - * `/routing-policy/policy-definitions` to configure the policy - * Use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/apply-policy/config/import-policy` - to configure the policy on the DUT to the ATE port 1 bgp neighbor - * Send traffic from ATE port-2 to all prefix-sets-5,6. - * Verify traffic is received on ATE port 1 for accepted prefixes. - * Verify traffic is not received on ATE port 1 for rejected prefixes. - * Stop traffic - - * Expected matches for each policy - | | zero-bandwidth-reject | 1-megabit | 2-gigabit-match | - | ------------ | --------------------- | --------- | --------------- | - | prefix-set-5 | reject | reject | reject | - | prefix-set-6 | accept | accept | reject | - -## Config Parameter Coverage - -### Policy definition - -* /routing-policy/policy-definitions/policy-definition/config/name -* /routing-policy/policy-definitions/policy-definition/statements/statement/config/name - -### Policy for community-set configuration - -* /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/ext-community-set-name -* /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/community-member - -### Policy for community-set match configuration - -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/config/community-set -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-ext-community-set/config/match-set-options -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy - -## Telemetry Parameter Coverage - -### Policy definition state - -* /routing-policy/policy-definitions/policy-definition/state/name -* /routing-policy/policy-definitions/policy-definition/statements/statement/state/name - -### Policy for community-set match state - -* /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-set-name -* /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-member -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-ext-community-set/state/match-set-options -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/state/community-set - -### Paths to verify policy state - -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - -### Paths to verify prefixes sent and received - -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/sent -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received-pre-policy -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received -* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/installed diff --git a/feature/bgp/policybase/otg_tests/extcomm_action_test/metadata.textproto b/feature/bgp/policybase/otg_tests/extcomm_action_test/metadata.textproto deleted file mode 100644 index 7317700d4f6..00000000000 --- a/feature/bgp/policybase/otg_tests/extcomm_action_test/metadata.textproto +++ /dev/null @@ -1,7 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -plan_id: "RT-7.9" -description: "BGP Policy - Import/Export Policy Action Using Communities" -testbed: TESTBED_DUT_ATE_2LINKS -tags: [TAGS_AGGREGATION, TAGS_TRANSIT, TAGS_DATACENTER_EDGE] diff --git a/testregistry.textproto b/testregistry.textproto index 3234ce41fbc..dd2f3a69982 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -789,12 +789,6 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/policybase/otg_tests/comm_match_action_test/README.md" exec: " " } -test: { - id: "RT-7.9" - description: "BGP Policy - Import/Export Policy Action Using Extended Communities" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/policybase/otg_tests/extcomm_action_test/README.md" - exec: " " -} test: { id: "RT-8" description: "Singleton with breakouts" From ca635e0eddc26ae10d762bd9e5ca18f35586c57f Mon Sep 17 00:00:00 2001 From: sunilprgit Date: Fri, 15 Mar 2024 12:23:22 +0530 Subject: [PATCH 21/97] updating readme (#2813) --- .../otg_tests/link_bandwidth_test/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md b/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md index 813e1e65b40..743a2401fcd 100644 --- a/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md +++ b/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md @@ -13,8 +13,8 @@ communities to routes based on a prefix match. * Testbed configuration - Setup external BGP sessions and prefixes. * Generate config for 2 DUT and ATE ports where: - * DUT port 1 to ATE port 1. - * DUT port 2 to ATE port 2. + * DUT port 1 to ATE port 1 EBGP session. + * DUT port 2 to ATE port 2 IBGP session. * Configure dummy accept policies and attach it to both sessions on DUT. * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` named 'allow_all' with the following `statements` @@ -27,7 +27,8 @@ communities to routes based on a prefix match. * prefix-set-1 with 2 ipv4 and 2 ipv6 routes without communities. * prefix-set-2 with 2 ipv4 and 2 ipv6 routes with communities `[ "100:100" ]`. * prefix-set-3 with 2 ipv4 and 2 ipv6 routes with extended communities `[ "link-bandwidth:100:0" ]`. - + * Configure Send community knob to IBGP neigbour to advertise the communities to IBGP peer + * use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/send-community`. * RT-7.5.1 - Validate bgp sessions and traffic * For IPv4 and IPv6 prefixes: * Observe received prefixes at ATE port-2. @@ -144,6 +145,10 @@ communities to routes based on a prefix match. ## Config Parameter Coverage +## Configuration to enable advertise communities to bgp peer + +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/send-community + ### Policy for community-set configuration * /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/ext-community-set-name From dfc3107366972621074b918886c6f566324dda77 Mon Sep 17 00:00:00 2001 From: Rohit Rattan Date: Fri, 15 Mar 2024 19:26:11 +0530 Subject: [PATCH 22/97] Fixing test name (#2814) --- feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go b/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go index 31d36dc6c63..e9af47dd567 100644 --- a/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go +++ b/feature/bgp/policybase/otg_tests/aspath_test/aspath_test.go @@ -183,7 +183,7 @@ type testCase struct { testResults [6]bool } -func TestCommunitySet(t *testing.T) { +func TestAsPathSet(t *testing.T) { bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{"port2"}, true, true) From 4f5ebe7c73f65b6930b1ba11c9173e02215f8b4c Mon Sep 17 00:00:00 2001 From: Tushar Rathod <111466464+trathod1@users.noreply.github.com> Date: Mon, 18 Mar 2024 00:30:36 -0400 Subject: [PATCH 23/97] RT-1.33 : BGP Policy with prefix-set matching (#2718) * RT-1.33 : BGP Prefix-set initial commit Following changes in this PR - 1. Adding test script bgp_prefix_set_test.go 2. Adding new deviation skip_prefix_set_mode "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." * Fixing rundata using tools/addrundata --- .../prefix_set_test/bgp_prefix_set_test.go | 483 ++++++++++++++++++ .../prefix_set_test/metadata.textproto | 17 +- internal/deviations/deviations.go | 5 + proto/metadata.proto | 2 + proto/metadata_go_proto/metadata.pb.go | 96 ++-- 5 files changed, 560 insertions(+), 43 deletions(-) create mode 100644 feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go diff --git a/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go b/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go new file mode 100644 index 00000000000..e5e8dbacce7 --- /dev/null +++ b/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go @@ -0,0 +1,483 @@ +// Copyright 2023 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 bgp_prefix_set_test + +import ( + "testing" + "time" + + "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/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + otg "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +const ( + peerGrpName = "BGP-PEER-GROUP" + dutAS = 65501 + ateAS = 65502 + plenIPv4 = 30 + plenIPv6 = 126 + v4Prefixes = true + acceptPolicy = "PERMIT-ALL" + rejectPolicy = "REJECT-ALL" + bgpImportIPv4 = "IPv4-IMPORT" + bgpImportIPv6 = "IPv6-IMPORT" + bgpExportIPv4 = "IPv4-ExPORT" + bgpExportIPv6 = "IPv6-ExPORT" +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "DUT to ATE Port1", + IPv4: "192.0.2.1", + IPv6: "2001:db8::192:0:2:1", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + atePort1 = attrs.Attributes{ + Name: "atePort1", + IPv4: "192.0.2.2", + IPv6: "2001:db8::192:0:2:2", + MAC: "02:00:01:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + dutPort2 = attrs.Attributes{ + Desc: "DUT to ATE Port2", + IPv4: "192.0.2.5", + IPv6: "2001:db8::192:0:2:5", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + atePort2 = attrs.Attributes{ + Name: "atePort2", + IPv4: "192.0.2.6", + IPv6: "2001:db8::192:0:2:6", + MAC: "02:00:02:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + + ebgp1NbrV4 = &bgpNeighbor{ + nbrAddr: atePort1.IPv4, + isV4: true, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, + as: ateAS} + ebgp1NbrV6 = &bgpNeighbor{ + nbrAddr: atePort1.IPv6, + isV4: false, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST, + as: ateAS} + ebgp2NbrV4 = &bgpNeighbor{ + nbrAddr: atePort2.IPv4, + isV4: true, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, + as: ateAS} + ebgp2NbrV6 = &bgpNeighbor{ + nbrAddr: atePort2.IPv6, + isV4: false, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST, + as: ateAS} + ebgpNbrs = []*bgpNeighbor{ebgp1NbrV4, ebgp1NbrV6, ebgp2NbrV4, ebgp2NbrV6} + + route1 = &route{prefix: "10.23.15.1", maskLen: 32, isV4: true} + route2 = &route{prefix: "10.23.15.2", maskLen: 16, isV4: true} + route3 = &route{prefix: "10.23.15.60", maskLen: 26, isV4: true} + route4 = &route{prefix: "10.23.15.70", maskLen: 26, isV4: true} + route5 = &route{prefix: "20.23.15.2", maskLen: 16, isV4: true} + + route6 = &route{prefix: "2001:4860:f804::1", maskLen: 48, isV4: false} + route7 = &route{prefix: "2001:4860:f804::2", maskLen: 128, isV4: false} + route8 = &route{prefix: "2001:4860:f804:1111::1", maskLen: 64, isV4: false} + route9 = &route{prefix: "2001:4860:f804::10", maskLen: 70, isV4: false} + route10 = &route{prefix: "2001:5555:f804::1", maskLen: 48, isV4: false} + + routes = []*route{route1, route2, route3, route4, route5, route6, route7, route8, route9, route10} + + prefixSet1V4 = &prefixSetPolicy{ + name: "IPv4-prefix-set-1", + ipPrefix: "10.23.15.0/26", + maskLenRange: "exact", + statement: "10", + actionAccept: false, + isV4: true} + prefixSet2V4 = &prefixSetPolicy{ + name: "IPv4-prefix-set-2", + ipPrefix: "10.23.0.0/16", + maskLenRange: "16..32", + statement: "20", + actionAccept: true, + isV4: true} + prefixSet1V6 = &prefixSetPolicy{ + name: "IPv6-prefix-set-1", + ipPrefix: "2001:4860:f804::/48", + maskLenRange: "exact", + statement: "10", + actionAccept: true, + isV4: false} + prefixSet2V6 = &prefixSetPolicy{ + name: "IPv6-prefix-set-2", + ipPrefix: "::/0", + maskLenRange: "65..128", + statement: "20", + actionAccept: false, + isV4: false} +) + +type route struct { + prefix string + maskLen uint32 + isV4 bool +} + +type prefixSetPolicy struct { + name string + ipPrefix string + maskLenRange string + statement string + actionAccept bool + isV4 bool +} + +type bgpNeighbor struct { + as uint32 + nbrAddr string + isV4 bool + afiSafi oc.E_BgpTypes_AFI_SAFI_TYPE +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + dc := gnmi.OC() + i1 := dutPort1.NewOCInterface(dut.Port(t, "port1").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) + + i2 := dutPort2.NewOCInterface(dut.Port(t, "port2").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i2.GetName()).Config(), i2) + fptest.ConfigureDefaultNetworkInstance(t, dut) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dut.Port(t, "port1")) + fptest.SetPortSpeed(t, dut.Port(t, "port2")) + } + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, dut.Port(t, "port1").Name(), deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, dut.Port(t, "port2").Name(), deviations.DefaultNetworkInstance(dut), 0) + } +} + +func configurePrefixSet(t *testing.T, dut *ondatra.DUTDevice, prefixSet []*prefixSetPolicy) { + // configure prefix-sets + d := &oc.Root{} + rp := d.GetOrCreateRoutingPolicy() + for _, ps := range prefixSet { + pset := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(ps.name) + pset.GetOrCreatePrefix(ps.ipPrefix, ps.maskLenRange) + if !deviations.SkipPrefixSetMode(dut) { + if ps.isV4 { + pset.SetMode(oc.PrefixSet_Mode_IPV4) + } else { + pset.SetMode(oc.PrefixSet_Mode_IPV6) + } + } + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet(ps.name).Config(), pset) + } +} + +func applyPrefixSetPolicy(t *testing.T, dut *ondatra.DUTDevice, prefixSet []*prefixSetPolicy, policyName string, bgpNbr bgpNeighbor, importPolicy bool) { + d := &oc.Root{} + rp := d.GetOrCreateRoutingPolicy() + + // Associate prefix-set with routing-policy + pdef := rp.GetOrCreatePolicyDefinition(policyName) + for _, pSet := range prefixSet { + stmt, err := pdef.AppendNewStatement(pSet.statement) + if err != nil { + t.Fatal(err) + } + ps := stmt.GetOrCreateConditions().GetOrCreateMatchPrefixSet() + ps.SetPrefixSet(pSet.name) + if !deviations.SkipSetRpMatchSetOptions(dut) { + ps.SetMatchSetOptions(oc.E_RoutingPolicy_MatchSetOptionsRestrictedType(oc.RoutingPolicy_MatchSetOptionsType_ANY)) + } + stmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + if !pSet.actionAccept { + stmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE + } + } + + batchConfig := &gnmi.SetBatch{} + gnmi.BatchUpdate(batchConfig, gnmi.OC().RoutingPolicy().Config(), rp) + + // Apply routing-policy with BGP neighbor + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + if importPolicy { + gnmi.BatchReplace(batchConfig, bgpPath.Neighbor(bgpNbr.nbrAddr).AfiSafi(bgpNbr.afiSafi).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) + } else { + gnmi.BatchReplace(batchConfig, bgpPath.Neighbor(bgpNbr.nbrAddr).AfiSafi(bgpNbr.afiSafi).ApplyPolicy().ExportPolicy().Config(), []string{policyName}) + } + batchConfig.Set(t, dut) +} + +func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { + + // Configure BGP on DUT + dutOcRoot := &oc.Root{} + ni1 := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() + + global := bgp.GetOrCreateGlobal() + global.RouterId = ygot.String(dutPort1.IPv4) + global.As = ygot.Uint32(localAs) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + + pg := bgp.GetOrCreatePeerGroup(peerGrpName) + pg.PeerAs = ygot.Uint32(ateAS) + pg.PeerGroupName = ygot.String(peerGrpName) + + for _, nbr := range ebgpNbrs { + bgpNbr := bgp.GetOrCreateNeighbor(nbr.nbrAddr) + bgpNbr.PeerGroup = ygot.String(peerGrpName) + bgpNbr.PeerAs = ygot.Uint32(nbr.as) + bgpNbr.Enabled = ygot.Bool(true) + + if nbr.isV4 == true { + af4 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(true) + af6 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(false) + } else { + af4 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(false) + af6 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(true) + } + } + return niProto +} + +func verifyBgpState(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + + t.Logf("Waiting for BGP neighbor to establish...") + for _, nbr := range ebgpNbrs { + nbrPath := bgpPath.Neighbor(nbr.nbrAddr) + var status *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState] + status, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + return ok && state == oc.Bgp_Neighbor_SessionState_ESTABLISHED + }).Await(t) + if !ok { + fptest.LogQuery(t, "BGP reported state", nbrPath.State(), gnmi.Get(t, dut, nbrPath.State())) + t.Fatal("No BGP neighbor formed") + } + state, _ := status.Val() + t.Logf("BGP adjacency for %s: %v", nbr.nbrAddr, state) + if want := oc.Bgp_Neighbor_SessionState_ESTABLISHED; state != want { + t.Errorf("BGP peer %s status got %d, want %d", nbr.nbrAddr, state, want) + } + } +} + +func configureOTG(t *testing.T, otg *otg.OTG) { + t.Helper() + config := gosnappi.NewConfig() + port1 := config.Ports().Add().SetName("port1") + port2 := config.Ports().Add().SetName("port2") + + // Port1 Configuration. + iDut1Dev := config.Devices().Add().SetName(atePort1.Name) + iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1.Name + ".Eth").SetMac(atePort1.MAC) + iDut1Eth.Connection().SetPortName(port1.Name()) + iDut1Ipv4 := iDut1Eth.Ipv4Addresses().Add().SetName(atePort1.Name + ".IPv4") + iDut1Ipv4.SetAddress(atePort1.IPv4).SetGateway(dutPort1.IPv4).SetPrefix(uint32(atePort1.IPv4Len)) + iDut1Ipv6 := iDut1Eth.Ipv6Addresses().Add().SetName(atePort1.Name + ".IPv6") + iDut1Ipv6.SetAddress(atePort1.IPv6).SetGateway(dutPort1.IPv6).SetPrefix(uint32(atePort1.IPv6Len)) + + // Port2 Configuration. + iDut2Dev := config.Devices().Add().SetName(atePort2.Name) + iDut2Eth := iDut2Dev.Ethernets().Add().SetName(atePort2.Name + ".Eth").SetMac(atePort2.MAC) + iDut2Eth.Connection().SetPortName(port2.Name()) + iDut2Ipv4 := iDut2Eth.Ipv4Addresses().Add().SetName(atePort2.Name + ".IPv4") + iDut2Ipv4.SetAddress(atePort2.IPv4).SetGateway(dutPort2.IPv4).SetPrefix(uint32(atePort2.IPv4Len)) + iDut2Ipv6 := iDut2Eth.Ipv6Addresses().Add().SetName(atePort2.Name + ".IPv6") + iDut2Ipv6.SetAddress(atePort2.IPv6).SetGateway(dutPort2.IPv6).SetPrefix(uint32(atePort2.IPv6Len)) + + // eBGP v4 seesion on Port1. + iDut1Bgp := iDut1Dev.Bgp().SetRouterId(iDut1Ipv4.Address()) + iDut1Bgp4Peer := iDut1Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut1Ipv4.Name()).Peers().Add().SetName(atePort1.Name + ".BGP4.peer") + iDut1Bgp4Peer.SetPeerAddress(iDut1Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut1Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + // eBGP v6 seesion on Port1. + iDut1Bgp6Peer := iDut1Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut1Ipv6.Name()).Peers().Add().SetName(atePort1.Name + ".BGP6.peer") + iDut1Bgp6Peer.SetPeerAddress(iDut1Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + iDut1Bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut1Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + // eBGP v4 seesion on Port2. + iDut2Bgp := iDut2Dev.Bgp().SetRouterId(iDut2Ipv4.Address()) + iDut2Bgp4Peer := iDut2Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut2Ipv4.Name()).Peers().Add().SetName(atePort2.Name + ".BGP4.peer") + iDut2Bgp4Peer.SetPeerAddress(iDut2Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut2Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut2Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + // eBGP v6 seesion on Port2. + iDut2Bgp6Peer := iDut2Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut2Ipv6.Name()).Peers().Add().SetName(atePort2.Name + ".BGP6.peer") + iDut2Bgp6Peer.SetPeerAddress(iDut2Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + iDut2Bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut2Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + // eBGP V4 routes from Port1. + bgpNeti1Bgp4PeerRoutes := iDut1Bgp4Peer.V4Routes().Add().SetName(atePort1.Name + ".BGP4.Route") + bgpNeti1Bgp4PeerRoutes.SetNextHopIpv4Address(iDut1Ipv4.Address()). + SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). + SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) + + // eBGP V6 routes from Port1. + bgpNeti1Bgp6PeerRoutes := iDut1Bgp6Peer.V6Routes().Add().SetName(atePort1.Name + ".BGP6.Route") + bgpNeti1Bgp6PeerRoutes.SetNextHopIpv6Address(iDut1Ipv6.Address()). + SetNextHopAddressType(gosnappi.BgpV6RouteRangeNextHopAddressType.IPV6). + SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) + + for _, sendRoute := range routes { + if sendRoute.isV4 { + bgpNeti1Bgp4PeerRoutes.Addresses().Add(). + SetAddress(sendRoute.prefix).SetPrefix(sendRoute.maskLen) + } + if !sendRoute.isV4 { + bgpNeti1Bgp6PeerRoutes.Addresses().Add(). + SetAddress(sendRoute.prefix).SetPrefix(sendRoute.maskLen) + } + } + + otg.PushConfig(t, config) + otg.StartProtocols(t) +} + +func validatePrefixCount(t *testing.T, dut *ondatra.DUTDevice, nbr bgpNeighbor, wantInstalled, wantRx, wantSent uint32) { + t.Helper() + + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + t.Logf("Validating prefix count for peer %v", nbr.nbrAddr) + prefixPath := statePath.Neighbor(nbr.nbrAddr).AfiSafi(nbr.afiSafi).Prefixes() + + // Waiting for Installed count to get updated after session comes up or policy is applied + gotInstalled, ok := gnmi.Watch(t, dut, prefixPath.Installed().State(), 10*time.Second, func(val *ygnmi.Value[uint32]) bool { + gotInstalled, _ := val.Val() + return gotInstalled == wantInstalled + }).Await(t) + if !ok { + t.Errorf("Installed prefixes mismatch: got %v, want %v", gotInstalled, wantInstalled) + } + + if !deviations.MissingPrePolicyReceivedRoutes(dut) { + // Waiting for Received count to get updated after session comes up or policy is applied + gotRx, ok := gnmi.Watch(t, dut, prefixPath.ReceivedPrePolicy().State(), 10*time.Second, func(val *ygnmi.Value[uint32]) bool { + gotRx, _ := val.Val() + return gotRx == wantRx + }).Await(t) + if !ok { + t.Errorf("Received prefixes mismatch: got %v, want %v", gotRx, wantRx) + } + } + + // Waiting for Sent count to get updated after session comes up or policy is applied + gotSent, ok := gnmi.Watch(t, dut, prefixPath.Sent().State(), 10*time.Second, func(val *ygnmi.Value[uint32]) bool { + gotSent, _ := val.Val() + return gotSent == wantSent + }).Await(t) + if !ok { + t.Errorf("Sent prefixes mismatch: got %v, want %v", gotSent, wantSent) + } +} + +// testPrefixSet is to validate prefix-set policies +func testPrefixSet(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + importPolicy := true + + // Configuring all 4 reqruired prefix-sets + t.Run("Configure prefix-set", func(t *testing.T) { + configurePrefixSet(t, dut, []*prefixSetPolicy{prefixSet1V4, prefixSet2V4, prefixSet1V6, prefixSet2V6}) + }) + + // Associating prefix-set with the required routing-policy and applying to BGP neighbors on ATE-port-1 + t.Run("Validate acceptance based on prefix-set policy", func(t *testing.T) { + applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet1V4, prefixSet2V4}, bgpImportIPv4, *ebgp1NbrV4, importPolicy) + applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet1V6, prefixSet2V6}, bgpImportIPv6, *ebgp1NbrV6, importPolicy) + + // route1, route2, route4 expected to be accepted based on prefix-set + validatePrefixCount(t, dut, *ebgp1NbrV4, 3, 5, 0) + // only route6 is expected to accepted based on prefix-set + validatePrefixCount(t, dut, *ebgp1NbrV6, 1, 5, 0) + validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 0) + validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 0) + }) + + // Associating prefix-set with the required routing-policy and applying to BGP neighbors on ATE-port-2 + t.Run("Validate advertise based on prefix-set policy", func(t *testing.T) { + applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet2V4}, bgpExportIPv4, *ebgp2NbrV4, !importPolicy) + applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet1V6}, bgpExportIPv6, *ebgp2NbrV6, !importPolicy) + + // route1, route2, route4 expected to be advertised based on prefix-set + validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 3) + // only route6 is expected to be advertised based on prefix-set + validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 1) + }) +} + +// TestBGPPrefixSet is to test prefix-set at the BGP neighbor levels. +func TestBGPPrefixSet(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + // Bring up 4 eBGP neighbors between DUT and ATE + t.Run("Establish BGP sessions", func(t *testing.T) { + configureDUT(t, dut) + + dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + gnmi.Delete(t, dut, dutConfPath.Config()) + dutConf := bgpCreateNbr(dutAS, ateAS, dut) + gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) + + otg := ate.OTG() + configureOTG(t, otg) + verifyBgpState(t, dut) + }) + + // Validate route count for BGP neighbors with default deny-all routing-policy + t.Run("Validate initial prefix count", func(t *testing.T) { + validatePrefixCount(t, dut, *ebgp1NbrV4, 0, 5, 0) + validatePrefixCount(t, dut, *ebgp1NbrV6, 0, 5, 0) + validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 0) + validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 0) + }) + + testPrefixSet(t, dut) +} diff --git a/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto b/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto index 10354b4d109..9bb11b3d562 100644 --- a/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto @@ -1,7 +1,22 @@ # proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata +uuid: "3a55a01a-2a2d-404e-b397-a840192d8d67" plan_id: "RT-1.33" description: "BGP Policy with prefix-set matching" testbed: TESTBED_DUT_ATE_2LINKS -tags: [TAGS_AGGREGATION, TAGS_TRANSIT, TAGS_DATACENTER_EDGE] +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_port_speed: true + explicit_interface_in_default_vrf: true + interface_enabled: true + skip_set_rp_match_set_options: true + skip_prefix_set_mode: true + } +} +tags: TAGS_AGGREGATION +tags: TAGS_TRANSIT +tags: TAGS_DATACENTER_EDGE diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index c334e54beb4..d9f48e97500 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -830,3 +830,8 @@ func SkipMacaddressCheck(dut *ondatra.DUTDevice) bool { func BGPRibOcPathUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetBgpRibOcPathUnsupported() } + +// SkipPrefixSetMode return true if device needs to skip setting prefix-set mode while configuring prefix-set routing-policy +func SkipPrefixSetMode(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetSkipPrefixSetMode() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index f9efbc2866a..87db1b59360 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -442,6 +442,8 @@ message Metadata { // Devices are having native telemetry paths for BGP RIB verification. // Juniper : b/306144372 bool bgp_rib_oc_path_unsupported = 155; + // Skip setting prefix-set mode while configuring prefix-set routing-policy + bool skip_prefix_set_mode = 156; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index d3bd55eb024..6b40c400684 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.19.3 +// protoc-gen-go v1.31.0 +// protoc v3.14.0 // source: metadata.proto package metadata_go_proto @@ -713,6 +713,8 @@ type Metadata_Deviations struct { // Devices are having native telemetry paths for BGP RIB verification. // Juniper : b/306144372 BgpRibOcPathUnsupported bool `protobuf:"varint,155,opt,name=bgp_rib_oc_path_unsupported,json=bgpRibOcPathUnsupported,proto3" json:"bgp_rib_oc_path_unsupported,omitempty"` + // Skip setting prefix-set mode while configuring prefix-set routing-policy + SkipPrefixSetMode bool `protobuf:"varint,156,opt,name=skip_prefix_set_mode,json=skipPrefixSetMode,proto3" json:"skip_prefix_set_mode,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1720,6 +1722,13 @@ func (x *Metadata_Deviations) GetBgpRibOcPathUnsupported() bool { return false } +func (x *Metadata_Deviations) GetSkipPrefixSetMode() bool { + if x != nil { + return x.SkipPrefixSetMode + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1783,7 +1792,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb8, 0x56, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xea, 0x56, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1814,7 +1823,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xb9, 0x4e, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xeb, 0x4e, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2438,44 +2447,47 @@ var file_metadata_proto_rawDesc = []byte{ 0x0a, 0x1b, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x69, 0x62, 0x5f, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x9b, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, 0x67, 0x70, 0x52, 0x69, 0x62, 0x4f, 0x63, 0x50, 0x61, - 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, - 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, - 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, - 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, - 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, - 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, - 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, - 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, - 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, - 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, - 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, - 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, - 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, - 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, - 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, - 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, + 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x74, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x9c, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, + 0x69, 0x70, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x4a, + 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, + 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, + 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, + 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, + 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, + 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, + 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, + 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, + 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, + 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, + 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, + 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, + 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, + 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, + 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, + 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, + 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, + 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, + 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, + 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, + 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, + 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From aa0b48b2783e03c1e95f42d1a8a018fe476e7613 Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Mon, 18 Mar 2024 14:01:08 +0530 Subject: [PATCH 24/97] added required deviations for arista (#2823) --- .../otg_tests/basic_encap_test/metadata.textproto | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/feature/gribi/otg_tests/basic_encap_test/metadata.textproto b/feature/gribi/otg_tests/basic_encap_test/metadata.textproto index 7f8aa1382c1..18e5306efb7 100644 --- a/feature/gribi/otg_tests/basic_encap_test/metadata.textproto +++ b/feature/gribi/otg_tests/basic_encap_test/metadata.textproto @@ -4,7 +4,7 @@ uuid: "36cc79b5-3766-4cb4-b83b-1baea1464de8" plan_id: "TE-16.1" description: "basic encapsulation tests" -testbed: TESTBED_DUT_ATE_2LINKS +testbed: TESTBED_DUT_ATE_8LINKS platform_exceptions: { platform: { vendor: CISCO @@ -17,4 +17,15 @@ platform_exceptions: { pf_require_match_default_rule: true } } +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + omit_l2_mtu: true + default_network_instance: "default" + static_protocol_name: "STATIC" + } +} tags: TAGS_DATACENTER_EDGE From c33dbbc82b8fe1ebd1b11afaf86ed7d60e603bd9 Mon Sep 17 00:00:00 2001 From: Rohit Rattan Date: Mon, 18 Mar 2024 19:32:42 +0530 Subject: [PATCH 25/97] MGT-1 Management HA test readme (#2763) * Management HA Readme * updating git issue * updating the README --- feature/system/management/README.md | 169 +++++++++++++++++++ feature/system/management/metadata.textproto | 7 + testregistry.textproto | 6 + 3 files changed, 182 insertions(+) create mode 100644 feature/system/management/README.md create mode 100644 feature/system/management/metadata.textproto diff --git a/feature/system/management/README.md b/feature/system/management/README.md new file mode 100644 index 00000000000..b5e1b4ce730 --- /dev/null +++ b/feature/system/management/README.md @@ -0,0 +1,169 @@ +# MGT-1: Management HA solution test + +## Summary + +- Test management HA + +## Testbed type + +* https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_4.testbed + +## Procedure + +### Applying configuration + +For each section of configuration below, prepare a gnmi.SetBatch with all the configuration items appended to one SetBatch. Then apply the configuration to the DUT in one gnmi.Set +using the `replace` option + +### Initial Setup: + +* Connect DUT port-1, 2 and 3 to ATE port-1, 2 and 3 +* Create VRF "mgmt" on DUT + * /network-instances/network-instance[name=mgmt]/config/name = mgmt + * /network-instances/network-instance[name=mgmt]/config/route-distinguisher = 64512:100 +* Create an IPv6 networks ```ateNet``` attached to ATE port-1, 2 and 3 +* Create a loopback interface "lo1" on DUT and assign it an IPv6 address + * /interfaces/interface[name=lo1]/config/name = lo1 + * /interfaces/interface[name=lo1]/config/type = softwareLoopback + * /interfaces/interface[name=lo1]/subinterfaces/subinterface[index=0]/ipv6/addresses/address/config/ip + * /interfaces/interface[name=lo1]/subinterfaces/subinterface[index=0]/ipv6/addresses/address/config/prefix-length +* Configure the loopback interface to participate in the VRF "mgmt" + * /network-instances/network-instance[name=mgmt]/interfaces/interface[name=lo1]/config/interface = lo1 + +##### Configure linecard ports to ATE using BGP + +* Configure IPv6 addresses on DUT and ATE ports 1 and 2. Configure them to participate in the VRF "mgmt" + * /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config/ip + * /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config/prefix-length + * /network-instances/network-instance[name=mgmt]/interfaces/interface/config/interface +* Configure IPv6 eBGP between DUT Port-1 <--> ATE Port-1 and DUT Port-2 <--> ATE Port-2 in VRF "mgmt" + * /network-instances/network-instance[name=mgmt]/protocols/protocol[identifier=BGP, name=BGP]/global/config/as = 64512 + * /network-instances/network-instance[name=mgmt]/protocols/protocol[identifier=BGP, name=BGP]/global/config/router-id = + * /network-instances/network-instance[name=mgmt]/protocols/protocol[identifier=BGP, name=BGP]/neighbor/config/peer-as = 64511 +* Set default import and export policy to ```ACCEPT_ROUTE``` for the eBGP sessions + * /network-instances/network-instance[name=mgmt]/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy + * /network-instances/network-instance[name=mgmt]/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy +* Advertise a default route from ATE to DUT throught both the BGP sessions +* Redistribute the loopback interface from DUT to ATE through both the BGP sessions + ##### Configure redistribution + * Set address-family to ```IPV6``` + * /network-instances/network-instance/table-connections/table-connection/config/address-family + * Configure source protocol to ```CONNECTED``` + * /network-instances/network-instance/table-connections/table-connection/config/src-protocol + * Configure destination protocol to ```BGP``` + * /network-instances/network-instance/table-connections/table-connection/config/dst-protocol + * Configure default export policy to ```ACCEPT_ROUTE``` + * /network-instances/network-instance/table-connections/table-connection/config/default-export-policy + * Disable metric propogation by setting it to ```true``` + * /network-instances/network-instance/table-connections/table-connection/config/disable-metric-propagation + ##### Configure redistribution + * Configure an IPv6 route-policy definition with the name ```route-policy``` + * /routing-policy/policy-definitions/policy-definition/config/name + * For routing-policy ```route-policy``` configure a statement with the name ```statement``` + * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name + * For routing-policy ```route-policy``` statement ```statement``` set policy-result as ```ACCEPT_ROUTE``` + * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result + ##### Configure a prefix-set for route-filtering/matching + * Configure a prefix-set with the name ```prefix-set``` and mode ```IPV6``` + * /routing-policy/defined-sets/prefix-sets/prefix-set/config/name + * /routing-policy/defined-sets/prefix-sets/prefix-set/config/mode + * For prefix-set ```prefix-set``` set the ip-prefix to ```loopback0 IPv6 address/mask``` and masklength to ```exact``` + * /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/ip-prefix + * /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/masklength-range + ##### Attach the prefix-set to route-policy + * For routing-policy ```route-policy``` statement ```statement``` set match options to ```ANY``` + * /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options + * For routing-policy ```route-policy``` statement ```statement``` set prefix set to ```prefix-set``` + * /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set + ##### Attach the route-policy to the redistribution export-policy + * Apply routing policy ```route-policy``` for redistribution to BGP + * /network-instances/network-instance/table-connections/table-connection/config/export-policy + +##### Configure linecard port to ATE + +* Configure IPv6 addresses on DUT Port-3 and ATE Port-3 + * /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config/ip + * /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config/prefix-length +* Configure DUT Port-3 to participate in the VRF "mgmt" + * /network-instances/network-instance[name=mgmt]/interfaces/interface/config/interface +* Configure a static route on ATE device of Port-3 destined to the DUT loopback with next-hop address of DUT Port-3 with administrative-distance or preference of 220 +* Configure a IPv6 default static route on DUT in VRF "mgmt" pointing towards the IPv6 address of ATE Port-3 with Administrative Distance or Preference of 220 + * /network-instances/network-instance[name=mgmt]/protocols/protocol[identifier=STATIC, name=static]/static-routes/static/config/prefix = ::/0 + * /network-instances/network-instance[name=mgmt]/protocols/protocol[identifier=STATIC, name=static]/static-routes/static/next-hops/next-hop/index = 1 + * /network-instances/network-instance[name=mgmt]/protocols/protocol[identifier=STATIC, name=static]/static-routes/static/next-hops/next-hop[index=1]/config/next-hop = ATE Port-3 IP + * /network-instances/network-instance[name=mgmt]/protocols/protocol[identifier=STATIC, name=static]/static-routes/static/next-hops/next-hop/config/preference = 220 + +### MGT-1.1 [TODO: https://github.com/openconfig/featureprofiles/issues/2762] +#### Testing reachability to the DUT loopback with no failures in the network +--- + +* Generate ICMP echo (ping) sourced from the ```ateNet``` network destined towards the DUT loopback1 IPv6 address +* Validate ICMP echo-reply is received by the ATE on Port-1 or Port-2 + +### MGT-1.2 [TODO: https://github.com/openconfig/featureprofiles/issues/2762] +#### Testing BGP redundancy +--- + +* Shutdown BGP session on Port-1 +* Generate ICMP echo (ping) sourced from the ```ateNet``` network destined towards the DUT loopback1 IPv6 address +* Validate ICMP echo-reply is received by the ATE on Port-2 +* Bring up BGP session on Port-1 and shutdowm BGP on Port-2 +* Generate ICMP echo (ping) sourced from the ```ateNet``` network destined towards the DUT loopback1 IPv6 address +* Validate ICMP echo-reply is received by the ATE on Port-1 + +### MGT-1.3 [TODO: https://github.com/openconfig/featureprofiles/issues/2762] +#### Testing failover between BGP and Static route +--- + +* Shutdown BGP session on Port-1 and Port-2 +* Generate ICMP echo (ping) sourced from the ```ateNet``` network destined towards the DUT loopback1 IPv6 address +* Validate ICMP echo-reply is received by the ATE on Port-3 +* Bring up BGP session on Port-1 and Port-2 +* Generate ICMP echo (ping) sourced from the ```ateNet``` network destined towards the DUT loopback1 IPv6 address +* Validate ICMP echo-reply is received by the ATE on Port-1 or Port-2 + +## Config parameter coverage + +* /network-instances/network-instance/config/name +* /network-instances/network-instance/config/route-distinguisher +* /network-instances/network-instance/interfaces/interface/config/interface +* /interfaces/interface/config/name +* /interfaces/interface/config/type +* /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config/ip +* /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/config/prefix-length +* /network-instances/network-instance/protocols/protocol/global/config/as +* /network-instances/network-instance/protocols/protocol/global/config/router-id +* /network-instances/network-instance/protocols/protocol/neighbor/config/peer-as +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy +* /network-instances/network-instance/table-connections/table-connection/config/address-family +* /network-instances/network-instance/table-connections/table-connection/config/src-protocol +* /network-instances/network-instance/table-connections/table-connection/config/dst-protocol +* /network-instances/network-instance/table-connections/table-connection/config/default-export-policy +* /network-instances/network-instance/table-connections/table-connection/config/disable-metric-propagation +* /routing-policy/policy-definitions/policy-definition/config/name +* /routing-policy/policy-definitions/policy-definition/statements/statement/config/name +* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result +* /routing-policy/defined-sets/prefix-sets/prefix-set/config/name +* /routing-policy/defined-sets/prefix-sets/prefix-set/config/mode +* /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/ip-prefix +* /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/masklength-range +* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options +* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set +* /network-instances/network-instance/protocols/protocol/static-routes/static/config/prefix +* /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/index +* /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/next-hop +* /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/preference + +## Telemetry parameter coverage + +* NA + +## Protocol/RPC Parameter Coverage + +* gNMI + * Set (replace) + +## Required DUT platform + +* FFF diff --git a/feature/system/management/metadata.textproto b/feature/system/management/metadata.textproto new file mode 100644 index 00000000000..205908fe722 --- /dev/null +++ b/feature/system/management/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +plan_id: "MGT-1" +description: "Management HA test" +testbed: TESTBED_DUT_ATE_4LINKS +tags: [TAGS_AGGREGATION, TAGS_TRANSIT, TAGS_DATACENTER_EDGE] diff --git a/testregistry.textproto b/testregistry.textproto index dd2f3a69982..3e815276597 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -1389,3 +1389,9 @@ test: { readme: "https://github.com/openconfig/featureprofiles/feature/experimental/platform/tests/breakout_configuration/README.md" exec: " " } +test: { + id: "MGT-1" + description: "Management HA test" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/system/management/README.md" + exec: " " +} From 1aad4047eda8b856f053df54710ed0c5091af4dc Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Mon, 18 Mar 2024 21:03:43 +0530 Subject: [PATCH 26/97] management ha solution test (#2786) * management HA solution test * merged readme --- .../management_ha_test}/README.md | 0 .../management_ha_test/management_ha_test.go | 313 ++++++++++++++++++ .../management_ha_test/metadata.textproto | 25 ++ internal/deviations/deviations.go | 6 + proto/metadata.proto | 2 + proto/metadata_go_proto/metadata.pb.go | 97 +++--- 6 files changed, 401 insertions(+), 42 deletions(-) rename feature/system/management/{ => otg_tests/management_ha_test}/README.md (100%) create mode 100644 feature/system/management/otg_tests/management_ha_test/management_ha_test.go create mode 100644 feature/system/management/otg_tests/management_ha_test/metadata.textproto diff --git a/feature/system/management/README.md b/feature/system/management/otg_tests/management_ha_test/README.md similarity index 100% rename from feature/system/management/README.md rename to feature/system/management/otg_tests/management_ha_test/README.md diff --git a/feature/system/management/otg_tests/management_ha_test/management_ha_test.go b/feature/system/management/otg_tests/management_ha_test/management_ha_test.go new file mode 100644 index 00000000000..1000241b90d --- /dev/null +++ b/feature/system/management/otg_tests/management_ha_test/management_ha_test.go @@ -0,0 +1,313 @@ +// 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 management_ha_test + +import ( + "fmt" + "math" + "sort" + "testing" + "time" + + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/cfgplugins" + "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/ondatra/netutil" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +const ( + prefixesStart = "2001:db8:1::1" + prefixP6Len = 128 + prefixesCount = 1 + pathID = 1 + defaultRoute = "0:0:0:0:0:0:0:0" + dutAS = 65501 +) + +var ( + dutlo0Attrs = attrs.Attributes{ + Desc: "Loopback ip", + IPv4: "203.0.113.1", + IPv6: "2001:db8::203:0:113:1", + IPv4Len: 32, + IPv6Len: 128, + } + + mgmtVRF = "mgmtvrf1" + bgpPorts = []string{"port1", "port2"} + + setNoPeerGroup = true + lossTolerance = float64(1) +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestManagementHA1(t *testing.T) { + dut := ondatra.DUT(t, "dut") + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + p3 := dut.Port(t, "port3") + p4 := dut.Port(t, "port4") + loopbackIntfName := netutil.LoopbackInterface(t, dut, 1) + + addInterfacesToVRF(t, dut, mgmtVRF, []string{p1.Name(), p2.Name(), p3.Name(), p4.Name(), loopbackIntfName}) + + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount4, &mgmtVRF) + bs.WithEBGP( + t, + []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, + bgpPorts, + true, + true, + ) + + if setNoPeerGroup { + bs.DUTConf.GetOrCreateNetworkInstance(mgmtVRF).GetOrCreateProtocol(cfgplugins.PTBGP, "BGP").GetOrCreateBgp().PeerGroup = nil + neighbors := bs.DUTConf.GetOrCreateNetworkInstance(mgmtVRF).GetOrCreateProtocol(cfgplugins.PTBGP, "BGP").GetOrCreateBgp().Neighbor + for _, neighbor := range neighbors { + neighbor.PeerGroup = nil + } + } + + configureEmulatedNetworks(bs) + + bs.DUTConf.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)).GetOrCreateProtocol(cfgplugins.PTBGP, "BGP").GetOrCreateBgp().GetOrCreateGlobal().SetAs(dutAS) + bs.DUTConf.GetOrCreateNetworkInstance(mgmtVRF).SetRouteDistinguisher(fmt.Sprintf("%d:%d", dutAS, 100)) + + bs.PushAndStart(t) + if verfied := verifyDUTBGPEstablished(t, bs.DUT, mgmtVRF); verfied { + t.Log("DUT BGP sessions established") + } else { + t.Fatalf("BGP sessions not established") + } + cfgplugins.VerifyOTGBGPEstablished(t, bs.ATE) + + configureLoopbackOnDUT(t, bs.DUT) + advertiseDUTLoopbackToATE(t, bs.DUT) + configureStaticRoute(t, bs.DUT, bs.ATEPorts[2].IPv6) + + t.Run("traffic received by port1 or port2", func(t *testing.T) { + createFlowV6(t, bs) + otgutils.WaitForARP(t, bs.ATE.OTG(), bs.ATETop, "IPv6") + bs.ATE.OTG().StartTraffic(t) + time.Sleep(30 * time.Second) + bs.ATE.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + otgutils.LogPortMetrics(t, bs.ATE.OTG(), bs.ATETop) + lossV6 := otgutils.GetFlowLossPct(t, bs.ATE.OTG(), "v6Flow", 10*time.Second) + if lossV6 > lossTolerance { + t.Errorf("Loss percent for IPv6 Traffic: got: %f, want %f", lossV6, lossTolerance) + } + }) + + t.Run("traffic received by port2", func(t *testing.T) { + createFlowV6(t, bs) + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Enabled().Config(), false) + gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_DOWN) + bs.ATE.OTG().StartTraffic(t) + time.Sleep(30 * time.Second) + bs.ATE.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + otgutils.LogPortMetrics(t, bs.ATE.OTG(), bs.ATETop) + framesTx := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Port(bs.ATE.Port(t, "port4").ID()).Counters().OutFrames().State()) + framesRx := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Port(bs.ATE.Port(t, "port2").ID()).Counters().InFrames().State()) + if lossPct(float64(framesTx), float64(framesRx)) > lossTolerance { + t.Errorf("Frames sent/received: got: %d, want: %d", framesRx, framesTx) + } + }) + + t.Run("traffic received by port3", func(t *testing.T) { + createFlowV6(t, bs) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Enabled().Config(), false) + gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_DOWN) + bs.ATE.OTG().StartTraffic(t) + time.Sleep(30 * time.Second) + bs.ATE.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + otgutils.LogPortMetrics(t, bs.ATE.OTG(), bs.ATETop) + framesTx := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Port(bs.ATE.Port(t, "port4").ID()).Counters().OutFrames().State()) + framesRx := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Port(bs.ATE.Port(t, "port3").ID()).Counters().InFrames().State()) + if lossPct(float64(framesTx), float64(framesRx)) > lossTolerance { + t.Errorf("Frames sent/received: got: %d, want: %d", framesRx, framesTx) + } + }) + + t.Run("traffic received by port1", func(t *testing.T) { + createFlowV6(t, bs) + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Enabled().Config(), true) + gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_UP) + time.Sleep(30 * time.Second) + bs.ATE.OTG().StartTraffic(t) + time.Sleep(30 * time.Second) + bs.ATE.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + otgutils.LogPortMetrics(t, bs.ATE.OTG(), bs.ATETop) + framesTx := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Port(bs.ATE.Port(t, "port4").ID()).Counters().OutFrames().State()) + framesRx := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Port(bs.ATE.Port(t, "port1").ID()).Counters().InFrames().State()) + if lossPct(float64(framesTx), float64(framesRx)) > lossTolerance { + t.Errorf("Frames sent/received: got: %d, want: %d", framesRx, framesTx) + } + }) +} + +func createFlowV6(t *testing.T, bs *cfgplugins.BGPSession) { + bs.ATETop.Flows().Clear() + + t.Log("Configuring v6 traffic flow") + v6Flow := bs.ATETop.Flows().Add().SetName("v6Flow") + v6Flow.Metrics().SetEnable(true) + v6Flow.TxRx().Device(). + SetTxNames([]string{"port4.IPv6"}). + SetRxNames([]string{"port1.BGP4.peer.rr6", "port2.BGP4.peer.rr6", "port3.IPv6"}) + v6Flow.Size().SetFixed(512) + v6Flow.Rate().SetPps(100) + v6Flow.Duration().Continuous() + e1 := v6Flow.Packet().Add().Ethernet() + e1.Src().SetValues([]string{bs.ATEPorts[3].MAC}) + v6 := v6Flow.Packet().Add().Ipv6() + v6.Src().SetValue(bs.ATEPorts[3].IPv6) + v6.Dst().Increment().SetStart(prefixesStart).SetCount(1) + icmp1 := v6Flow.Packet().Add().Icmp() + icmp1.SetEcho(gosnappi.NewFlowIcmpEcho()) + + bs.ATE.OTG().PushConfig(t, bs.ATETop) + bs.ATE.OTG().StartProtocols(t) +} + +func configureStaticRoute(t *testing.T, dut *ondatra.DUTDevice, nextHopIP string) { + c := &oc.NetworkInstance_Protocol{ + Identifier: oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + Name: ygot.String(deviations.StaticProtocolName(dut)), + } + s := c.GetOrCreateStatic(defaultRoute + "/0") + nh := s.GetOrCreateNextHop("0") + nh.NextHop = oc.UnionString(nextHopIP) + if deviations.SetMetricAsPreference(dut) { + nh.Metric = ygot.Uint32(220) + } else { + nh.Preference = ygot.Uint32(220) + } + sp := gnmi.OC().NetworkInstance(mgmtVRF).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) + gnmi.Update(t, dut, sp.Config(), c) + gnmi.Replace(t, dut, sp.Static(defaultRoute+"/0").Config(), s) +} + +func configureEmulatedNetworks(bs *cfgplugins.BGPSession) { + devices := bs.ATETop.Devices().Items() + byName := func(i, j int) bool { return devices[i].Name() < devices[j].Name() } + sort.Slice(devices, byName) + for i, otgPort := range bs.ATEPorts[:len(bgpPorts)] { + ipv6 := devices[i].Ethernets().Items()[0].Ipv6Addresses().Items()[0] + bgp6Peer := devices[i].Bgp().Ipv6Interfaces().Items()[0].Peers().Items()[0] + bgp6PeerRoute := bgp6Peer.V6Routes().Add() + bgp6PeerRoute.SetName(otgPort.Name + ".BGP4.peer.rr6") + bgp6PeerRoute.SetNextHopIpv6Address(ipv6.Address()) + bgp6PeerRoute.SetNextHopAddressType(gosnappi.BgpV6RouteRangeNextHopAddressType.IPV6) + bgp6PeerRoute.SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) + bgp6PeerRoute.AddPath().SetPathId(pathID) + + bgp6PeerRoute.Addresses().Add().SetAddress(prefixesStart).SetPrefix(prefixP6Len).SetCount(prefixesCount) + bgp6PeerRoute.Addresses().Add().SetAddress(defaultRoute).SetPrefix(0) + } +} + +func configureLoopbackOnDUT(t *testing.T, dut *ondatra.DUTDevice) { + loopbackIntfName := netutil.LoopbackInterface(t, dut, 1) + loop := dutlo0Attrs.NewOCInterface(loopbackIntfName, dut) + loop.Type = oc.IETFInterfaces_InterfaceType_softwareLoopback + gnmi.Update(t, dut, gnmi.OC().Interface(loopbackIntfName).Config(), loop) + t.Logf("Got DUT IPv6 loopback address: %v", dutlo0Attrs.IPv6) +} + +func addInterfacesToVRF(t *testing.T, dut *ondatra.DUTDevice, vrfname string, intfNames []string) { + root := &oc.Root{} + mgmtNI := root.GetOrCreateNetworkInstance(vrfname) + mgmtNI.Type = oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF + for _, intfName := range intfNames { + vi := mgmtNI.GetOrCreateInterface(intfName) + vi.Interface = ygot.String(intfName) + vi.Subinterface = ygot.Uint32(0) + } + gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(mgmtVRF).Config(), mgmtNI) + t.Logf("Added interface %v to VRF %s", intfNames, vrfname) +} + +func verifyDUTBGPEstablished(t *testing.T, dut *ondatra.DUTDevice, ni string) bool { + nSessionState := gnmi.OC().NetworkInstance(ni).Protocol(cfgplugins.PTBGP, "BGP").Bgp().NeighborAny().SessionState().State() + watch := gnmi.WatchAll(t, dut, nSessionState, 2*time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + if !ok || state != oc.Bgp_Neighbor_SessionState_ESTABLISHED { + return false + } + return true + }) + if _, ok := watch.Await(t); !ok { + return false + } + return true +} + +func advertiseDUTLoopbackToATE(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + + batchSet := &gnmi.SetBatch{} + + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + pdef := rp.GetOrCreatePolicyDefinition("rp") + stmt, err := pdef.AppendNewStatement("rp-stmt") + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", "rp-stmt", err) + } + stmt.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + prefixSet := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet("ps") + prefixSet.SetMode(oc.PrefixSet_Mode_IPV6) + prefixSet.GetOrCreatePrefix(dutlo0Attrs.IPv6CIDR(), "exact") + + if !deviations.SkipSetRpMatchSetOptions(dut) { + stmt.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + stmt.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet("ps") + gnmi.BatchUpdate(batchSet, gnmi.OC().RoutingPolicy().Config(), rp) + + tableConn := root.GetOrCreateNetworkInstance(mgmtVRF).GetOrCreateTableConnection(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_DIRECTLY_CONNECTED, oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, oc.Types_ADDRESS_FAMILY_IPV6) + if !deviations.SkipSettingDisableMetricPropagation(dut) { + tableConn.SetDisableMetricPropagation(false) + } + tableConn.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + tableConn.SetImportPolicy([]string{"rp"}) + gnmi.BatchUpdate(batchSet, gnmi.OC().NetworkInstance(mgmtVRF).TableConnection(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_DIRECTLY_CONNECTED, oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, oc.Types_ADDRESS_FAMILY_IPV6).Config(), tableConn) + + tableConn1 := root.GetOrCreateNetworkInstance(mgmtVRF).GetOrCreateTableConnection(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_DIRECTLY_CONNECTED, oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, oc.Types_ADDRESS_FAMILY_IPV4) + tableConn1.SetImportPolicy([]string{"rp"}) + gnmi.BatchUpdate(batchSet, gnmi.OC().NetworkInstance(mgmtVRF).TableConnection(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_DIRECTLY_CONNECTED, oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, oc.Types_ADDRESS_FAMILY_IPV4).Config(), tableConn1) + + batchSet.Set(t, dut) +} + +func lossPct(tx, rx float64) float64 { + return (math.Abs(tx-rx) * 100) / tx +} diff --git a/feature/system/management/otg_tests/management_ha_test/metadata.textproto b/feature/system/management/otg_tests/management_ha_test/metadata.textproto new file mode 100644 index 00000000000..247f7f2735d --- /dev/null +++ b/feature/system/management/otg_tests/management_ha_test/metadata.textproto @@ -0,0 +1,25 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "b569d5de-0038-43f5-b329-bedce86eec3d" +plan_id: "MGT-1" +description: "Management HA solution test" +testbed: TESTBED_DUT_ATE_4LINKS +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + route_policy_under_afi_unsupported: true + omit_l2_mtu: true + static_protocol_name: "STATIC" + interface_enabled: true + default_network_instance: "default" + skip_set_rp_match_set_options: true + skip_setting_disable_metric_propagation: true + set_metric_as_preference: true + } +} +tags: TAGS_AGGREGATION +tags: TAGS_TRANSIT +tags: TAGS_DATACENTER_EDGE diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index d9f48e97500..3a91d1fad52 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -835,3 +835,9 @@ func BGPRibOcPathUnsupported(dut *ondatra.DUTDevice) bool { func SkipPrefixSetMode(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetSkipPrefixSetMode() } + +// SetMetricAsPreference returns true for devices which set metric as +// preference for static next-hop +func SetMetricAsPreference(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetSetMetricAsPreference() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 87db1b59360..40415e91693 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -444,6 +444,8 @@ message Metadata { bool bgp_rib_oc_path_unsupported = 155; // Skip setting prefix-set mode while configuring prefix-set routing-policy bool skip_prefix_set_mode = 156; + // Devices set metric as preference for static next-hop + bool set_metric_as_preference = 157; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 6b40c400684..f9879af2e15 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v3.14.0 +// protoc-gen-go v1.32.0 +// protoc v3.21.12 // source: metadata.proto package metadata_go_proto @@ -715,6 +715,8 @@ type Metadata_Deviations struct { BgpRibOcPathUnsupported bool `protobuf:"varint,155,opt,name=bgp_rib_oc_path_unsupported,json=bgpRibOcPathUnsupported,proto3" json:"bgp_rib_oc_path_unsupported,omitempty"` // Skip setting prefix-set mode while configuring prefix-set routing-policy SkipPrefixSetMode bool `protobuf:"varint,156,opt,name=skip_prefix_set_mode,json=skipPrefixSetMode,proto3" json:"skip_prefix_set_mode,omitempty"` + // Devices set metric as preference for static next-hop + SetMetricAsPreference bool `protobuf:"varint,157,opt,name=set_metric_as_preference,json=setMetricAsPreference,proto3" json:"set_metric_as_preference,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1729,6 +1731,13 @@ func (x *Metadata_Deviations) GetSkipPrefixSetMode() bool { return false } +func (x *Metadata_Deviations) GetSetMetricAsPreference() bool { + if x != nil { + return x.SetMetricAsPreference + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1792,7 +1801,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xea, 0x56, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x57, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1823,7 +1832,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xeb, 0x4e, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xa5, 0x4f, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2450,44 +2459,48 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x9c, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, - 0x69, 0x70, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x4a, - 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, - 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, - 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, - 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, - 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, - 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, - 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, - 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, - 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, - 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, - 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, - 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, - 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, - 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, - 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, - 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, - 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, - 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, - 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x70, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, + 0x38, 0x0a, 0x18, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x61, 0x73, + 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x9d, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x15, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x73, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, + 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, + 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, + 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, + 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, + 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, + 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, + 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, + 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, + 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, + 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, + 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, + 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, + 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, + 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, + 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, + 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, + 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From a38856e0e3e0e23beca53369dcb6e2c2d0b7c278 Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Mon, 18 Mar 2024 11:55:33 -0400 Subject: [PATCH 27/97] Cleanup featureprofiles static analysis errors (#2819) * Cleanup featureprofiles static analysis errors. * added .test file by mistake * fix tests --- .../gnmi_sample_mode_test.go | 10 +++---- .../zr_fec_uncorrectable_frames_test.go | 8 +++--- .../zr_laser_bias_current_test.go | 26 ++++++++--------- .../zr_logical_channels_test.go | 4 +-- .../zr_low_power_mode_test.go | 20 ++++++------- .../tests/zr_pm_test/zr_pm_test.go | 2 +- .../zr_supply_voltage_test.go | 20 ++++++------- .../zr_temperature_test.go | 28 +++++++++---------- .../zr_tunable_parameters_test.go | 14 +++++----- internal/cntrsrv/cntrsrv.go | 2 +- internal/cntrsrv/cntrsrv_test.go | 4 +-- internal/samplestream/samplestream.go | 8 +++--- 12 files changed, 73 insertions(+), 73 deletions(-) diff --git a/feature/gnmi/subscribe/tests/gnmi_sample_mode_test/gnmi_sample_mode_test.go b/feature/gnmi/subscribe/tests/gnmi_sample_mode_test/gnmi_sample_mode_test.go index 3882ee875b0..1b31e0a73d4 100644 --- a/feature/gnmi/subscribe/tests/gnmi_sample_mode_test/gnmi_sample_mode_test.go +++ b/feature/gnmi/subscribe/tests/gnmi_sample_mode_test/gnmi_sample_mode_test.go @@ -35,7 +35,7 @@ func TestGNMISampleMode(t *testing.T) { p1Stream := samplestream.New(t, dut, gnmi.OC().Interface(p1.Name()).Description().State(), 10*time.Second) defer p1Stream.Close() - desc := p1Stream.Next(t) + desc := p1Stream.Next() if desc == nil { t.Errorf("Interface %q telemetry not received before config", p1.Name()) } else { @@ -48,7 +48,7 @@ func TestGNMISampleMode(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) - desc = p1Stream.Next(t) + desc = p1Stream.Next() if desc == nil { t.Errorf("Interface %q telemetry not received after config", p1.Name()) } else { @@ -64,7 +64,7 @@ func TestGNMISampleMode(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Description().Config(), "DUT Port 1 - Updated") - desc = p1Stream.Next(t) + desc = p1Stream.Next() if desc == nil { t.Errorf("Interface %q telemetry not received after description update", p1.Name()) } else { @@ -108,7 +108,7 @@ func TestNoInvalidValuesOnInterfaceFlap(t *testing.T) { time.Sleep(10 * time.Second) // wait 10 seconds for at-least 1 stream value. // Now validate description stream didn't return any invalid values. - vals := p1Stream.All(t) + vals := p1Stream.All() for idx, v := range vals { if v, ok := v.Val(); !ok { @@ -133,7 +133,7 @@ func TestISISProtocol(t *testing.T) { // Starting ISIS protocol takes some time to converge. So we may not receive ISIS data // in the first sample after configuration. - samples := niStream.Nexts(t, 5) + samples := niStream.Nexts(5) updated := false for idx, sample := range samples { diff --git a/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go b/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go index 8a8ac84dfbc..2779d56a4d6 100644 --- a/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go +++ b/feature/platform/transceiver/tests/zr_fec_uncorrectable_frames_test/zr_fec_uncorrectable_frames_test.go @@ -38,8 +38,8 @@ func TestMain(m *testing.M) { fptest.RunTests(m) } -func validateFecUncorrectableBlocks(t *testing.T, dut *ondatra.DUTDevice, stream *samplestream.SampleStream[uint64]) { - fecStream := stream.Next(t) +func validateFecUncorrectableBlocks(t *testing.T, stream *samplestream.SampleStream[uint64]) { + fecStream := stream.Next() if fecStream == nil { t.Fatalf("Fec Uncorrectable Blocks was not streamed in the most recent subscription interval") } @@ -79,13 +79,13 @@ func TestZrUncorrectableFrames(t *testing.T) { streamFec := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(0).Otn().FecUncorrectableBlocks().State(), sampleInterval) defer streamFec.Close() - validateFecUncorrectableBlocks(t, dut, streamFec) + validateFecUncorrectableBlocks(t, streamFec) // Toggle interface enabled gnmi.Update(t, dut, gnmi.OC().Interface(dp.Name()).Enabled().Config(), bool(false)) gnmi.Update(t, dut, gnmi.OC().Interface(dp.Name()).Enabled().Config(), bool(true)) - validateFecUncorrectableBlocks(t, dut, streamFec) + validateFecUncorrectableBlocks(t, streamFec) }) } } diff --git a/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go b/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go index 57278323887..0044d117154 100644 --- a/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go +++ b/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go @@ -43,8 +43,8 @@ func TestMain(m *testing.M) { // dut:port1 <--> port2:dut // -func verifyLaserBiasCurrent(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[float64], sensorName string) float64 { - laserBias := pStream.Next(t) +func verifyLaserBiasCurrent(t *testing.T, pStream *samplestream.SampleStream[float64], sensorName string) float64 { + laserBias := pStream.Next() if laserBias == nil { t.Fatalf("laserBias telemetry %q was not streamed in the most recent subscription interval", sensorName) } @@ -62,14 +62,14 @@ func verifyLaserBiasCurrent(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samp return laserBiasVal } -func verifyLaserBiasCurrentAll(t *testing.T, dut1 *ondatra.DUTDevice, pStreamInstant *samplestream.SampleStream[float64], pStreamAvg *samplestream.SampleStream[float64], pStreamMax *samplestream.SampleStream[float64], pStreamMin *samplestream.SampleStream[float64]) { - laserbiasInstant := verifyLaserBiasCurrent(t, dut1, pStreamInstant, "laserbiasInstant") +func verifyLaserBiasCurrentAll(t *testing.T, pStreamInstant *samplestream.SampleStream[float64], pStreamAvg *samplestream.SampleStream[float64], pStreamMax *samplestream.SampleStream[float64], pStreamMin *samplestream.SampleStream[float64]) { + laserbiasInstant := verifyLaserBiasCurrent(t, pStreamInstant, "laserbiasInstant") t.Logf("laserBias Instant value: %f", laserbiasInstant) - laserbiasMin := verifyLaserBiasCurrent(t, dut1, pStreamMin, "laserbiasMin") + laserbiasMin := verifyLaserBiasCurrent(t, pStreamMin, "laserbiasMin") t.Logf("laserBias Min value: %f", laserbiasMin) - laserbiasMax := verifyLaserBiasCurrent(t, dut1, pStreamMax, "laserbiasMax") + laserbiasMax := verifyLaserBiasCurrent(t, pStreamMax, "laserbiasMax") t.Logf("laserBias Max value: %f", laserbiasMax) - laserbiasAvg := verifyLaserBiasCurrent(t, dut1, pStreamAvg, "laserbiasAvg") + laserbiasAvg := verifyLaserBiasCurrent(t, pStreamAvg, "laserbiasAvg") t.Logf("laserBias Avg value: %f", laserbiasAvg) if laserbiasAvg >= laserbiasMin && laserbiasAvg <= laserbiasMax { t.Logf("The average is between the maximum and minimum values") @@ -113,7 +113,7 @@ func TestZRLaserBiasCurrentState(t *testing.T) { defer p1StreamMax.Close() defer p1StreamMin.Close() defer p1StreamInstant.Close() - verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) } func TestZRLaserBiasCurrentStateInterface_Flap(t *testing.T) { dut1 := ondatra.DUT(t, "dut") @@ -147,15 +147,15 @@ func TestZRLaserBiasCurrentStateInterface_Flap(t *testing.T) { defer p1StreamMin.Close() defer p1StreamMax.Close() defer p1StreamAvg.Close() - verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) // Wait 120 sec cooling off period gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_DOWN) // Enable interface - verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) i.Enabled = ygot.Bool(true) gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Config(), i) gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) - verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) } func TestZRLaserBiasCurrentStateTransceiverOnOff(t *testing.T) { dut1 := ondatra.DUT(t, "dut") @@ -184,11 +184,11 @@ func TestZRLaserBiasCurrentStateTransceiverOnOff(t *testing.T) { defer p1StreamAvg.Close() // Disable interface transceiver power off gnmi.Update(t, dut1, gnmi.OC().Component(dp1.Name()).Transceiver().Enabled().Config(), false) - verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) // Enable interface transceiver power on gnmi.Update(t, dut1, gnmi.OC().Component(dp1.Name()).Transceiver().Enabled().Config(), true) gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) - verifyLaserBiasCurrentAll(t, dut1, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) + verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin) } func opticalChannelComponentFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { t.Helper() diff --git a/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go b/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go index 97a810089c7..5ca9be69189 100644 --- a/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go +++ b/feature/platform/transceiver/tests/zr_logical_channels_test/zr_logical_channels_test.go @@ -122,7 +122,7 @@ func configureLogicalChannels(t *testing.T, dut *ondatra.DUTDevice, ethernetChId } func validateEthernetChannelTelemetry(t *testing.T, ethernetChIdx, coherentChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { - val := stream.Next(t) // value received in the gnmi subscription within 10 seconds + val := stream.Next() // value received in the gnmi subscription within 10 seconds if val == nil { t.Fatalf("Ethernet Channel telemetry stream not received in last 10 seconds") } @@ -201,7 +201,7 @@ func validateEthernetChannelTelemetry(t *testing.T, ethernetChIdx, coherentChIdx } func validateCoherentChannelTelemetry(t *testing.T, coherentChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { - val := stream.Next(t) // value received in the gnmi subscription within 10 seconds + val := stream.Next() // value received in the gnmi subscription within 10 seconds if val == nil { t.Fatalf("Coherent Channel telemetry stream not received in last 10 seconds") } diff --git a/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go b/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go index 47c6ea4e1c4..4d655bdd815 100644 --- a/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go +++ b/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go @@ -40,9 +40,9 @@ func TestMain(m *testing.M) { } // validateStreamOutput validates that the OC path is streamed in the most recent subscription interval. -func validateStreamOutput(t *testing.T, dut *ondatra.DUTDevice, streams map[string]*samplestream.SampleStream[string]) { +func validateStreamOutput(t *testing.T, streams map[string]*samplestream.SampleStream[string]) { for key, stream := range streams { - output := stream.Next(t) + output := stream.Next() if output == nil { t.Fatalf("OC path for %s not streamed in the most recent subscription interval", key) } @@ -61,9 +61,9 @@ func validateStreamOutput(t *testing.T, dut *ondatra.DUTDevice, streams map[stri } // validateOutputPower validates that the output power is streamed in the most recent subscription interval. -func validateOutputPower(t *testing.T, dut *ondatra.DUTDevice, streams map[string]*samplestream.SampleStream[float64]) { +func validateOutputPower(t *testing.T, streams map[string]*samplestream.SampleStream[float64]) { for key, stream := range streams { - outputStream := stream.Next(t) + outputStream := stream.Next() if outputStream == nil { t.Fatalf("OC path for %s not streamed in the most recent subscription interval", key) } @@ -118,11 +118,11 @@ func TestLowPowerMode(t *testing.T) { "hwVersion": streamHwVersion, "firmwareVersion": streamFirmwareVersion, } - validateStreamOutput(t, dut, allStream) + validateStreamOutput(t, allStream) opInst := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Instant().State(), samplingInterval) defer opInst.Close() - if opInstN := opInst.Next(t); opInstN != nil { + if opInstN := opInst.Next(); opInstN != nil { if _, ok := opInstN.Val(); ok { t.Fatalf("streaming /components/component/optical-channel/state/output-power/instant is not expected to be reported") } @@ -130,7 +130,7 @@ func TestLowPowerMode(t *testing.T) { opAvg := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Avg().State(), samplingInterval) defer opAvg.Close() - if opAvgN := opAvg.Next(t); opAvgN != nil { + if opAvgN := opAvg.Next(); opAvgN != nil { if _, ok := opAvgN.Val(); ok { t.Fatalf("streaming /components/component/optical-channel/state/output-power/avg is not expected to be reported") } @@ -138,7 +138,7 @@ func TestLowPowerMode(t *testing.T) { opMin := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Min().State(), samplingInterval) defer opMin.Close() - if opMinN := opMin.Next(t); opMinN != nil { + if opMinN := opMin.Next(); opMinN != nil { if _, ok := opMinN.Val(); ok { t.Fatalf("streaming /components/component/optical-channel/state/output-power/min is not expected to be reported") } @@ -146,7 +146,7 @@ func TestLowPowerMode(t *testing.T) { opMax := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Max().State(), samplingInterval) defer opMax.Close() - if opMaxN := opMax.Next(t); opMaxN != nil { + if opMaxN := opMax.Next(); opMaxN != nil { if _, ok := opMaxN.Val(); ok { t.Fatalf("streaming /components/component/optical-channel/state/output-power/max is not expected to be reported") } @@ -161,7 +161,7 @@ func TestLowPowerMode(t *testing.T) { "max": opMax, } - validateOutputPower(t, dut, powerStreamMap) + validateOutputPower(t, powerStreamMap) // Derive transceiver names from ports. component := gnmi.OC().Component(tr) diff --git a/feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go b/feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go index e505e600139..f4d86199a35 100644 --- a/feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go +++ b/feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go @@ -136,7 +136,7 @@ func TestPM(t *testing.T) { // Now validate OTN streams didn't return any invalid values. for portName, stream := range otnStreams { var linkStates []oc.E_Channel_LinkState - for _, val := range stream.All(t) { + for _, val := range stream.All() { linkStates = append(linkStates, validateStream(t, val, portName)) } validateLinkStateTransitions(t, linkStates, portName) diff --git a/feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go b/feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go index 8ec0640deca..39497170da3 100644 --- a/feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go +++ b/feature/platform/transceiver/tests/zr_supply_voltage_test/zr_supply_voltage_test.go @@ -38,8 +38,8 @@ func TestMain(m *testing.M) { fptest.RunTests(m) } -func verifyVoltageValue(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[float64], path string) float64 { - voltageSample := pStream.Next(t) +func verifyVoltageValue(t *testing.T, pStream *samplestream.SampleStream[float64], path string) float64 { + voltageSample := pStream.Next() if voltageSample == nil { t.Fatalf("Voltage telemetry %s was not streamed in the most recent subscription interval", path) } @@ -87,13 +87,13 @@ func TestZrSupplyVoltage(t *testing.T) { streamMax := samplestream.New(t, dut, component.Transceiver().SupplyVoltage().Max().State(), samplingInterval) defer streamMax.Close() - volInst := verifyVoltageValue(t, dut, streamInst, "Instant") + volInst := verifyVoltageValue(t, streamInst, "Instant") t.Logf("Port %s instant voltage: %v", dp.Name(), volInst) - volAvg := verifyVoltageValue(t, dut, streamAvg, "Avg") + volAvg := verifyVoltageValue(t, streamAvg, "Avg") t.Logf("Port %s average voltage: %v", dp.Name(), volAvg) - volMin := verifyVoltageValue(t, dut, streamMin, "Min") + volMin := verifyVoltageValue(t, streamMin, "Min") t.Logf("Port %s minimum voltage: %v", dp.Name(), volMin) - volMax := verifyVoltageValue(t, dut, streamMax, "Max") + volMax := verifyVoltageValue(t, streamMax, "Max") t.Logf("Port %s maximum voltage: %v", dp.Name(), volMax) if volAvg >= volMin && volAvg <= volMax { @@ -105,13 +105,13 @@ func TestZrSupplyVoltage(t *testing.T) { // Wait for the cooling off period gnmi.Await(t, dut, gnmi.OC().Interface(dp.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_DOWN) - volInstNew := verifyVoltageValue(t, dut, streamInst, "Instant") + volInstNew := verifyVoltageValue(t, streamInst, "Instant") t.Logf("Port %s instant voltage after port down: %v", dp.Name(), volInstNew) - volAvgNew := verifyVoltageValue(t, dut, streamAvg, "Avg") + volAvgNew := verifyVoltageValue(t, streamAvg, "Avg") t.Logf("Port %s average voltage after port down: %v", dp.Name(), volAvgNew) - volMinNew := verifyVoltageValue(t, dut, streamMin, "Min") + volMinNew := verifyVoltageValue(t, streamMin, "Min") t.Logf("Port %s minimum voltage after port down: %v", dp.Name(), volMinNew) - volMaxNew := verifyVoltageValue(t, dut, streamMax, "Max") + volMaxNew := verifyVoltageValue(t, streamMax, "Max") t.Logf("Port %s maximum voltage after port down: %v", dp.Name(), volMaxNew) if volAvgNew >= volMinNew && volAvgNew <= volMaxNew { diff --git a/feature/platform/transceiver/tests/zr_temperature_test/zr_temperature_test.go b/feature/platform/transceiver/tests/zr_temperature_test/zr_temperature_test.go index f9e85189ef8..a3850f1cb7b 100644 --- a/feature/platform/transceiver/tests/zr_temperature_test/zr_temperature_test.go +++ b/feature/platform/transceiver/tests/zr_temperature_test/zr_temperature_test.go @@ -56,8 +56,8 @@ func interfaceConfig(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port) { Frequency: ygot.Uint64(frequency), }) } -func verifyTemperatureSensorValue(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[float64], sensorName string) float64 { - temperatureSample := pStream.Next(t) +func verifyTemperatureSensorValue(t *testing.T, pStream *samplestream.SampleStream[float64], sensorName string) float64 { + temperatureSample := pStream.Next() if temperatureSample == nil { t.Fatalf("Temperature telemetry %s was not streamed in the most recent subscription interval", sensorName) } @@ -108,13 +108,13 @@ func TestZRTemperatureState(t *testing.T) { p1StreamAvg := samplestream.New(t, dut1, component1.Temperature().Avg().State(), 10*time.Second) p1StreamMin := samplestream.New(t, dut1, component1.Temperature().Min().State(), 10*time.Second) p1StreamMax := samplestream.New(t, dut1, component1.Temperature().Max().State(), 10*time.Second) - temperatureInstant := verifyTemperatureSensorValue(t, dut1, p1StreamInstant, "Instant") + temperatureInstant := verifyTemperatureSensorValue(t, p1StreamInstant, "Instant") t.Logf("Port1 dut1 %s Instant Temperature: %v", dp1.Name(), temperatureInstant) - temperatureMax := verifyTemperatureSensorValue(t, dut1, p1StreamMax, "Max") + temperatureMax := verifyTemperatureSensorValue(t, p1StreamMax, "Max") t.Logf("Port1 dut1 %s Max Temperature: %v", dp1.Name(), temperatureMax) - temperatureMin := verifyTemperatureSensorValue(t, dut1, p1StreamMin, "Min") + temperatureMin := verifyTemperatureSensorValue(t, p1StreamMin, "Min") t.Logf("Port1 dut1 %s Min Temperature: %v", dp1.Name(), temperatureMin) - temperatureAvg := verifyTemperatureSensorValue(t, dut1, p1StreamAvg, "Avg") + temperatureAvg := verifyTemperatureSensorValue(t, p1StreamAvg, "Avg") t.Logf("Port1 dut1 %s Avg Temperature: %v", dp1.Name(), temperatureAvg) if temperatureAvg >= temperatureMin && temperatureAvg <= temperatureMax { t.Logf("The average is between the maximum and minimum values") @@ -166,13 +166,13 @@ func TestZRTemperatureStateInterfaceFlap(t *testing.T) { p1StreamMax := samplestream.New(t, dut1, component1.Temperature().Max().State(), 10*time.Second) // Wait 120 sec cooling off period gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_DOWN) - temperatureInstant := verifyTemperatureSensorValue(t, dut1, p1StreamInstant, "Instant") + temperatureInstant := verifyTemperatureSensorValue(t, p1StreamInstant, "Instant") t.Logf("Port1 dut1 %s Instant Temperature: %v", dp1.Name(), temperatureInstant) - temperatureMax := verifyTemperatureSensorValue(t, dut1, p1StreamMax, "Max") + temperatureMax := verifyTemperatureSensorValue(t, p1StreamMax, "Max") t.Logf("Port1 dut1 %s Max Temperature: %v", dp1.Name(), temperatureMax) - temperatureMin := verifyTemperatureSensorValue(t, dut1, p1StreamMin, "Min") + temperatureMin := verifyTemperatureSensorValue(t, p1StreamMin, "Min") t.Logf("Port1 dut1 %s Min Temperature: %v", dp1.Name(), temperatureMin) - temperatureAvg := verifyTemperatureSensorValue(t, dut1, p1StreamAvg, "Avg") + temperatureAvg := verifyTemperatureSensorValue(t, p1StreamAvg, "Avg") t.Logf("Port1 dut1 %s Avg Temperature: %v", dp1.Name(), temperatureAvg) i = d.GetOrCreateInterface(dp1.Name()) i.Enabled = ygot.Bool(true) @@ -180,13 +180,13 @@ func TestZRTemperatureStateInterfaceFlap(t *testing.T) { // Enable interface gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Config(), i) gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) - temperatureInstant = verifyTemperatureSensorValue(t, dut1, p1StreamInstant, "Instant") + temperatureInstant = verifyTemperatureSensorValue(t, p1StreamInstant, "Instant") t.Logf("Port1 dut1 %s Instant Temperature: %v", dp1.Name(), temperatureInstant) - temperatureMax = verifyTemperatureSensorValue(t, dut1, p1StreamMax, "Max") + temperatureMax = verifyTemperatureSensorValue(t, p1StreamMax, "Max") t.Logf("Port1 dut1 %s Max Temperature: %v", dp1.Name(), temperatureMax) - temperatureMin = verifyTemperatureSensorValue(t, dut1, p1StreamMin, "Min") + temperatureMin = verifyTemperatureSensorValue(t, p1StreamMin, "Min") t.Logf("Port1 dut1 %s Min Temperature: %v", dp1.Name(), temperatureMin) - temperatureAvg = verifyTemperatureSensorValue(t, dut1, p1StreamAvg, "Avg") + temperatureAvg = verifyTemperatureSensorValue(t, p1StreamAvg, "Avg") t.Logf("Port1 dut1 %s Avg Temperature: %v", dp1.Name(), temperatureAvg) if temperatureAvg >= temperatureMin && temperatureAvg <= temperatureMax { t.Logf("The average is between the maximum and minimum values") diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go index 079425dbc76..96f356df552 100644 --- a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go @@ -90,7 +90,7 @@ func Test400ZRTunableFrequency(t *testing.T) { Frequency: ygot.Uint64(freq), OperationalMode: ygot.Uint16(dp16QAM), }) - validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, freq, tc.targetOutputPower) + validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, freq, tc.targetOutputPower) }) } }) @@ -140,7 +140,7 @@ func Test400ZRTunableOutputPower(t *testing.T) { Frequency: ygot.Uint64(tc.frequency), OperationalMode: ygot.Uint16(dp16QAM), }) - validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, tc.frequency, top) + validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, tc.frequency, top) }) } } @@ -171,7 +171,7 @@ func Test400ZRInterfaceFlap(t *testing.T) { OperationalMode: ygot.Uint16(dp16QAM), }) t.Run("Telemetry before flap", func(t *testing.T) { - validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) + validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) }) // Disable or shut down the interface on the DUT. gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Enabled().Config(), false) @@ -181,7 +181,7 @@ func Test400ZRInterfaceFlap(t *testing.T) { // Verify for the TX output power with interface in down state a decimal64 // value of -40 dB is streamed. t.Run("Telemetry during interface disabled", func(t *testing.T) { - validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, 0, -40) + validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, 0, -40) }) // Re-enable the interfaces on the DUT. gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Enabled().Config(), true) @@ -192,13 +192,13 @@ func Test400ZRInterfaceFlap(t *testing.T) { // power as per the configuration and related telemetry values are updated // to the value in the normal range again. t.Run("Telemetry after flap", func(t *testing.T) { - validateOpticsTelemetry(t, dut, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) + validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) }) } -func validateOpticsTelemetry(t *testing.T, dut *ondatra.DUTDevice, streams []*samplestream.SampleStream[*oc.Component], frequency uint64, outputPower float64) { +func validateOpticsTelemetry(t *testing.T, streams []*samplestream.SampleStream[*oc.Component], frequency uint64, outputPower float64) { var ocs []*oc.Component_OpticalChannel for _, s := range streams { - val := s.Next(t) + val := s.Next() if val == nil { t.Fatal("Optical channel streaming telemetry not received") } diff --git a/internal/cntrsrv/cntrsrv.go b/internal/cntrsrv/cntrsrv.go index 74ce925e22a..ed51d122ed2 100644 --- a/internal/cntrsrv/cntrsrv.go +++ b/internal/cntrsrv/cntrsrv.go @@ -76,7 +76,7 @@ type rpcCredentials struct { *creds.UserPass } -func (r *rpcCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { +func (r *rpcCredentials) GetRequestMetadata(context.Context, ...string) (map[string]string, error) { return map[string]string{ "username": "admin", "password": "admin", diff --git a/internal/cntrsrv/cntrsrv_test.go b/internal/cntrsrv/cntrsrv_test.go index 19a2f9274e2..e4f41913aed 100644 --- a/internal/cntrsrv/cntrsrv_test.go +++ b/internal/cntrsrv/cntrsrv_test.go @@ -98,7 +98,7 @@ type gRIBIServer struct { *spb.UnimplementedGRIBIServer } -func (g *gRIBIServer) Get(req *spb.GetRequest, stream spb.GRIBI_GetServer) error { +func (g *gRIBIServer) Get(_ *spb.GetRequest, stream spb.GRIBI_GetServer) error { if err := stream.Send(&spb.GetResponse{}); err != nil { return status.Errorf(codes.Internal, "can't send") } @@ -127,7 +127,7 @@ type gNMIServer struct { *gpb.UnimplementedGNMIServer } -func (g *gNMIServer) Capabilities(ctx context.Context, req *gpb.CapabilityRequest) (*gpb.CapabilityResponse, error) { +func (g *gNMIServer) Capabilities(context.Context, *gpb.CapabilityRequest) (*gpb.CapabilityResponse, error) { return &gpb.CapabilityResponse{ GNMIVersion: "demo", }, nil diff --git a/internal/samplestream/samplestream.go b/internal/samplestream/samplestream.go index da762a38135..b65c02ca5d8 100644 --- a/internal/samplestream/samplestream.go +++ b/internal/samplestream/samplestream.go @@ -53,7 +53,7 @@ func New[T any](t *testing.T, dut *ondatra.DUTDevice, q ygnmi.SingletonQuery[T], // Next returns the next sample received within the sample interval. // If no sample is received within the interval, nil is returned. -func (s *SampleStream[T]) Next(t *testing.T) *ygnmi.Value[T] { +func (s *SampleStream[T]) Next() *ygnmi.Value[T] { func() { s.dataMu.Lock() defer s.dataMu.Unlock() @@ -73,16 +73,16 @@ func (s *SampleStream[T]) Next(t *testing.T) *ygnmi.Value[T] { } // Nexts calls Next() count times and returns the slice of returned samples. -func (s *SampleStream[T]) Nexts(t *testing.T, count int) []*ygnmi.Value[T] { +func (s *SampleStream[T]) Nexts(count int) []*ygnmi.Value[T] { var nexts []*ygnmi.Value[T] for i := 0; i < count; i++ { - nexts = append(nexts, s.Next(t)) + nexts = append(nexts, s.Next()) } return nexts } // All returns the list of values that has been received thus far. -func (s *SampleStream[T]) All(t *testing.T) []*ygnmi.Value[T] { +func (s *SampleStream[T]) All() []*ygnmi.Value[T] { s.dataMu.Lock() defer s.dataMu.Unlock() return s.data From f4507c23a381a000351a345a28eb83e3f1a95120 Mon Sep 17 00:00:00 2001 From: Rob Shakir Date: Mon, 18 Mar 2024 10:14:16 -0700 Subject: [PATCH 28/97] Add TE-16.2 to testregistry.textproto. (#2818) Co-authored-by: Darren Loher --- testregistry.textproto | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testregistry.textproto b/testregistry.textproto index 3e815276597..88819754859 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -1043,6 +1043,11 @@ test: { description: "gRIBI MPLS Forwarding" readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/mpls_forwarding/README.md" } +test: { + id: "TE-16.2" + description: "gRIBI encapsulation FRR scenarios" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/encap_frr/README.md" +} test: { id: "TR-6.1" description: "system logging remote syslog" From 6aca6d676a72a51a0e0589b8c53cd1e2b3e4c134 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Mon, 18 Mar 2024 15:26:51 -0700 Subject: [PATCH 29/97] RT-7.11 README for multi-criteria BGP route policy (#2746) * add registry and body * define policy rough draft * try yaml formatting for path list * Defined paths and policies * add expected results * fix comm name * add export policy * Break out config and validation in separate subtests * define accept policy for test environment setup verification Co-authored-by: rszarecki <46606165+rszarecki@users.noreply.github.com> * revise numbering, break out steps for config vs. validation --------- Co-authored-by: rszarecki <46606165+rszarecki@users.noreply.github.com> --- .../otg_tests/import_export_multi/README.md | 239 ++++++++++++++++++ .../import_export_multi/metadata.textproto | 7 + testregistry.textproto | 6 + 3 files changed, 252 insertions(+) create mode 100644 feature/bgp/policybase/otg_tests/import_export_multi/README.md create mode 100644 feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/README.md b/feature/bgp/policybase/otg_tests/import_export_multi/README.md new file mode 100644 index 00000000000..824872838f2 --- /dev/null +++ b/feature/bgp/policybase/otg_tests/import_export_multi/README.md @@ -0,0 +1,239 @@ +# RT-7.11: BGP Policy - Import/Export Policy Action Using Multiple Criteria + +## Summary + +The purpose of this test is to verify a combination of bgp conditions using +matching and policy nesting as well as and actions in a single BGP import +policy. Additional combinations may be added in the future as additonal +subtests. + +## Testbed type + +* [2 port ATE to DUT](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed) + +## Testbed common configuration + +This configuration initializes the testbed with configurations that are a +pre-requisite for the test. This configuration should not be part of the test +functions. + +* Testbed configuration - Setup eBGP sessions and prefixes + * Generate config for 2 DUT and ATE ports where + * DUT port 1 connects to ATE port 1. + * DUT port 2 connects to ATE port 2. + * Configure ATE port 1 with an external type BGP session to DUT port 1 + * DUT ASN 65000 + * ATE port 1 ASN 65100 + * ATE port 2 ASN 65200 + * Advertise ipv4 and ipv6 prefixes from ATE port 1 to DUT port 1 using + the following communities: + * prefix-set-1 with 2 ipv4 and 2 ipv6 routes with communities [ "10:1" ] + * prefix-set-2 with 2 ipv4 and 2 ipv6 routes with communities [ "20:1" ] + * prefix-set-3 with 2 ipv4 and 2 ipv6 routes with communities [ "30:1" ] + * prefix-set-4 with 2 ipv4 and 2 ipv6 routes with communities [ "20:2", "30:3" ] + * prefix-set-5 with 2 ipv4 and 2 ipv6 routes with communities [ "40:1" ] + * prefix-set-6 with 2 ipv4 and 2 ipv6 routes with communities [ "50:1" ] + * Configure accept_all policy + * Create policy-definitions/policy-definition/config/name = "accept_all" + * statements/statement/config/name = "accept" + * actions/config/policy-result = "ACCEPT_ROUTE" + * apply as an export and import policy on the DUT + eBGP session to ATE port 1 and port 2. + +* Configure the following community sets on the DUT: + * /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config + * name = "reject_communities" + * community-member = [ "10:1" ] + * name = "accept_communities" + * community-member = [ "20:1" ] + * name = "regex_community" + * community-member = [ "^30:.*$" ] + * name = "add_communities" + * community-member = [ "40:1", "40:2" ] + * name "my_community" + * community-member = [ "50:1" ] + * name = "add_comm_60" + * community-member = [ "60:1" ] + * name = "add_comm_70" + * community-member = [ "70:1" ] + +* Create an as-path-set on the DUT as follows + * /routing-policy/defined-sets/bgp-defined-sets/as-path-sets/as-path-set/config/ + * as-path-set-name = "my_aspath" + * as-path-set-member = "65100" + +* Validate bgp sessions and traffic + * For IPv4 and IPv6 prefixes: + * Observe received prefixes at ATE port-2. + * Generate traffic from ATE port-2 to ATE port-1. + * Validate + * Traffic can be received on ATE port-1 for all installed routes. + * Communities on ATE Port 2 are equal to those sent by ATE Port1 + * as-path shall be "65100 65000" + * Local-Preference should be not present + * MED should be not present + +## Procedure + +### RT-7.11.1 - Create a bgp policy containing the following conditions and actions + +* Summary of this policy + * Reject route matching any communities in a community-set. + * Reject route matching another policy (nested) and not matching a community-set. + * Add a community-set if missing that same community-set. + * Add two communities and set localpref if matching a community and prefix-set. + * Set MED if matching an aspath + +* Define a policy that will be called from another policy + * policy-definitions/policy-definition/config/name: "match_community_regex" + * statements/statement/config/name: "match_community_regex" + * conditions/bgp-conditions/match-community-set/config/ + * community-set: "regex-community" + * match-set-options: "ANY" + * actions/config/policy-result = "NEXT_STATEMENT" + +* Create policy-definitions/policy-definition/config/name = "multi_policy" + * statements/statement/config/name = "reject_route_community" + * conditions/bgp-conditions/match-community-set/config + * community-set = "reject_communities" + * match-set-options = "ANY" + * actions/config/policy-result = "REJECT_ROUTE" + + * statements/statement/config/name = "if_30:.*_and_not_20:1_nested_reject" + * conditions/config/call-policy = "match_community_regex" + * conditions/bgp-conditions/match-community-set/config/ + * community-set = "accept_communities" + * match-set-options = "INVERT" + * actions/config/policy-result = "REJECT_ROUTE" + + * statements/statement/config/name = "add_communities_if_missing" + * conditions/bgp-conditions/match-community-set/config/ + * community-set-refs = "add-communities" + * match-set-options: "INVERT" + * actions/bgp-actions/set-community/reference/config/ + * community-set-refs = "add-communities" + * method = "REFERENCE" + * option = "ADD" + * actions/config/policy-result = "NEXT_STATEMENT" + + * statements/statement/config/name: "match_comm_and_prefix_add_2_community_sets" + * conditions/bgp-conditions/match-community-set/config + * community-set = "my_community" + * match-set-options = "ANY" + * conditions/match-prefix-set/config + * prefix-set = "prefix-set-5" + * match-set-options = "ANY" + * actions/bgp-actions/set-community/config + * method = "REFERENCE" + * option = "ADD" + * community-set-refs = "add_comm_60", "add_comm_70" + * actions/bgp-actions/config/set-local-pref = 5 + * actions/config/policy-result = "NEXT_STATEMENT" + + * statements/statement/config/name: "match_aspath_set_med" + * conditions/bgp-conditions/match-as-path-set/config/ + * as-path-set = "my_aspath" + * match-set-options = "ANY" + * actions/bgp-actions/config/ + * set-med = 100 + * actions/config/policy-result = "ACCEPT_ROUTE" + +* Use gnmi Set REPLACE option to configure the policies above on the DUT at this subtree level: + * `/routing-policy/policy-definitions` + +#### RT-7.11.2 Attach multi_policy as import policy + +* Use gnmi Set REPLACE option to apply the policy on the DUT bgp neighbor to the ATE port 1. + * at this subtree level: /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy + * Set the value `config/import-policy` = "multi-policy" + +#### RT-7.11.3 Verify import_multi_policy expected attributes are present + +* Verify expected attributes are present in ATE. + +> NOTE: (At the time of writing, the APIs necesary to do this validation are not yet available via the OTG API. A feature enhancement has been submitted.) + +#### RT-7.11.4 Configure export_multi_policy + +This replace method should guarantee that the previous step's import-policy is removed. + +* Use gnmi Set REPLACE option to apply the policy on the DUT bgp neighbor to the ATE port 1. + * at this subtree level: /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy + * Set the value `config/export-policy` = "multi-policy" + +#### RT-7.11.5 Verify export_multi_policy expected attributes are present + +* Verify expected attributes are present in ATE. + +#### Multi_policy results observed on ATE port 2 for both import and export cases + + | | Received | Communities | as-path | lpref | med | Notes | + | ------------ | -------- | --------------------------------- | ----------- | ----- | --- | --------------------------------------------------------- | + | prefix-set-1 | False | n/a | n/a | n/a | n/a | rejected by statement reject_route_community | + | prefix-set-2 | True | [ "20:1", "40:1", "40:2" ] | 65000 65100 | n/a | 100 | accepted | + | prefix-set-3 | False | n/a | n/a | n/a | n/a | rejected by statement if_30:.*_and_not_20:1_nested_reject | + | prefix-set-4 | False | n/a | n/a | n/a | n/a | rejected by statement if_30:.*_and_not_20:1_nested_reject | + | prefix-set-5 | True | [ "40:1","40:2", "60:1", "70:1" ] | 65000 65100 | 5 | 100 | accepted and match_comm_and_prefix_add_2_community_sets | + | prefix-set-6 | True | [ "10:1", "40:1", "40:2" ] | 65000 65100 | n/a | 100 | accepted | + +## OpenConfig Path Coverage + +The below yaml defines the OC paths intended to be covered by this test. OC paths used for test setup are not listed here. + +```yaml +config_paths: + # Policy definition + - /routing-policy/policy-definitions/policy-definition/config/name + - /routing-policy/policy-definitions/policy-definition/statements/statement/config/name + + # Policy for community-set configuration + - /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/community-set-name + - /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/community-member + + # Policy for match configuration + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/community-set + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/match-set-options + + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-as-path-set/config/as-path-set + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-as-path-set/config/match-set-options + + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options + + # Policy for bgp actions + - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/config/method + - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/config/options + - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/reference/config/community-set-ref + - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/reference/config/community-set-refs + - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-local-pref + - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med + + # Policy for bgp attachment + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy + +state_paths: + # Policy definition state + - /routing-policy/policy-definitions/policy-definition/state/name + - /routing-policy/policy-definitions/policy-definition/statements/statement/state/name + + # Policy for community-set match state + - /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-set-name + - /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-member + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-ext-community-set/state/match-set-options + - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/state/community-set + + # Paths to verify policy state + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy + + # Paths to verify prefixes sent and received + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/sent + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received-pre-policy + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received + - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/installed +``` + +## Minimum DUT Required + +vRX - Virtual Router Device diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto b/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto new file mode 100644 index 00000000000..fdbbd48c5b7 --- /dev/null +++ b/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +plan_id: "RT-7.11" +description: "BGP Policy - Import/Export Policy Action Using Multiple Criteria" +testbed: TESTBED_DUT_ATE_2LINKS +tags: TAGS_AGGREGATION, TAGS_DATACENTER_EDGE diff --git a/testregistry.textproto b/testregistry.textproto index 88819754859..846fa782588 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -789,6 +789,12 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/policybase/otg_tests/comm_match_action_test/README.md" exec: " " } +test: { + id: "RT-7.11" + description: "RT-7.11: BGP Policy - Import/Export Policy Action Using Multiple Criteria" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/policybase/otg_tests/import-export-multi/README.md" + exec: " " +} test: { id: "RT-8" description: "Singleton with breakouts" From 0ac1e3f951a9694bbc2b141f9178c921b6c7dcb1 Mon Sep 17 00:00:00 2001 From: ahsaanyousaf <46231245+ahsaanyousaf@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:45:55 -0700 Subject: [PATCH 30/97] ADD a test to verify ZR optic firmware version (#2784) * ADD a test to verify ZR optic firmware version streaming telemetry --- .../metadata.textproto | 17 ++ .../zr_firmware_version_test.go | 148 ++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 feature/platform/transceiver/tests/zr_firmware_version_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go diff --git a/feature/platform/transceiver/tests/zr_firmware_version_test/metadata.textproto b/feature/platform/transceiver/tests/zr_firmware_version_test/metadata.textproto new file mode 100644 index 00000000000..0e66e1c9c2e --- /dev/null +++ b/feature/platform/transceiver/tests/zr_firmware_version_test/metadata.textproto @@ -0,0 +1,17 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "0f3bb528-28f4-4284-8d2f-de105be09241" +plan_id: "TRANSCEIVER-3" +description: "Telemetry: 400ZR Optics firmware version streaming" +testbed: TESTBED_DUT_400ZR +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + missing_port_to_optical_channel_component_mapping: true + } +} \ No newline at end of file diff --git a/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go b/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go new file mode 100644 index 00000000000..e8dc8d8b41a --- /dev/null +++ b/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go @@ -0,0 +1,148 @@ +// Copyright 2022 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 zr_firmware_version_test + +import ( + "fmt" + "reflect" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +const ( + dp16QAM = 1 + targetOutputPower = -10 + frequency = 193100000 +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// Topology: dut:port1 <--> port2:dut + +func configInterface(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port, enable bool) { + d := &oc.Root{} + i := d.GetOrCreateInterface(dp.Name()) + i.Enabled = ygot.Bool(enable) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp.Name()).Config(), i) + component := opticalChannelComponentFromPort(t, dut1, dp) + gnmi.Replace(t, dut1, gnmi.OC().Component(component).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(targetOutputPower), + Frequency: ygot.Uint64(frequency), + }) +} +func verifyFirmwareVersionValue(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[string]) { + firmwareVersionSample := pStream.Next(t) + if firmwareVersionSample == nil { + t.Fatalf("Firmware telemetry %v was not streamed in the most recent subscription interval", firmwareVersionSample) + } + firmwareVersionVal, ok := firmwareVersionSample.Val() + if !ok { + t.Fatalf("Firmware version %q telemetry is not present", firmwareVersionSample) + } + // Check firmware version return value of correct type + if reflect.TypeOf(firmwareVersionVal).Kind() != reflect.String { + t.Fatalf("Return value is not type string") + } +} + +func TestZRFirmwareVersionState(t *testing.T) { + dut1 := ondatra.DUT(t, "dut") + dp1 := dut1.Port(t, "port1") + dp2 := dut1.Port(t, "port2") + t.Logf("dut1: %v", dut1) + t.Logf("dut1 dp1 name: %v", dp1.Name()) + configInterface(t, dut1, dp1, true) + configInterface(t, dut1, dp2, true) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + transceiverName := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) + // Check if TRANSCEIVER is of type 400ZR + if dp1.PMD() != ondatra.PMD400GBASEZR { + t.Fatalf("%s Transceiver is not 400ZR its of type: %v", transceiverName, dp1.PMD()) + } + component1 := gnmi.OC().Component(transceiverName) + + p1Stream := samplestream.New(t, dut1, component1.FirmwareVersion().State(), 10*time.Second) + + verifyFirmwareVersionValue(t, dut1, p1Stream) + + p1Stream.Close() +} +func TestZRFirmwareVersionStateInterfaceFlap(t *testing.T) { + dut1 := ondatra.DUT(t, "dut") + dp1 := dut1.Port(t, "port1") + dp2 := dut1.Port(t, "port2") + t.Logf("dut1: %v", dut1) + t.Logf("dut1 dp1 name: %v", dp1.Name()) + configInterface(t, dut1, dp1, true) + configInterface(t, dut1, dp2, true) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + transceiverName := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) + // Check if TRANSCEIVER is of type 400ZR + if dp1.PMD() != ondatra.PMD400GBASEZR { + t.Fatalf("%s Transceiver is not 400ZR its of type: %v", transceiverName, dp1.PMD()) + } + // Disable interface + configInterface(t, dut1, dp1, false) + component1 := gnmi.OC().Component(transceiverName) + + p1Stream := samplestream.New(t, dut1, component1.FirmwareVersion().State(), 10*time.Second) + + // Wait 60 sec cooling off period + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_DOWN) + verifyFirmwareVersionValue(t, dut1, p1Stream) + + // Enable interface + configInterface(t, dut1, dp1, true) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + verifyFirmwareVersionValue(t, dut1, p1Stream) +} + +func opticalChannelComponentFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { + t.Helper() + if deviations.MissingPortToOpticalChannelMapping(dut) { + switch dut.Vendor() { + case ondatra.ARISTA: + transceiverName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).Transceiver().State()) + return fmt.Sprintf("%s-Optical0", transceiverName) + default: + t.Fatal("Manual Optical channel name required when deviation missing_port_to_optical_channel_component_mapping applied.") + } + } + compName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).HardwarePort().State()) + for { + comp, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(compName).State()).Val() + if !ok { + t.Fatalf("Recursive optical channel lookup failed for port: %s, component %s not found.", p.Name(), compName) + } + if comp.GetType() == oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL { + return compName + } + if comp.GetParent() == "" { + t.Fatalf("Recursive optical channel lookup failed for port: %s, parent of component %s not found.", p.Name(), compName) + } + compName = comp.GetParent() + } +} From 78a50c2e877ad3f8ead1919c3338ee233536cb1c Mon Sep 17 00:00:00 2001 From: anksaiki Date: Tue, 19 Mar 2024 20:14:58 -0400 Subject: [PATCH 31/97] Add workaround for Arista in the IPv6 Static Route with IPv4 Next Hop subtest (#2804) * Add workaround for Arista * fix go vet error --- .../zr_firmware_version_test.go | 2 +- .../basic_static_route_support_test.go | 82 ++++++++++++-- .../metadata.textproto | 1 + internal/deviations/deviations.go | 7 ++ internal/otgutils/actions.go | 9 +- proto/metadata.proto | 4 + proto/metadata_go_proto/metadata.pb.go | 100 +++++++++++------- 7 files changed, 150 insertions(+), 55 deletions(-) diff --git a/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go b/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go index e8dc8d8b41a..4958e4b516d 100644 --- a/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go +++ b/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go @@ -54,7 +54,7 @@ func configInterface(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port, en }) } func verifyFirmwareVersionValue(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[string]) { - firmwareVersionSample := pStream.Next(t) + firmwareVersionSample := pStream.Next() if firmwareVersionSample == nil { t.Fatalf("Firmware telemetry %v was not streamed in the most recent subscription interval", firmwareVersionSample) } diff --git a/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go b/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go index 14259f34278..a5d8a8580b0 100644 --- a/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go +++ b/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go @@ -47,6 +47,8 @@ const ( ecmpTolerance = uint64(2) port1Tag = "0x101" port2Tag = "0x102" + dummyV6 = "2001:db8::192:0:2:d" + dummyMAC = "00:1A:11:00:0A:BC" ) var ( @@ -674,13 +676,25 @@ func (td *testData) testIPv6StaticRouteWithIPv4NextHop(t *testing.T) { // IPv4 address of ATE port-1 // Change the IPv6 next-hop of the ipv6-route-b with the next hop set to the // IPv4 address of ATE port-2 - v6Cfg := &cfgplugins.StaticRouteCfg{ - NetworkInstance: deviations.DefaultNetworkInstance(td.dut), - Prefix: td.staticIPv6.cidr(t), - NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ - "0": oc.UnionString(atePort1.IPv4), - "1": oc.UnionString(atePort2.IPv4), - }, + var v6Cfg *cfgplugins.StaticRouteCfg + if deviations.IPv6StaticRouteWithIPv4NextHopRequiresStaticARP(td.dut) { + staticARPWithMagicUniversalIP(t, td.dut) + v6Cfg = &cfgplugins.StaticRouteCfg{ + NetworkInstance: deviations.DefaultNetworkInstance(td.dut), + Prefix: td.staticIPv6.cidr(t), + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(dummyV6), + }, + } + } else { + v6Cfg = &cfgplugins.StaticRouteCfg{ + NetworkInstance: deviations.DefaultNetworkInstance(td.dut), + Prefix: td.staticIPv6.cidr(t), + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(atePort1.IPv4), + "1": oc.UnionString(atePort2.IPv4), + }, + } } if _, err := cfgplugins.NewStaticRouteCfg(b, v6Cfg, td.dut); err != nil { t.Fatalf("Failed to configure IPv6 static route: %v", err) @@ -690,6 +704,9 @@ func (td *testData) testIPv6StaticRouteWithIPv4NextHop(t *testing.T) { // Validate both the routes i.e. ipv6-route-[a|b] are configured and the IPv4 // next-hop is reported correctly t.Run("Telemetry", func(t *testing.T) { + if deviations.IPv6StaticRouteWithIPv4NextHopRequiresStaticARP(td.dut) { + t.Skip("Telemetry not validated due to use of deviation: IPv6StaticRouteWithIPv4NextHopRequiresStaticARP.") + } sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(td.dut)) gnmi.Await(t, td.dut, sp.Static(td.staticIPv6.cidr(t)).Prefix().State(), 30*time.Second, td.staticIPv6.cidr(t)) gotStatic := gnmi.Get(t, td.dut, sp.Static(td.staticIPv6.cidr(t)).State()) @@ -739,6 +756,44 @@ func (td *testData) testIPv6StaticRouteWithIPv4NextHop(t *testing.T) { }) } +func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + dummyIPCIDR := dummyV6 + "/128" + s2 := &oc.NetworkInstance_Protocol_Static{ + Prefix: ygot.String(dummyIPCIDR), + NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ + "0": { + Index: ygot.String("0"), + InterfaceRef: &oc.NetworkInstance_Protocol_Static_NextHop_InterfaceRef{ + Interface: ygot.String(p1.Name()), + }, + }, + "1": { + Index: ygot.String("1"), + InterfaceRef: &oc.NetworkInstance_Protocol_Static_NextHop_InterfaceRef{ + Interface: ygot.String(p2.Name()), + }, + }, + }, + } + sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) + static, ok := gnmi.LookupConfig(t, dut, sp.Config()).Val() + if !ok || static == nil { + static = &oc.NetworkInstance_Protocol{ + Identifier: oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + Name: ygot.String(deviations.StaticProtocolName(dut)), + Static: map[string]*oc.NetworkInstance_Protocol_Static{ + dummyIPCIDR: s2, + }, + } + gnmi.Replace(t, dut, sp.Config(), static) + } else { + gnmi.Replace(t, dut, sp.Static(dummyIPCIDR).Config(), s2) + } +} + func (td *testData) testIPv4StaticRouteWithIPv6NextHop(t *testing.T) { b := &gnmi.SetBatch{} // Change the IPv4 next-hop of the ipv4-route-a with the next hop set to the @@ -962,9 +1017,16 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { p2 := dut.Port(t, "port2") p3 := dut.Port(t, "port3") b := &gnmi.SetBatch{} - gnmi.BatchReplace(b, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) - gnmi.BatchReplace(b, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) - gnmi.BatchReplace(b, gnmi.OC().Interface(p3.Name()).Config(), dutPort3.NewOCInterface(p3.Name(), dut)) + i1 := dutPort1.NewOCInterface(p1.Name(), dut) + i2 := dutPort2.NewOCInterface(p2.Name(), dut) + i3 := dutPort3.NewOCInterface(p3.Name(), dut) + if deviations.IPv6StaticRouteWithIPv4NextHopRequiresStaticARP(dut) { + i1.GetOrCreateSubinterface(0).GetOrCreateIpv6().GetOrCreateNeighbor(dummyV6).LinkLayerAddress = ygot.String(dummyMAC) + i2.GetOrCreateSubinterface(0).GetOrCreateIpv6().GetOrCreateNeighbor(dummyV6).LinkLayerAddress = ygot.String(dummyMAC) + } + gnmi.BatchReplace(b, gnmi.OC().Interface(p1.Name()).Config(), i1) + gnmi.BatchReplace(b, gnmi.OC().Interface(p2.Name()).Config(), i2) + gnmi.BatchReplace(b, gnmi.OC().Interface(p3.Name()).Config(), i3) b.Set(t, dut) if deviations.ExplicitPortSpeed(dut) { diff --git a/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto b/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto index e552d95cdc9..4fe43c4c602 100644 --- a/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto +++ b/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto @@ -18,6 +18,7 @@ platform_exceptions: { isis_interface_afi_unsupported: true missing_isis_interface_afi_safi_enable: true isis_require_same_l1_metric_with_l2_metric: true + ipv6_static_route_with_ipv4_next_hop_requires_static_arp: true } } tags: TAGS_DATACENTER_EDGE diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 3a91d1fad52..109a1ddcfd8 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -841,3 +841,10 @@ func SkipPrefixSetMode(dut *ondatra.DUTDevice) bool { func SetMetricAsPreference(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetSetMetricAsPreference() } + +// IPv6StaticRouteWithIPv4NextHopRequiresStaticARP returns true if devices don't support having an +// IPv6 static Route with an IPv4 address as next hop and requires configuring a static ARP entry. +// Arista: https://partnerissuetracker.corp.google.com/issues/316593298 +func IPv6StaticRouteWithIPv4NextHopRequiresStaticARP(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetIpv6StaticRouteWithIpv4NextHopRequiresStaticArp() +} diff --git a/internal/otgutils/actions.go b/internal/otgutils/actions.go index af0feab727c..a342a5fba8e 100644 --- a/internal/otgutils/actions.go +++ b/internal/otgutils/actions.go @@ -36,10 +36,13 @@ func GetFlowStats(t testing.TB, otg *otg.OTG, flowName string, timeout time.Dura } txPkts := gnmi.Get(t, otg, gnmi.OTG().Flow(flowName).Counters().OutPkts().State()) - rxPkts, _ := gnmi.Watch(t, otg, gnmi.OTG().Flow(flowName).Counters().InPkts().State(), timeout, func(val *ygnmi.Value[uint64]) bool { - rxPackets, ok := val.Val() - return ok && rxPackets == txPkts + rxPkts, ok := gnmi.Watch(t, otg, gnmi.OTG().Flow(flowName).Counters().InPkts().State(), timeout, func(val *ygnmi.Value[uint64]) bool { + rxPackets, present := val.Val() + return present && rxPackets == txPkts }).Await(t) + if !ok { + return txPkts, 0 + } rx, _ := rxPkts.Val() return txPkts, rx diff --git a/proto/metadata.proto b/proto/metadata.proto index 40415e91693..a42bb5f8bd1 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -446,6 +446,10 @@ message Metadata { bool skip_prefix_set_mode = 156; // Devices set metric as preference for static next-hop bool set_metric_as_preference = 157; + // Devices don't support having an IPv6 static Route with an IPv4 address + // as next hop and requires configuring a static ARP entry. + // Arista: https://partnerissuetracker.corp.google.com/issues/316593298 + bool ipv6_static_route_with_ipv4_next_hop_requires_static_arp = 158; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index f9879af2e15..1598fb0f0e9 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.28.0 // protoc v3.21.12 // source: metadata.proto @@ -674,7 +674,7 @@ type Metadata_Deviations struct { // Skip setting allow-multiple-as while configuring eBGP // Arista: partnerissuetracker.corp.google.com/issues/317422300 SkipSettingAllowMultipleAs bool `protobuf:"varint,140,opt,name=skip_setting_allow_multiple_as,json=skipSettingAllowMultipleAs,proto3" json:"skip_setting_allow_multiple_as,omitempty"` - // Skip tests with decap encap vrf as PBF action + //Skip tests with decap encap vrf as PBF action // Nokia: partnerissuetracker.corp.google.com/issues/323251581 SkipPbfWithDecapEncapVrf bool `protobuf:"varint,141,opt,name=skip_pbf_with_decap_encap_vrf,json=skipPbfWithDecapEncapVrf,proto3" json:"skip_pbf_with_decap_encap_vrf,omitempty"` // Devices which does not support copying TTL. @@ -717,6 +717,10 @@ type Metadata_Deviations struct { SkipPrefixSetMode bool `protobuf:"varint,156,opt,name=skip_prefix_set_mode,json=skipPrefixSetMode,proto3" json:"skip_prefix_set_mode,omitempty"` // Devices set metric as preference for static next-hop SetMetricAsPreference bool `protobuf:"varint,157,opt,name=set_metric_as_preference,json=setMetricAsPreference,proto3" json:"set_metric_as_preference,omitempty"` + // Devices don't support having an IPv6 static Route with an IPv4 address + // as next hop and requires configuring a static ARP entry. + // Arista: https://partnerissuetracker.corp.google.com/issues/316593298 + Ipv6StaticRouteWithIpv4NextHopRequiresStaticArp bool `protobuf:"varint,158,opt,name=ipv6_static_route_with_ipv4_next_hop_requires_static_arp,json=ipv6StaticRouteWithIpv4NextHopRequiresStaticArp,proto3" json:"ipv6_static_route_with_ipv4_next_hop_requires_static_arp,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1738,6 +1742,13 @@ func (x *Metadata_Deviations) GetSetMetricAsPreference() bool { return false } +func (x *Metadata_Deviations) GetIpv6StaticRouteWithIpv4NextHopRequiresStaticArp() bool { + if x != nil { + return x.Ipv6StaticRouteWithIpv4NextHopRequiresStaticArp + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1801,7 +1812,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x57, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x58, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1832,7 +1843,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xa5, 0x4f, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x99, 0x50, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2463,44 +2474,51 @@ var file_metadata_proto_rawDesc = []byte{ 0x38, 0x0a, 0x18, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x9d, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x73, 0x50, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, - 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, - 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, - 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, - 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, - 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, - 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, - 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, - 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, - 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, - 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x38, 0x69, 0x70, 0x76, + 0x36, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, + 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, + 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x9e, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2f, 0x69, 0x70, + 0x76, 0x36, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, + 0x68, 0x49, 0x70, 0x76, 0x34, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, 0x4a, 0x04, 0x08, + 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, + 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, + 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, + 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, + 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, + 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, - 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, - 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, - 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, - 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, - 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, - 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, + 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, + 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, + 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, + 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, + 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, + 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, + 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, + 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, + 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, + 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, + 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From fca566fc7b487d908d038fcb707f7a71f9d0a1e0 Mon Sep 17 00:00:00 2001 From: arvbaska1 <123760606+arvbaska1@users.noreply.github.com> Date: Wed, 20 Mar 2024 03:07:20 -0400 Subject: [PATCH 32/97] [TE-11.21, TE-3.1, TE-3.7, TE-11.31, TE-3.31] Adding deviations for new subtest for PolicyW (#2648) * Adding deviation for new subtest for PolicyW * add deviation * fix checks * Add deviation for TE-3.7 * Changes for te-3.7 and resolve conflicts * fix conflicts * resolve conflicts --------- Co-authored-by: AmrNJ <155722765+AmrNJ@users.noreply.github.com> --- .../backup_nhg_action/metadata.textproto | 1 + .../backup_nhg_action_pbf/metadata.textproto | 3 + .../metadata.textproto | 3 +- .../metadata.textproto | 1 - .../metadata.textproto | 3 + .../metadata.textproto | 1 + .../base_hierarchical_nhg_update_test.go | 12 ++- .../metadata.textproto | 3 + ...se_hierarchical_route_installation_test.go | 24 ++++- .../metadata.textproto | 2 + internal/deviations/deviations.go | 5 + internal/vrfpolicy/vrfpolicy.go | 36 ++++++- proto/metadata.proto | 2 + proto/metadata_go_proto/metadata.pb.go | 100 ++++++++++-------- 14 files changed, 140 insertions(+), 56 deletions(-) diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action/metadata.textproto b/feature/experimental/gribi/otg_tests/backup_nhg_action/metadata.textproto index 84a121a892a..81bfb47ea92 100644 --- a/feature/experimental/gribi/otg_tests/backup_nhg_action/metadata.textproto +++ b/feature/experimental/gribi/otg_tests/backup_nhg_action/metadata.textproto @@ -11,6 +11,7 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true + interface_ref_interface_id_format: true } } platform_exceptions: { diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto b/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto index 5e9b261eb3d..1de5ed3f110 100644 --- a/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto +++ b/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto @@ -11,6 +11,9 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true + interface_ref_interface_id_format: true + pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true } } platform_exceptions: { diff --git a/feature/gribi/ate_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto b/feature/gribi/ate_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto index 147723391ea..f64bcea4013 100644 --- a/feature/gribi/ate_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto +++ b/feature/gribi/ate_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto @@ -13,7 +13,8 @@ platform_exceptions: { hierarchical_weight_resolution_tolerance: 1.5 ipv4_missing_enabled: true interface_ref_interface_id_format: true - + pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true } } platform_exceptions: { diff --git a/feature/gribi/ate_tests/hierarchical_weight_resolution_test/metadata.textproto b/feature/gribi/ate_tests/hierarchical_weight_resolution_test/metadata.textproto index f8ea374a730..63b7b4f20f6 100644 --- a/feature/gribi/ate_tests/hierarchical_weight_resolution_test/metadata.textproto +++ b/feature/gribi/ate_tests/hierarchical_weight_resolution_test/metadata.textproto @@ -13,7 +13,6 @@ platform_exceptions: { hierarchical_weight_resolution_tolerance: 1.5 ipv4_missing_enabled: true interface_ref_interface_id_format: true - } } platform_exceptions: { diff --git a/feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/metadata.textproto b/feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/metadata.textproto index 868d9b38bba..9c71cbd5fc6 100644 --- a/feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/metadata.textproto +++ b/feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/metadata.textproto @@ -11,6 +11,9 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true + interface_ref_interface_id_format: true + pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true } } platform_exceptions: { diff --git a/feature/gribi/otg_tests/backup_nhg_multiple_nh_test/metadata.textproto b/feature/gribi/otg_tests/backup_nhg_multiple_nh_test/metadata.textproto index 43061474e5e..07ec0e6a61e 100644 --- a/feature/gribi/otg_tests/backup_nhg_multiple_nh_test/metadata.textproto +++ b/feature/gribi/otg_tests/backup_nhg_multiple_nh_test/metadata.textproto @@ -11,6 +11,7 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true + interface_ref_interface_id_format: true } } platform_exceptions: { diff --git a/feature/gribi/otg_tests/base_hierarchical_nhg_update/base_hierarchical_nhg_update_test.go b/feature/gribi/otg_tests/base_hierarchical_nhg_update/base_hierarchical_nhg_update_test.go index bea9dc7941c..c705b00528b 100644 --- a/feature/gribi/otg_tests/base_hierarchical_nhg_update/base_hierarchical_nhg_update_test.go +++ b/feature/gribi/otg_tests/base_hierarchical_nhg_update/base_hierarchical_nhg_update_test.go @@ -224,16 +224,16 @@ func TestBaseHierarchicalNHGUpdate(t *testing.T) { desc: "Usecase for NHG update in hierarchical resolution scenario", fn: testBaseHierarchialNHG, }, - { - name: "testImplementDrain", - desc: "Usecase for Implementing Drain test", - fn: testImplementDrain, - }, { name: "testRecursiveIPv4EntrywithVRFSelectionPolW", desc: "Usecase for NHG update in hierarchical resolution scenario with VRF Selection Policy W", fn: testBaseHierarchialNHGwithVrfPolW, }, + { + name: "testImplementDrain", + desc: "Usecase for Implementing Drain test", + fn: testImplementDrain, + }, } // Configure the gRIBI client client := gribi.Client{ @@ -287,6 +287,8 @@ func testBaseHierarchialNHGwithVrfPolW(ctx context.Context, t *testing.T, args * ctx = context.WithValue(ctx, transitKey{}, true) testBaseHierarchialNHG(ctx, t, args) + //Delete Policy-forwarding PolicyW from the ingress interface + vrfpolicy.DeletePolicyForwarding(t, args.dut, "port1") } // TE3.7 - case 1: testBaseHierarchialNHG. diff --git a/feature/gribi/otg_tests/base_hierarchical_nhg_update/metadata.textproto b/feature/gribi/otg_tests/base_hierarchical_nhg_update/metadata.textproto index c08cca4e5e5..fca5d3f83ec 100644 --- a/feature/gribi/otg_tests/base_hierarchical_nhg_update/metadata.textproto +++ b/feature/gribi/otg_tests/base_hierarchical_nhg_update/metadata.textproto @@ -12,6 +12,9 @@ platform_exceptions: { deviations: { ipv4_missing_enabled: true gribi_mac_override_with_static_arp: true + interface_ref_interface_id_format: true + pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true } } platform_exceptions: { diff --git a/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go b/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go index 61865b765b9..2d076e71219 100644 --- a/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go +++ b/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go @@ -222,6 +222,12 @@ func configureVrfSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice) { pfRule12 := &policyFwRule{SeqId: 12, protocol: 41, sourceAddr: ipv4OuterSrc111WithMask, decapNi: niDecapTeVrf, postDecapNi: niDefault, decapFallbackNi: niTeVrf111} + if deviations.PfRequireSequentialOrderPbrRules(dut) { + pfRule10.SeqId = 910 + pfRule11.SeqId = 911 + pfRule12.SeqId = 912 + } + pfRuleList := []*policyFwRule{pfRule1, pfRule2, pfRule3, pfRule4, pfRule5, pfRule6, pfRule7, pfRule8, pfRule9, pfRule10, pfRule11, pfRule12} @@ -243,9 +249,21 @@ func configureVrfSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice) { pfRAction.PostDecapNetworkInstance = ygot.String(pfRule.postDecapNi) pfRAction.DecapFallbackNetworkInstance = ygot.String(pfRule.decapFallbackNi) } - pfR := niPf.GetOrCreateRule(13) - pfRAction := pfR.GetOrCreateAction() - pfRAction.NetworkInstance = ygot.String(niDefault) + + if deviations.PfRequireMatchDefaultRule(dut) { + pfR13 := niPf.GetOrCreateRule(913) + pfR13.GetOrCreateL2().SetEthertype(oc.PacketMatchTypes_ETHERTYPE_ETHERTYPE_IPV4) + pfRAction := pfR13.GetOrCreateAction() + pfRAction.NetworkInstance = ygot.String(niDefault) + pfR14 := niPf.GetOrCreateRule(914) + pfR14.GetOrCreateL2().SetEthertype(oc.PacketMatchTypes_ETHERTYPE_ETHERTYPE_IPV6) + pfRAction = pfR14.GetOrCreateAction() + pfRAction.NetworkInstance = ygot.String(niDefault) + } else { + pfR := niPf.GetOrCreateRule(13) + pfRAction := pfR.GetOrCreateAction() + pfRAction.NetworkInstance = ygot.String(niDefault) + } p1 := dut.Port(t, "port1") interfaceID := p1.Name() diff --git a/feature/gribi/otg_tests/base_hierarchical_route_installation_test/metadata.textproto b/feature/gribi/otg_tests/base_hierarchical_route_installation_test/metadata.textproto index 8058da4d567..ff82417d6fb 100644 --- a/feature/gribi/otg_tests/base_hierarchical_route_installation_test/metadata.textproto +++ b/feature/gribi/otg_tests/base_hierarchical_route_installation_test/metadata.textproto @@ -13,6 +13,8 @@ platform_exceptions: { ipv4_missing_enabled: true gribi_mac_override_with_static_arp: true interface_ref_interface_id_format: true + pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true } } platform_exceptions: { diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 109a1ddcfd8..8b4d6808551 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -848,3 +848,8 @@ func SetMetricAsPreference(dut *ondatra.DUTDevice) bool { func IPv6StaticRouteWithIPv4NextHopRequiresStaticARP(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetIpv6StaticRouteWithIpv4NextHopRequiresStaticArp() } + +// PfRequireSequentialOrderPbrRules returns true for device requires policy-forwarding rules to be in sequential order in the gNMI set-request. +func PfRequireSequentialOrderPbrRules(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetPfRequireSequentialOrderPbrRules() +} diff --git a/internal/vrfpolicy/vrfpolicy.go b/internal/vrfpolicy/vrfpolicy.go index 2c35c500671..5d914ef0dcb 100644 --- a/internal/vrfpolicy/vrfpolicy.go +++ b/internal/vrfpolicy/vrfpolicy.go @@ -150,6 +150,12 @@ func BuildVRFSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice, niName strin pfRule7, pfRule8, pfRule9, pfRule10, pfRule11, pfRule12, } + if deviations.PfRequireSequentialOrderPbrRules(dut) { + pfRule10.seqID = 910 + pfRule11.seqID = 911 + pfRule12.seqID = 912 + } + ni := d.GetOrCreateNetworkInstance(niName) niP := ni.GetOrCreatePolicyForwarding() niPf := niP.GetOrCreatePolicy(vrfPolW) @@ -169,9 +175,20 @@ func BuildVRFSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice, niName strin pfRAction.DecapFallbackNetworkInstance = ygot.String(pfRule.action.decapFallbackNI) } - pfR := niPf.GetOrCreateRule(13) - pfRAction := pfR.GetOrCreateAction() - pfRAction.NetworkInstance = ygot.String(niDefault) + if deviations.PfRequireMatchDefaultRule(dut) { + pfR13 := niPf.GetOrCreateRule(913) + pfR13.GetOrCreateL2().SetEthertype(oc.PacketMatchTypes_ETHERTYPE_ETHERTYPE_IPV4) + pfRAction := pfR13.GetOrCreateAction() + pfRAction.NetworkInstance = ygot.String(niDefault) + pfR14 := niPf.GetOrCreateRule(914) + pfR14.GetOrCreateL2().SetEthertype(oc.PacketMatchTypes_ETHERTYPE_ETHERTYPE_IPV6) + pfRAction = pfR14.GetOrCreateAction() + pfRAction.NetworkInstance = ygot.String(niDefault) + } else { + pfR := niPf.GetOrCreateRule(13) + pfRAction := pfR.GetOrCreateAction() + pfRAction.NetworkInstance = ygot.String(niDefault) + } return niP } @@ -202,3 +219,16 @@ func ConfigureVRFSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice) { } gnmi.Replace(t, dut, dutForwardingPath.Interface(interfaceID).Config(), interface1) } + +// deletePolicyForwarding deletes policy configured under given interface +func DeletePolicyForwarding(t *testing.T, dut *ondatra.DUTDevice, portID string) { + t.Helper() + p1 := dut.Port(t, portID) + ingressPort := p1.Name() + interfaceID := ingressPort + if deviations.InterfaceRefInterfaceIDFormat(dut) { + interfaceID = ingressPort + ".0" + } + pfpath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Interface(interfaceID) + gnmi.Delete(t, dut, pfpath.Config()) +} diff --git a/proto/metadata.proto b/proto/metadata.proto index a42bb5f8bd1..8432765b56b 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -450,6 +450,8 @@ message Metadata { // as next hop and requires configuring a static ARP entry. // Arista: https://partnerissuetracker.corp.google.com/issues/316593298 bool ipv6_static_route_with_ipv4_next_hop_requires_static_arp = 158; + // Device requires policy-forwarding rules to be in sequential order in the gNMI set-request. + bool pf_require_sequential_order_pbr_rules = 159; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 1598fb0f0e9..3b1c36c9cf6 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 -// protoc v3.21.12 +// protoc-gen-go v1.31.0 +// protoc v4.23.4 // source: metadata.proto package metadata_go_proto @@ -674,7 +674,7 @@ type Metadata_Deviations struct { // Skip setting allow-multiple-as while configuring eBGP // Arista: partnerissuetracker.corp.google.com/issues/317422300 SkipSettingAllowMultipleAs bool `protobuf:"varint,140,opt,name=skip_setting_allow_multiple_as,json=skipSettingAllowMultipleAs,proto3" json:"skip_setting_allow_multiple_as,omitempty"` - //Skip tests with decap encap vrf as PBF action + // Skip tests with decap encap vrf as PBF action // Nokia: partnerissuetracker.corp.google.com/issues/323251581 SkipPbfWithDecapEncapVrf bool `protobuf:"varint,141,opt,name=skip_pbf_with_decap_encap_vrf,json=skipPbfWithDecapEncapVrf,proto3" json:"skip_pbf_with_decap_encap_vrf,omitempty"` // Devices which does not support copying TTL. @@ -721,6 +721,8 @@ type Metadata_Deviations struct { // as next hop and requires configuring a static ARP entry. // Arista: https://partnerissuetracker.corp.google.com/issues/316593298 Ipv6StaticRouteWithIpv4NextHopRequiresStaticArp bool `protobuf:"varint,158,opt,name=ipv6_static_route_with_ipv4_next_hop_requires_static_arp,json=ipv6StaticRouteWithIpv4NextHopRequiresStaticArp,proto3" json:"ipv6_static_route_with_ipv4_next_hop_requires_static_arp,omitempty"` + // Device requires policy-forwarding rules to be in sequential order in the gNMI set-request. + PfRequireSequentialOrderPbrRules bool `protobuf:"varint,159,opt,name=pf_require_sequential_order_pbr_rules,json=pfRequireSequentialOrderPbrRules,proto3" json:"pf_require_sequential_order_pbr_rules,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1749,6 +1751,13 @@ func (x *Metadata_Deviations) GetIpv6StaticRouteWithIpv4NextHopRequiresStaticArp return false } +func (x *Metadata_Deviations) GetPfRequireSequentialOrderPbrRules() bool { + if x != nil { + return x.PfRequireSequentialOrderPbrRules + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1812,7 +1821,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x58, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xea, 0x58, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1843,7 +1852,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x99, 0x50, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xeb, 0x50, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2481,44 +2490,49 @@ var file_metadata_proto_rawDesc = []byte{ 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x9e, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2f, 0x69, 0x70, 0x76, 0x36, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x70, 0x76, 0x34, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, 0x4a, 0x04, 0x08, - 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, - 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, - 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, - 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, - 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, - 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, - 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, - 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, - 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, - 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, - 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, - 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, - 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, - 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, - 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x72, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, 0x12, 0x50, 0x0a, + 0x25, 0x70, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x72, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x9f, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, + 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x62, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x4a, + 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, + 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, + 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, + 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, + 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, + 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, + 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, + 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, + 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, + 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, + 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, + 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, + 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, + 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, + 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, + 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, + 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, + 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, + 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, + 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, + 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, + 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From cb683fec03144ef0f17e1f17bfb7e05a68df1db5 Mon Sep 17 00:00:00 2001 From: Marc Charlebois <105758144+MarcCharlebois@users.noreply.github.com> Date: Wed, 20 Mar 2024 08:00:22 -0700 Subject: [PATCH 33/97] Migrate kne configs to grpc_server (#2809) * KNE: migrating configs to grpc_server "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." * added jrpc-server "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --- topologies/kne/nokia/srlinux/config.cfg | 91 ++++++++++++------------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/topologies/kne/nokia/srlinux/config.cfg b/topologies/kne/nokia/srlinux/config.cfg index 7f734c0580d..28e1788311d 100644 --- a/topologies/kne/nokia/srlinux/config.cfg +++ b/topologies/kne/nokia/srlinux/config.cfg @@ -1,4 +1,3 @@ - acl { acl-filter cpm type ipv4 { entry 441 { @@ -89,22 +88,52 @@ system { lldp { admin-state enable } - gnmi-server { + grpc-server mgmt { + rate-limit 65535 + session-limit 65535 + yang-models openconfig admin-state enable - rate-limit 65000 - trace-options [ - request - response - common + default-tls-profile true + network-instance mgmt + port 9339 + services [ + gnmi + gnsi + gnoi ] + } + grpc-server mgmt-gribi { + admin-state enable + rate-limit 65535 + session-limit 65535 + default-tls-profile true + network-instance mgmt + port 9340 + services [ + gribi + ] + } + grpc-server mgmt-p4rt { + admin-state enable + rate-limit 65535 + session-limit 65535 + default-tls-profile true + network-instance mgmt + port 9559 + services [ + p4rt + ] + } + json-rpc-server { + admin-state enable network-instance mgmt { - admin-state enable - port 9339 - yang-models openconfig - tls-profile kne-profile - } - unix-socket { - admin-state enable + http { + admin-state enable + } + https { + admin-state enable + tls-profile kne-profile + } } } tls { @@ -135,26 +164,6 @@ ufJifhmpItpy3mkUCLEJ33ex2AA6 " } } - gribi-server { - admin-state enable - network-instance mgmt { - admin-state enable - port 9340 - tls-profile kne-profile - } - } - json-rpc-server { - admin-state enable - network-instance mgmt { - http { - admin-state enable - } - https { - admin-state enable - tls-profile kne-profile - } - } - } banner { login-banner "................................................................ : Welcome to Nokia SR Linux! : @@ -173,20 +182,6 @@ ufJifhmpItpy3mkUCLEJ33ex2AA6 ................................................................ " } - p4rt-server { - admin-state enable - network-instance mgmt { - admin-state enable - tls-profile kne-profile - } - } } network-instance DEFAULT { } -network-instance mgmt { - protocols { - gribi { - admin-state enable - } - } -} From 6df6471301562d4d4d064ce376ae367581b6808a Mon Sep 17 00:00:00 2001 From: g-yiwenhu <163206410+g-yiwenhu@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:33:50 -0700 Subject: [PATCH 34/97] Add Chromatic Dispersion (CD) test (#2806) * Add CD test * Add CD test * Revise readme * Revise readme * fix description mismatch * minor update --- .../tests/zr_cd_test/{README.MD => README.md} | 2 +- .../tests/zr_cd_test/metadata.textproto | 16 ++ .../tests/zr_cd_test/zr_cd_test.go | 180 ++++++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) rename feature/platform/transceiver/tests/zr_cd_test/{README.MD => README.md} (99%) create mode 100644 feature/platform/transceiver/tests/zr_cd_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go diff --git a/feature/platform/transceiver/tests/zr_cd_test/README.MD b/feature/platform/transceiver/tests/zr_cd_test/README.md similarity index 99% rename from feature/platform/transceiver/tests/zr_cd_test/README.MD rename to feature/platform/transceiver/tests/zr_cd_test/README.md index 46b563badf7..1a9f6e127ab 100644 --- a/feature/platform/transceiver/tests/zr_cd_test/README.MD +++ b/feature/platform/transceiver/tests/zr_cd_test/README.md @@ -5,7 +5,7 @@ Validate 400ZR optics module reports accurate CD telemetry values. Chromatic Dispersion is frequency dependent change in signal phase velocity due -to fiber measured in ps/nm +to fiber measured in ps/nm ## Procedure diff --git a/feature/platform/transceiver/tests/zr_cd_test/metadata.textproto b/feature/platform/transceiver/tests/zr_cd_test/metadata.textproto new file mode 100644 index 00000000000..a410a8e7339 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_cd_test/metadata.textproto @@ -0,0 +1,16 @@ +# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata +uuid: "6c7ec460-10be-4c71-81f5-888f76ef241b" +plan_id: "TRANSCEIVER-1" +description: "Telemetry: 400ZR Chromatic Dispersion(CD) telemetry values streaming" +testbed: TESTBED_DUT_400ZR +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + missing_port_to_optical_channel_component_mapping: true + } +} diff --git a/feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go b/feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go new file mode 100644 index 00000000000..76a316ed2c9 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go @@ -0,0 +1,180 @@ +package zr_cd_test + +import ( + "fmt" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +const ( + dp16QAM = 1 + samplingInterval = 10 * time.Second + minCDValue = 0 + maxCDValue = 2400 + inActiveCDValue = 0.0 + timeout = 10 * time.Minute + flapInterval = 30 * time.Second +) + +type portState int + +const ( + disabled portState = iota + enabled +) + +var ( + frequencies = []uint64{191400000, 196100000} + targetOutputPowers = []float64{-6, -10} +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func interfaceConfig(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port, frequency uint64, targetOutputPower float64) { + d := &oc.Root{} + i := d.GetOrCreateInterface(dp.Name()) + i.Enabled = ygot.Bool(true) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp.Name()).Config(), i) + OCcomponent := opticalChannelComponentFromPort(t, dut1, dp) + gnmi.Replace(t, dut1, gnmi.OC().Component(OCcomponent).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(targetOutputPower), + Frequency: ygot.Uint64(frequency), + }) +} + +func verifyCDValue(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[float64], sensorName string, status portState) float64 { + CDSample := pStream.Next(t) + if CDSample == nil { + t.Fatalf("CD telemetry %s was not streamed in the most recent subscription interval", sensorName) + } + CDVal, ok := CDSample.Val() + if !ok { + t.Fatalf("CD %q telemetry is not present", CDSample) + } + // Check CD return value of correct type + switch { + case status == disabled: + if CDVal != inActiveCDValue { + t.Fatalf("The inactive CD is %v, expected %v", CDVal, inActiveCDValue) + } + case status == enabled: + if CDVal < minCDValue && CDVal > maxCDValue { + t.Fatalf("The variable CD is %v, expected range (%v, %v)", CDVal, minCDValue, maxCDValue) + } + default: + t.Fatalf("Invalid status %v", status) + } + t.Logf("Device %v CD %s value : %v", dut1.Name(), sensorName, CDVal) + return CDVal +} + +func verifyAllCDValues(t *testing.T, dut1 *ondatra.DUTDevice, p1StreamInstant, p1StreamMax, p1StreamMin, p1StreamAvg *samplestream.SampleStream[float64], status portState) { + CDInstant := verifyCDValue(t, dut1, p1StreamInstant, "Instant", status) + CDMax := verifyCDValue(t, dut1, p1StreamMax, "Max", status) + CDMin := verifyCDValue(t, dut1, p1StreamMin, "Min", status) + CDAvg := verifyCDValue(t, dut1, p1StreamAvg, "Avg", status) + + if CDAvg >= CDMin && CDAvg <= CDMax { + t.Logf("The average is between the maximum and minimum values, Avg:%v Max:%v Min:%v", CDAvg, CDMax, CDMin) + } else { + t.Fatalf("The average is NOT between the maximum and minimum values, Avg:%v Max:%v Min:%v", CDAvg, CDMax, CDMin) + } + + if CDInstant >= CDMin && CDInstant <= CDMax { + t.Logf("The instant is between the maximum and minimum values, Instant:%v Max:%v Min:%v", CDInstant, CDMax, CDMin) + } else { + t.Fatalf("The instant is NOT between the maximum and minimum values, Instant:%v Max:%v Min:%v", CDInstant, CDMax, CDMin) + } + +} + +func TestCDValue(t *testing.T) { + dut1 := ondatra.DUT(t, "dut") + dp1 := dut1.Port(t, "port1") + dp2 := dut1.Port(t, "port2") + fptest.ConfigureDefaultNetworkInstance(t, dut1) + + // Derive transceiver names from ports. + tr1 := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) + tr2 := gnmi.Get(t, dut1, gnmi.OC().Interface(dp2.Name()).Transceiver().State()) + component1 := gnmi.OC().Component(tr1) + + for _, frequency := range frequencies { + for _, targetOutputPower := range targetOutputPowers { + interfaceConfig(t, dut1, dp1, frequency, targetOutputPower) + interfaceConfig(t, dut1, dp2, frequency, targetOutputPower) + // Wait for channels to be up. + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + + p1StreamInstant := samplestream.New(t, dut1, component1.OpticalChannel().ChromaticDispersion().Instant().State(), samplingInterval) + p1StreamAvg := samplestream.New(t, dut1, component1.OpticalChannel().ChromaticDispersion().Avg().State(), samplingInterval) + p1StreamMin := samplestream.New(t, dut1, component1.OpticalChannel().ChromaticDispersion().Min().State(), samplingInterval) + p1StreamMax := samplestream.New(t, dut1, component1.OpticalChannel().ChromaticDispersion().Max().State(), samplingInterval) + + verifyAllCDValues(t, dut1, p1StreamInstant, p1StreamMax, p1StreamMin, p1StreamAvg, enabled) + + // Disable or shut down the interface on the DUT. + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Enabled().Config(), false) + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp2.Name()).Enabled().Config(), false) + // Wait for channels to be down. + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_DOWN) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_DOWN) + + verifyAllCDValues(t, dut1, p1StreamInstant, p1StreamMax, p1StreamMin, p1StreamAvg, disabled) + time.Sleep(flapInterval) + + // Re-enable interfaces. + gnmi.Replace(t, dut1, gnmi.OC().Component(tr1).Transceiver().Enabled().Config(), true) + gnmi.Replace(t, dut1, gnmi.OC().Component(tr2).Transceiver().Enabled().Config(), true) + // Wait for channels to be up. + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + + verifyAllCDValues(t, dut1, p1StreamInstant, p1StreamMax, p1StreamMin, p1StreamAvg, enabled) + + p1StreamMin.Close() + p1StreamMax.Close() + p1StreamAvg.Close() + p1StreamInstant.Close() + } + } +} + +func opticalChannelComponentFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { + t.Helper() + if deviations.MissingPortToOpticalChannelMapping(dut) { + switch dut.Vendor() { + case ondatra.ARISTA: + transceiverName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).Transceiver().State()) + return fmt.Sprintf("%s-Optical0", transceiverName) + default: + t.Fatal("Manual Optical channel name required when deviation missing_port_to_optical_channel_component_mapping applied.") + } + } + compName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).HardwarePort().State()) + for { + comp, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(compName).State()).Val() + if !ok { + t.Fatalf("Recursive optical channel lookup failed for port: %s, component %s not found.", p.Name(), compName) + } + if comp.GetType() == oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL { + return compName + } + if comp.GetParent() == "" { + t.Fatalf("Recursive optical channel lookup failed for port: %s, parent of component %s not found.", p.Name(), compName) + } + compName = comp.GetParent() + } +} From 75f898040eea32c1b66200da64845c93dab37c63 Mon Sep 17 00:00:00 2001 From: anksaiki Date: Wed, 20 Mar 2024 23:16:42 -0400 Subject: [PATCH 35/97] Arista specific fixes for basic_static_route_support_test (#2834) * Arista specific fixes for basic_static_route_support_test * fix flow stats logic --- .../tests/zr_cd_test/zr_cd_test.go | 2 +- .../basic_static_route_support_test/README.md | 8 +- .../basic_static_route_support_test.go | 124 +++++++++++----- .../metadata.textproto | 4 + internal/deviations/deviations.go | 21 +++ internal/otgutils/actions.go | 4 +- proto/metadata.proto | 9 ++ proto/metadata_go_proto/metadata.pb.go | 134 ++++++++++++------ 8 files changed, 224 insertions(+), 82 deletions(-) diff --git a/feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go b/feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go index 76a316ed2c9..235db2506f2 100644 --- a/feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go +++ b/feature/platform/transceiver/tests/zr_cd_test/zr_cd_test.go @@ -54,7 +54,7 @@ func interfaceConfig(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port, fr } func verifyCDValue(t *testing.T, dut1 *ondatra.DUTDevice, pStream *samplestream.SampleStream[float64], sensorName string, status portState) float64 { - CDSample := pStream.Next(t) + CDSample := pStream.Next() if CDSample == nil { t.Fatalf("CD telemetry %s was not streamed in the most recent subscription interval", sensorName) } diff --git a/feature/staticroute/otg_tests/basic_static_route_support_test/README.md b/feature/staticroute/otg_tests/basic_static_route_support_test/README.md index eecbe83c336..e64a0047f6b 100644 --- a/feature/staticroute/otg_tests/basic_static_route_support_test/README.md +++ b/feature/staticroute/otg_tests/basic_static_route_support_test/README.md @@ -57,7 +57,7 @@ #### Test to validate static route metric -* Configure metric of ipv4-route-b and ipv6-route-b to 1000 +* Configure metric of ipv4-route-b and ipv6-route-b to 100 * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/metric * Validate that the metric is set correctly * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/state/metric @@ -69,7 +69,7 @@ #### Test to validate static route preference -* Configure preference of ipv4-route-a and ipv6-route-a to 200 +* Configure preference of ipv4-route-a and ipv6-route-a to 50 * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/preference * Validate that the preference is set correctly * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/state/preference @@ -90,9 +90,9 @@ #### Test to validate IPv6 static route with IPv4 next-hop -* Remove metric of 1000 from ipv4-route-b and ipv6-route-b +* Remove metric of 100 from ipv4-route-b and ipv6-route-b * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/metric -* Remove preference of 200 from ipv4-route-a and ipv6-route-a +* Remove preference of 50 from ipv4-route-a and ipv6-route-a * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/preference * Change the IPv6 next-hop of the ipv6-route-a with the next hop set to the IPv4 address of ATE port-1 diff --git a/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go b/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go index a5d8a8580b0..f801c2fbdc8 100644 --- a/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go +++ b/feature/staticroute/otg_tests/basic_static_route_support_test/basic_static_route_support_test.go @@ -211,6 +211,9 @@ func TestBasicStaticRouteSupport(t *testing.T) { func TestDisableRecursiveNextHopResolution(t *testing.T) { dut := ondatra.DUT(t, "dut") + if deviations.UnsupportedStaticRouteNextHopRecurse(dut) { + t.Skip("Skipping Disable Recursive Next Hop Resolution Test. Deviation UnsupportedStaticRouteNextHopRecurse enabled.") + } configureDUT(t, dut) ate := ondatra.ATE(t, "ate") @@ -252,6 +255,7 @@ func TestDisableRecursiveNextHopResolution(t *testing.T) { if err := td.awaitISISAdjacency(t, dut.Port(t, "port2"), isisName); err != nil { t.Fatal(err) } + t.Run("RT-1.26.8: Disable Recursive Next Hop Resolution", func(t *testing.T) { td.testRecursiveNextHopResolution(t) td.testRecursiveNextHopResolutionDisabled(t) @@ -270,9 +274,11 @@ func (td *testData) testRecursiveNextHopResolution(t *testing.T) { "0": oc.UnionString(td.advertisedIPv4.address), }, } - if _, err := cfgplugins.NewStaticRouteCfg(b, sV4, td.dut); err != nil { + spV4, err := cfgplugins.NewStaticRouteCfg(b, sV4, td.dut) + if err != nil { t.Fatal(err) } + spV4.GetOrCreateNextHop("0").SetRecurse(true) // Configure one IPv6 static route i.e. ipv6-route on the DUT for destination // `ipv6-network 2001:db8:128:128::/64` with the next hop of `ipv6-loopback = // 2001:db8::64:64::1/128`. Remove all other existing next hops for the route. @@ -283,9 +289,11 @@ func (td *testData) testRecursiveNextHopResolution(t *testing.T) { "0": oc.UnionString(td.advertisedIPv6.address), }, } - if _, err := cfgplugins.NewStaticRouteCfg(b, sV6, td.dut); err != nil { + spV6, err := cfgplugins.NewStaticRouteCfg(b, sV6, td.dut) + if err != nil { t.Fatal(err) } + spV6.GetOrCreateNextHop("0").SetRecurse(true) b.Set(t, td.dut) @@ -310,8 +318,8 @@ func (td *testData) testRecursiveNextHopResolution(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 10*time.Second) - lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 10*time.Second) + lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 20*time.Second) + lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 20*time.Second) // Validate that traffic is received from DUT (doesn't matter which port) otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) @@ -351,8 +359,8 @@ func (td *testData) testRecursiveNextHopResolutionDisabled(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 10*time.Second) - lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 10*time.Second) + lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 20*time.Second) + lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 20*time.Second) // Validate that traffic is NOT received from DUT otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) @@ -365,7 +373,7 @@ func (td *testData) testRecursiveNextHopResolutionDisabled(t *testing.T) { }) } -func (td *testData) testStaticRouteECMP(t *testing.T) { +func (td *testData) configureStaticRouteToATEP1AndP2(t *testing.T) { b := &gnmi.SetBatch{} // Configure IPv4 static routes: // * Configure one IPv4 static route i.e. ipv4-route-a on the DUT for @@ -405,6 +413,19 @@ func (td *testData) testStaticRouteECMP(t *testing.T) { t.Fatalf("Failed to configure IPv6 static route: %v", err) } b.Set(t, td.dut) +} + +func (td *testData) deleteStaticRoutes(t *testing.T) { + b := &gnmi.SetBatch{} + sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(td.dut)) + gnmi.BatchDelete(b, sp.Static(td.staticIPv4.cidr(t)).Config()) + gnmi.BatchDelete(b, sp.Static(td.staticIPv6.cidr(t)).Config()) + b.Set(t, td.dut) +} + +func (td *testData) testStaticRouteECMP(t *testing.T) { + td.configureStaticRouteToATEP1AndP2(t) + defer td.deleteStaticRoutes(t) t.Run("Telemetry", func(t *testing.T) { sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(td.dut)) @@ -438,8 +459,8 @@ func (td *testData) testStaticRouteECMP(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 10*time.Second) - lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 10*time.Second) + lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 20*time.Second) + lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 20*time.Second) otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) if lossV4 > lossTolerance { @@ -494,17 +515,23 @@ func (td *testData) testStaticRouteECMP(t *testing.T) { } func (td *testData) testStaticRouteWithMetric(t *testing.T) { - const port2Metric = uint32(1000) + td.configureStaticRouteToATEP1AndP2(t) + defer td.deleteStaticRoutes(t) + + const port2Metric = uint32(100) sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(td.dut)) - // Configure metric of ipv4-route-b and ipv6-route-b to 1000 + // Configure metric of ipv4-route-b and ipv6-route-b to 100 batch := &gnmi.SetBatch{} gnmi.BatchReplace(batch, sp.Static(td.staticIPv4.cidr(t)).NextHop("1").Metric().Config(), port2Metric) gnmi.BatchReplace(batch, sp.Static(td.staticIPv6.cidr(t)).NextHop("1").Metric().Config(), port2Metric) batch.Set(t, td.dut) t.Run("Telemetry", func(t *testing.T) { + if deviations.MissingStaticRouteNextHopMetricTelemetry(td.dut) { + t.Skip("Skipping Telemetry check for Metric, since deviation MissingStaticRouteNextHopMetricTelemetry is enabled.") + } gnmi.Await(t, td.dut, sp.Static(td.staticIPv4.cidr(t)).Prefix().State(), 30*time.Second, td.staticIPv4.cidr(t)) gnmi.Await(t, td.dut, sp.Static(td.staticIPv6.cidr(t)).Prefix().State(), 30*time.Second, td.staticIPv6.cidr(t)) // Validate that the metric is set correctly @@ -523,8 +550,8 @@ func (td *testData) testStaticRouteWithMetric(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 10*time.Second) - lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 10*time.Second) + lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 20*time.Second) + lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 20*time.Second) otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) if lossV4 > lossTolerance { @@ -535,7 +562,7 @@ func (td *testData) testStaticRouteWithMetric(t *testing.T) { } // Validate that traffic is received from DUT on port-1 and not on port-2 portCounters := egressTrackingCounters(t, td.ate, v4Flow) - _, rxV4 := otgutils.GetFlowStats(t, td.ate.OTG(), v4Flow, 10*time.Second) + _, rxV4 := otgutils.GetFlowStats(t, td.ate.OTG(), v4Flow, 20*time.Second) port1Counter, ok := portCounters[port1Tag] if !ok { t.Errorf("Port1 IPv4 egress tracking counter not found: %v", portCounters) @@ -545,7 +572,7 @@ func (td *testData) testStaticRouteWithMetric(t *testing.T) { } // Validate that traffic is received from DUT on port-1 and not on port-2 portCounters = egressTrackingCounters(t, td.ate, v6Flow) - _, rxV6 := otgutils.GetFlowStats(t, td.ate.OTG(), v6Flow, 10*time.Second) + _, rxV6 := otgutils.GetFlowStats(t, td.ate.OTG(), v6Flow, 20*time.Second) port1Counter, ok = portCounters[port1Tag] if !ok { t.Errorf("Port1 IPv6 egress tracking counter not found: %v", portCounters) @@ -557,23 +584,44 @@ func (td *testData) testStaticRouteWithMetric(t *testing.T) { } func (td *testData) testStaticRouteWithPreference(t *testing.T) { - const port1Preference = uint32(200) + td.configureStaticRouteToATEP1AndP2(t) + defer td.deleteStaticRoutes(t) + + const port1Preference = uint32(50) + const port2Metric = uint32(100) sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(td.dut)) - // Configure preference of ipv4-route-a and ipv6-route-a to 200 + + // Configure metric of ipv4-route-b and ipv6-route-b to 100 batch := &gnmi.SetBatch{} - gnmi.BatchReplace(batch, sp.Static(td.staticIPv4.cidr(t)).NextHop("0").Preference().Config(), port1Preference) - gnmi.BatchReplace(batch, sp.Static(td.staticIPv6.cidr(t)).NextHop("0").Preference().Config(), port1Preference) + gnmi.BatchReplace(batch, sp.Static(td.staticIPv4.cidr(t)).NextHop("1").Metric().Config(), port2Metric) + gnmi.BatchReplace(batch, sp.Static(td.staticIPv6.cidr(t)).NextHop("1").Metric().Config(), port2Metric) + + // Configure preference of ipv4-route-a and ipv6-route-a to 50 + if deviations.SetMetricAsPreference(td.dut) { + // Lower metric indicate more favourable path. + // If we use Metric instead of Preference, we would need to have a port1Metric + // larger than port2Metric for traffic to pass through port 2 + port1Metric := port2Metric + port1Preference + gnmi.BatchReplace(batch, sp.Static(td.staticIPv4.cidr(t)).NextHop("0").Metric().Config(), port1Metric) + gnmi.BatchReplace(batch, sp.Static(td.staticIPv6.cidr(t)).NextHop("0").Metric().Config(), port1Metric) + } else { + gnmi.BatchReplace(batch, sp.Static(td.staticIPv4.cidr(t)).NextHop("0").Preference().Config(), port1Preference) + gnmi.BatchReplace(batch, sp.Static(td.staticIPv6.cidr(t)).NextHop("0").Preference().Config(), port1Preference) + } batch.Set(t, td.dut) t.Run("Telemetry", func(t *testing.T) { + if deviations.SetMetricAsPreference(td.dut) { + t.Skip("Skipping Preference telemetry check since deviation SetMetricAsPreference is enabled") + } gnmi.Await(t, td.dut, sp.Static(td.staticIPv4.cidr(t)).Prefix().State(), 30*time.Second, td.staticIPv4.cidr(t)) gnmi.Await(t, td.dut, sp.Static(td.staticIPv6.cidr(t)).Prefix().State(), 30*time.Second, td.staticIPv6.cidr(t)) // Validate that the preference is set correctly - if got, want := gnmi.Get(t, td.dut, sp.Static(td.staticIPv4.cidr(t)).NextHop("1").Preference().State()), port1Preference; got != want { + if got, want := gnmi.Get(t, td.dut, sp.Static(td.staticIPv4.cidr(t)).NextHop("0").Preference().State()), port1Preference; got != want { t.Errorf("IPv4 Static Route preference for NextHop 0, got: %d, want: %d", got, want) } - if got, want := gnmi.Get(t, td.dut, sp.Static(td.staticIPv6.cidr(t)).NextHop("1").Preference().State()), port1Preference; got != want { + if got, want := gnmi.Get(t, td.dut, sp.Static(td.staticIPv6.cidr(t)).NextHop("0").Preference().State()), port1Preference; got != want { t.Errorf("IPv6 Static Route preference for NextHop 0, got: %d, want: %d", got, want) } }) @@ -585,8 +633,8 @@ func (td *testData) testStaticRouteWithPreference(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 10*time.Second) - lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 10*time.Second) + lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 20*time.Second) + lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 20*time.Second) otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) if lossV4 > lossTolerance { @@ -597,7 +645,7 @@ func (td *testData) testStaticRouteWithPreference(t *testing.T) { } // Validate that traffic is now received from DUT on port-2 and not on port-1 portCounters := egressTrackingCounters(t, td.ate, v4Flow) - _, rxV4 := otgutils.GetFlowStats(t, td.ate.OTG(), v4Flow, 10*time.Second) + _, rxV4 := otgutils.GetFlowStats(t, td.ate.OTG(), v4Flow, 20*time.Second) port2Counter, ok := portCounters[port2Tag] if !ok { t.Errorf("Port2 IPv4 egress tracking counter not found: %v", portCounters) @@ -607,7 +655,7 @@ func (td *testData) testStaticRouteWithPreference(t *testing.T) { } // Validate that traffic is now received from DUT on port-2 and not on port-1 portCounters = egressTrackingCounters(t, td.ate, v6Flow) - _, rxV6 := otgutils.GetFlowStats(t, td.ate.OTG(), v6Flow, 10*time.Second) + _, rxV6 := otgutils.GetFlowStats(t, td.ate.OTG(), v6Flow, 20*time.Second) port2Counter, ok = portCounters[port2Tag] if !ok { t.Errorf("Port2 IPv6 egress tracking counter not found: %v", portCounters) @@ -620,6 +668,7 @@ func (td *testData) testStaticRouteWithPreference(t *testing.T) { func (td *testData) testStaticRouteSetTag(t *testing.T) { const tag = uint32(10) + b := &gnmi.SetBatch{} // Configure a tag of value 10 on ipv4 and ipv6 static routes v4Cfg := &cfgplugins.StaticRouteCfg{ @@ -652,6 +701,8 @@ func (td *testData) testStaticRouteSetTag(t *testing.T) { b.Set(t, td.dut) + defer td.deleteStaticRoutes(t) + // Validate the tag is set t.Run("Telemetry", func(t *testing.T) { sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(td.dut)) @@ -667,15 +718,15 @@ func (td *testData) testStaticRouteSetTag(t *testing.T) { } func (td *testData) testIPv6StaticRouteWithIPv4NextHop(t *testing.T) { - b := &gnmi.SetBatch{} - // Remove metric of 1000 from ipv4-route-b and ipv6-route-b + // Remove metric of 100 from ipv4-route-b and ipv6-route-b // * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/metric - // Remove preference of 200 from ipv4-route-a and ipv6-route-a + // Remove preference of 50 from ipv4-route-a and ipv6-route-a // * /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/preference // Change the IPv6 next-hop of the ipv6-route-a with the next hop set to the // IPv4 address of ATE port-1 // Change the IPv6 next-hop of the ipv6-route-b with the next hop set to the // IPv4 address of ATE port-2 + b := &gnmi.SetBatch{} var v6Cfg *cfgplugins.StaticRouteCfg if deviations.IPv6StaticRouteWithIPv4NextHopRequiresStaticARP(td.dut) { staticARPWithMagicUniversalIP(t, td.dut) @@ -701,6 +752,8 @@ func (td *testData) testIPv6StaticRouteWithIPv4NextHop(t *testing.T) { } b.Set(t, td.dut) + defer td.deleteStaticRoutes(t) + // Validate both the routes i.e. ipv6-route-[a|b] are configured and the IPv4 // next-hop is reported correctly t.Run("Telemetry", func(t *testing.T) { @@ -725,7 +778,7 @@ func (td *testData) testIPv6StaticRouteWithIPv4NextHop(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 10*time.Second) + lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 20*time.Second) otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) @@ -813,6 +866,8 @@ func (td *testData) testIPv4StaticRouteWithIPv6NextHop(t *testing.T) { } b.Set(t, td.dut) + defer td.deleteStaticRoutes(t) + // Validate both the routes i.e. ipv4-route-[a|b] are configured and the IPv6 // next-hop is reported correctly t.Run("Telemetry", func(t *testing.T) { @@ -834,7 +889,7 @@ func (td *testData) testIPv4StaticRouteWithIPv6NextHop(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 10*time.Second) + lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 20*time.Second) otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) @@ -899,7 +954,12 @@ func (td *testData) testStaticRouteWithDropNextHop(t *testing.T) { } b.Set(t, td.dut) + defer td.deleteStaticRoutes(t) + t.Run("Telemetry", func(t *testing.T) { + if deviations.MissingStaticRouteDropNextHopTelemetry(td.dut) { + t.Skip("Skipping telemetry check for DROP next hop. Deviation MissingStaticRouteDropNextHopTelemetryenabled.") + } sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(td.dut)) gnmi.Await(t, td.dut, sp.Static(td.staticIPv4.cidr(t)).Prefix().State(), 30*time.Second, td.staticIPv4.cidr(t)) gnmi.Await(t, td.dut, sp.Static(td.staticIPv6.cidr(t)).Prefix().State(), 30*time.Second, td.staticIPv6.cidr(t)) @@ -923,8 +983,8 @@ func (td *testData) testStaticRouteWithDropNextHop(t *testing.T) { time.Sleep(trafficDuration) td.ate.OTG().StopTraffic(t) - lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 10*time.Second) - lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 10*time.Second) + lossV4 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v4Flow, 20*time.Second) + lossV6 := otgutils.GetFlowLossPct(t, td.ate.OTG(), v6Flow, 20*time.Second) // Validate that traffic is dropped on DUT and not received on port-1 and // port-2 diff --git a/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto b/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto index 4fe43c4c602..1fce39fd6f2 100644 --- a/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto +++ b/feature/staticroute/otg_tests/basic_static_route_support_test/metadata.textproto @@ -19,6 +19,10 @@ platform_exceptions: { missing_isis_interface_afi_safi_enable: true isis_require_same_l1_metric_with_l2_metric: true ipv6_static_route_with_ipv4_next_hop_requires_static_arp: true + set_metric_as_preference: true + missing_static_route_next_hop_metric_telemetry: true + unsupported_static_route_next_hop_recurse: true + missing_static_route_drop_next_hop_telemetry: true } } tags: TAGS_DATACENTER_EDGE diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 8b4d6808551..622c8becb95 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -853,3 +853,24 @@ func IPv6StaticRouteWithIPv4NextHopRequiresStaticARP(dut *ondatra.DUTDevice) boo func PfRequireSequentialOrderPbrRules(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetPfRequireSequentialOrderPbrRules() } + +// MissingStaticRouteNextHopMetricTelemetry returns true for devices missing +// static route next-hop metric telemetry. +// Arista: https://partnerissuetracker.corp.google.com/issues/321010782 +func MissingStaticRouteNextHopMetricTelemetry(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetMissingStaticRouteNextHopMetricTelemetry() +} + +// UnsupportedStaticRouteNextHopRecurse returns true for devices that don't support recursive +// resolution of static route next hop. +// Arista: https://partnerissuetracker.corp.google.com/issues/314449182 +func UnsupportedStaticRouteNextHopRecurse(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetUnsupportedStaticRouteNextHopRecurse() +} + +// MissingStaticRouteDropNextHopTelemetry returns true for devices missing +// static route telemetry with DROP next hop. +// Arista: https://partnerissuetracker.corp.google.com/issues/330619816 +func MissingStaticRouteDropNextHopTelemetry(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetMissingStaticRouteDropNextHopTelemetry() +} diff --git a/internal/otgutils/actions.go b/internal/otgutils/actions.go index a342a5fba8e..9ed8f136f98 100644 --- a/internal/otgutils/actions.go +++ b/internal/otgutils/actions.go @@ -36,11 +36,11 @@ func GetFlowStats(t testing.TB, otg *otg.OTG, flowName string, timeout time.Dura } txPkts := gnmi.Get(t, otg, gnmi.OTG().Flow(flowName).Counters().OutPkts().State()) - rxPkts, ok := gnmi.Watch(t, otg, gnmi.OTG().Flow(flowName).Counters().InPkts().State(), timeout, func(val *ygnmi.Value[uint64]) bool { + rxPkts, _ := gnmi.Watch(t, otg, gnmi.OTG().Flow(flowName).Counters().InPkts().State(), timeout, func(val *ygnmi.Value[uint64]) bool { rxPackets, present := val.Val() return present && rxPackets == txPkts }).Await(t) - if !ok { + if rxPkts == nil { return txPkts, 0 } rx, _ := rxPkts.Val() diff --git a/proto/metadata.proto b/proto/metadata.proto index 8432765b56b..c153113d116 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -452,6 +452,15 @@ message Metadata { bool ipv6_static_route_with_ipv4_next_hop_requires_static_arp = 158; // Device requires policy-forwarding rules to be in sequential order in the gNMI set-request. bool pf_require_sequential_order_pbr_rules = 159; + // Device telemetry missing next hop metric value. + // Arista: https://partnerissuetracker.corp.google.com/issues/321010782 + bool missing_static_route_next_hop_metric_telemetry = 160; + // Device does not support recursive resolution of static route next hop. + // Arista: https://partnerissuetracker.corp.google.com/issues/314449182 + bool unsupported_static_route_next_hop_recurse = 161; + // Device missing telemetry for static route that has DROP next hop. + // Arista: https://partnerissuetracker.corp.google.com/issues/330619816 + bool missing_static_route_drop_next_hop_telemetry = 162; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 3b1c36c9cf6..9c67e06edf9 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.23.4 +// protoc-gen-go v1.28.0 +// protoc v3.21.12 // source: metadata.proto package metadata_go_proto @@ -674,7 +674,7 @@ type Metadata_Deviations struct { // Skip setting allow-multiple-as while configuring eBGP // Arista: partnerissuetracker.corp.google.com/issues/317422300 SkipSettingAllowMultipleAs bool `protobuf:"varint,140,opt,name=skip_setting_allow_multiple_as,json=skipSettingAllowMultipleAs,proto3" json:"skip_setting_allow_multiple_as,omitempty"` - // Skip tests with decap encap vrf as PBF action + //Skip tests with decap encap vrf as PBF action // Nokia: partnerissuetracker.corp.google.com/issues/323251581 SkipPbfWithDecapEncapVrf bool `protobuf:"varint,141,opt,name=skip_pbf_with_decap_encap_vrf,json=skipPbfWithDecapEncapVrf,proto3" json:"skip_pbf_with_decap_encap_vrf,omitempty"` // Devices which does not support copying TTL. @@ -723,6 +723,15 @@ type Metadata_Deviations struct { Ipv6StaticRouteWithIpv4NextHopRequiresStaticArp bool `protobuf:"varint,158,opt,name=ipv6_static_route_with_ipv4_next_hop_requires_static_arp,json=ipv6StaticRouteWithIpv4NextHopRequiresStaticArp,proto3" json:"ipv6_static_route_with_ipv4_next_hop_requires_static_arp,omitempty"` // Device requires policy-forwarding rules to be in sequential order in the gNMI set-request. PfRequireSequentialOrderPbrRules bool `protobuf:"varint,159,opt,name=pf_require_sequential_order_pbr_rules,json=pfRequireSequentialOrderPbrRules,proto3" json:"pf_require_sequential_order_pbr_rules,omitempty"` + // Device telemetry missing next hop metric value. + // Arista: https://partnerissuetracker.corp.google.com/issues/321010782 + MissingStaticRouteNextHopMetricTelemetry bool `protobuf:"varint,160,opt,name=missing_static_route_next_hop_metric_telemetry,json=missingStaticRouteNextHopMetricTelemetry,proto3" json:"missing_static_route_next_hop_metric_telemetry,omitempty"` + // Device does not support recursive resolution of static route next hop. + // Arista: https://partnerissuetracker.corp.google.com/issues/314449182 + UnsupportedStaticRouteNextHopRecurse bool `protobuf:"varint,161,opt,name=unsupported_static_route_next_hop_recurse,json=unsupportedStaticRouteNextHopRecurse,proto3" json:"unsupported_static_route_next_hop_recurse,omitempty"` + // Device missing telemetry for static route that has DROP next hop. + // Arista: https://partnerissuetracker.corp.google.com/issues/330619816 + MissingStaticRouteDropNextHopTelemetry bool `protobuf:"varint,162,opt,name=missing_static_route_drop_next_hop_telemetry,json=missingStaticRouteDropNextHopTelemetry,proto3" json:"missing_static_route_drop_next_hop_telemetry,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1758,6 +1767,27 @@ func (x *Metadata_Deviations) GetPfRequireSequentialOrderPbrRules() bool { return false } +func (x *Metadata_Deviations) GetMissingStaticRouteNextHopMetricTelemetry() bool { + if x != nil { + return x.MissingStaticRouteNextHopMetricTelemetry + } + return false +} + +func (x *Metadata_Deviations) GetUnsupportedStaticRouteNextHopRecurse() bool { + if x != nil { + return x.UnsupportedStaticRouteNextHopRecurse + } + return false +} + +func (x *Metadata_Deviations) GetMissingStaticRouteDropNextHopTelemetry() bool { + if x != nil { + return x.MissingStaticRouteDropNextHopTelemetry + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1821,7 +1851,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xea, 0x58, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x86, 0x5b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1852,7 +1882,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xeb, 0x50, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x87, 0x53, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2495,44 +2525,62 @@ var file_metadata_proto_rawDesc = []byte{ 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x9f, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x62, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x4a, - 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, - 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, - 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, - 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, - 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, - 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, - 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, - 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, - 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, - 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, - 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, - 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, - 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, - 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, - 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, - 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, - 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, - 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, - 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x62, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x61, 0x0a, 0x2e, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, + 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, + 0x79, 0x18, 0xa0, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, + 0x48, 0x6f, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x12, 0x58, 0x0a, 0x29, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, + 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x18, + 0xa1, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, + 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x2c, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, + 0x6f, 0x70, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa2, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x26, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x65, 0x78, 0x74, 0x48, + 0x6f, 0x70, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x4a, 0x04, 0x08, 0x54, 0x10, + 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, + 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, + 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, + 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, + 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, + 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, + 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, + 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, + 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, + 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, + 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, + 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, + 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, + 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, + 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, + 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, + 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, + 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, + 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, + 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, + 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 6484c755565f3a93c84927cc9780c6a0a62c9974 Mon Sep 17 00:00:00 2001 From: prakashbadri-arista <127355794+prakashbadri-arista@users.noreply.github.com> Date: Thu, 21 Mar 2024 04:49:17 -0700 Subject: [PATCH 36/97] Fix TE-16.1 basic_encap_test for Arista due to expected deviations (#2828) * Fix TE-16.1 basic_encap_test for Arista due to expected deviations Fix the test failures due to the following issues in the test - The test was setting "network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/ethertype" to detect match rule AF for the default rule. But this path should not be used for that and is not supported by EOS. - Add the following deviations for EOS: static_protocol_name: "STATIC" gribi_mac_override_static_arp_static_route: true interface_enabled: true ttl_copy_unsupported: true ( The TTL expectation is wrong in the test. once that is fixed, this can be removed ) default_network_instance: "default" - Add static routes to magic IP and setup a static arp entry for magic ip address with all the egress interfaces for EOS. - Change the publishing of AFT entries such that NH/NHG aft entries are pushed together. The test still fails on validating encapRatio. We need to see if the test has the right flows to validate this. But pushing the fixes for other issues. * Address pramod's comments. --------- Co-authored-by: Pramod Maurya --- .../basic_encap_test/basic_encap_test.go | 78 +++++++++++++++---- .../basic_encap_test/metadata.textproto | 10 ++- 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go index 4ca9844fbc0..43cf4d68d86 100644 --- a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go +++ b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go @@ -35,6 +35,7 @@ import ( "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/gribi" "github.com/openconfig/featureprofiles/internal/otgutils" + "github.com/openconfig/gribigo/client" "github.com/openconfig/gribigo/fluent" "github.com/openconfig/ondatra" "github.com/openconfig/ondatra/gnmi" @@ -75,6 +76,7 @@ const ( dscpEncapB1 = 20 dscpEncapB2 = 28 dscpEncapNoMatch = 30 + magicIp = "192.168.1.1" magicMac = "02:00:00:00:00:01" tunnelDstIP1 = "203.0.113.1" tunnelDstIP2 = "203.0.113.2" @@ -628,7 +630,6 @@ func getPbrPolicy(dut *ondatra.DUTDevice, name string, clusterFacing bool) *oc.N for _, pRule := range getPbrRules(dut, clusterFacing) { r := p.GetOrCreateRule(pRule.sequence) - l2 := r.GetOrCreateL2() r4 := r.GetOrCreateIpv4() if pRule.dscpSet != nil { @@ -653,9 +654,6 @@ func getPbrPolicy(dut *ondatra.DUTDevice, name string, clusterFacing bool) *oc.N ra.DecapFallbackNetworkInstance = ygot.String(pRule.decapVrfSet[2]) } - if pRule.etherType != nil { - l2.SetEthertype(pRule.etherType) - } if pRule.encapVrf != "" { r.GetOrCreateAction().SetNetworkInstance(pRule.encapVrf) @@ -674,6 +672,31 @@ func configureBaseconfig(t *testing.T, dut *ondatra.DUTDevice) { gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Config(), pf) } +func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + p2 := dut.Port(t, "port2") + p3 := dut.Port(t, "port3") + p4 := dut.Port(t, "port4") + p5 := dut.Port(t, "port5") + portList := []*ondatra.Port{p2, p3, p4, p5} + for idx, p := range portList { + s := &oc.NetworkInstance_Protocol_Static{ + Prefix: ygot.String(magicIp + "/32"), + NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ + strconv.Itoa(idx): { + Index: ygot.String(strconv.Itoa(idx)), + InterfaceRef: &oc.NetworkInstance_Protocol_Static_NextHop_InterfaceRef{ + Interface: ygot.String(p.Name()), + }, + }, + }, + } + sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) + gnmi.Update(t, dut, sp.Static(magicIp+"/32").Config(), s) + gnmi.Update(t, dut, gnmi.OC().Interface(p.Name()).Config(), configStaticArp(p.Name(), magicIp, magicMac)) + } +} + // programEntries pushes RIB entries on the DUT required for Encap functionality func programEntries(t *testing.T, dut *ondatra.DUTDevice, c *gribi.Client) { // push RIB entries @@ -682,28 +705,55 @@ func programEntries(t *testing.T, dut *ondatra.DUTDevice, c *gribi.Client) { c.AddNH(t, nh11ID, "MACwithIp", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Dest: otgPort3DummyIP.IPv4, Mac: magicMac}) c.AddNH(t, nh100ID, "MACwithIp", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Dest: otgPort4DummyIP.IPv4, Mac: magicMac}) c.AddNH(t, nh101ID, "MACwithIp", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Dest: otgPort5DummyIP.IPv4, Mac: magicMac}) - + c.AddNHG(t, nhg2ID, map[uint64]uint64{nh10ID: 1, nh11ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + c.AddNHG(t, nhg3ID, map[uint64]uint64{nh100ID: 2, nh101ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + } else if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { + p2 := dut.Port(t, "port2") + p3 := dut.Port(t, "port3") + p4 := dut.Port(t, "port4") + p5 := dut.Port(t, "port5") + nh1, op1 := gribi.NHEntry(nh10ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), + fluent.InstalledInFIB, &gribi.NHOptions{Interface: p2.Name(), Mac: magicMac, Dest: magicIp}) + nh2, op2 := gribi.NHEntry(nh11ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), + fluent.InstalledInFIB, &gribi.NHOptions{Interface: p3.Name(), Mac: magicMac, Dest: magicIp}) + nh3, op3 := gribi.NHEntry(nh100ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), + fluent.InstalledInFIB, &gribi.NHOptions{Interface: p4.Name(), Mac: magicMac, Dest: magicIp}) + nh4, op4 := gribi.NHEntry(nh101ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), + fluent.InstalledInFIB, &gribi.NHOptions{Interface: p5.Name(), Mac: magicMac, Dest: magicIp}) + nhg1, op5 := gribi.NHGEntry(nhg2ID, map[uint64]uint64{nh10ID: 1, nh11ID: 3}, + deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + nhg2, op6 := gribi.NHGEntry(nhg3ID, map[uint64]uint64{nh100ID: 2, nh101ID: 3}, + deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + c.AddEntries(t, []fluent.GRIBIEntry{nh1, nh2, nh3, nh4, nhg1, nhg2}, + []*client.OpResult{op1, op2, op3, op4, op5, op6}) } else { c.AddNH(t, nh10ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Interface: dut.Port(t, "port2").Name(), Mac: magicMac}) c.AddNH(t, nh11ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Interface: dut.Port(t, "port3").Name(), Mac: magicMac}) c.AddNH(t, nh100ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Interface: dut.Port(t, "port4").Name(), Mac: magicMac}) c.AddNH(t, nh101ID, "MACwithInterface", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Interface: dut.Port(t, "port5").Name(), Mac: magicMac}) + c.AddNHG(t, nhg2ID, map[uint64]uint64{nh10ID: 1, nh11ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + c.AddNHG(t, nhg3ID, map[uint64]uint64{nh100ID: 2, nh101ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) } - c.AddNHG(t, nhg2ID, map[uint64]uint64{nh10ID: 1, nh11ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) c.AddIPv4(t, cidr(vipIP1, 32), nhg2ID, deviations.DefaultNetworkInstance(dut), deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) - c.AddNHG(t, nhg3ID, map[uint64]uint64{nh100ID: 2, nh101ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) c.AddIPv4(t, cidr(vipIP2, 32), nhg3ID, deviations.DefaultNetworkInstance(dut), deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) - c.AddNH(t, nh1ID, vipIP1, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) - c.AddNH(t, nh2ID, vipIP2, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) - c.AddNHG(t, nhg1ID, map[uint64]uint64{nh1ID: 1, nh2ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + nh5, op7 := gribi.NHEntry(nh1ID, vipIP1, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + nh6, op8 := gribi.NHEntry(nh2ID, vipIP2, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + nhg3, op9 := gribi.NHGEntry(nhg1ID, map[uint64]uint64{nh1ID: 1, nh2ID: 3}, + deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + c.AddEntries(t, []fluent.GRIBIEntry{nh5, nh6, nhg3}, []*client.OpResult{op7, op8, op9}) + c.AddIPv4(t, cidr(tunnelDstIP1, 32), nhg1ID, vrfTransit, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) c.AddIPv4(t, cidr(tunnelDstIP2, 32), nhg1ID, vrfTransit, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) - c.AddNH(t, nh201ID, "Encap", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Src: ipv4OuterSrc111, Dest: tunnelDstIP1, VrfName: vrfTransit}) - c.AddNH(t, nh202ID, "Encap", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, &gribi.NHOptions{Src: ipv4OuterSrc111, Dest: tunnelDstIP2, VrfName: vrfTransit}) - c.AddNHG(t, nhg10ID, map[uint64]uint64{nh201ID: 1, nh202ID: 3}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + nh7, op9 := gribi.NHEntry(nh201ID, "Encap", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, + &gribi.NHOptions{Src: ipv4OuterSrc111, Dest: tunnelDstIP1, VrfName: vrfTransit}) + nh8, op10 := gribi.NHEntry(nh202ID, "Encap", deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB, + &gribi.NHOptions{Src: ipv4OuterSrc111, Dest: tunnelDstIP2, VrfName: vrfTransit}) + nhg4, op11 := gribi.NHGEntry(nhg10ID, map[uint64]uint64{nh201ID: 1, nh202ID: 3}, + deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) + c.AddEntries(t, []fluent.GRIBIEntry{nh7, nh8, nhg4}, []*client.OpResult{op9, op10, op11}) c.AddIPv4(t, cidr(ipv4EntryPrefix, ipv4EntryPrefixLen), nhg10ID, vrfEncapA, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) c.AddIPv4(t, cidr(ipv4EntryPrefix, ipv4EntryPrefixLen), nhg10ID, vrfEncapB, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) c.AddIPv6(t, cidr(ipv6EntryPrefix, ipv6EntryPrefixLen), nhg10ID, vrfEncapA, deviations.DefaultNetworkInstance(dut), fluent.InstalledInFIB) @@ -732,6 +782,8 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { applyForwardingPolicy(t, dut, p1.Name()) if deviations.GRIBIMACOverrideWithStaticARP(dut) { staticARPWithSecondaryIP(t, dut) + } else if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { + staticARPWithMagicUniversalIP(t, dut) } } diff --git a/feature/gribi/otg_tests/basic_encap_test/metadata.textproto b/feature/gribi/otg_tests/basic_encap_test/metadata.textproto index 18e5306efb7..8170adcc237 100644 --- a/feature/gribi/otg_tests/basic_encap_test/metadata.textproto +++ b/feature/gribi/otg_tests/basic_encap_test/metadata.textproto @@ -19,13 +19,15 @@ platform_exceptions: { } platform_exceptions: { platform: { - vendor: ARISTA + vendor: ARISTA } deviations: { - interface_enabled: true - omit_l2_mtu: true - default_network_instance: "default" static_protocol_name: "STATIC" + gribi_mac_override_static_arp_static_route: true + interface_enabled: true + ttl_copy_unsupported: true + default_network_instance: "default" + omit_l2_mtu: true } } tags: TAGS_DATACENTER_EDGE From 56d773f4357028d44b1d347e7dea459ba9089aab Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Thu, 21 Mar 2024 19:45:28 +0530 Subject: [PATCH 37/97] added support for 100g_fr port (#2836) --- .../basic_encap_test/basic_encap_test.go | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go index 43cf4d68d86..d055ec18919 100644 --- a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go +++ b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go @@ -656,7 +656,6 @@ func getPbrPolicy(dut *ondatra.DUTDevice, name string, clusterFacing bool) *oc.N if pRule.encapVrf != "" { r.GetOrCreateAction().SetNetworkInstance(pRule.encapVrf) - } } return pf @@ -674,6 +673,7 @@ func configureBaseconfig(t *testing.T, dut *ondatra.DUTDevice) { func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { t.Helper() + sb := &gnmi.SetBatch{} p2 := dut.Port(t, "port2") p3 := dut.Port(t, "port3") p4 := dut.Port(t, "port4") @@ -692,9 +692,10 @@ func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { }, } sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) - gnmi.Update(t, dut, sp.Static(magicIp+"/32").Config(), s) - gnmi.Update(t, dut, gnmi.OC().Interface(p.Name()).Config(), configStaticArp(p.Name(), magicIp, magicMac)) + gnmi.BatchUpdate(sb, sp.Static(magicIp+"/32").Config(), s) + gnmi.BatchUpdate(sb, gnmi.OC().Interface(p.Name()).Config(), configStaticArp(p.Name(), magicIp, magicMac)) } + sb.Set(t, dut) } // programEntries pushes RIB entries on the DUT required for Encap functionality @@ -767,13 +768,20 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { p3 := dut.Port(t, "port3") p4 := dut.Port(t, "port4") p5 := dut.Port(t, "port5") + portList := []*ondatra.Port{p1, p2, p3, p4, p5} // configure interfaces - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p3.Name()).Config(), dutPort3.NewOCInterface(p3.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p4.Name()).Config(), dutPort4.NewOCInterface(p4.Name(), dut)) - gnmi.Replace(t, dut, d.Interface(p5.Name()).Config(), dutPort5.NewOCInterface(p5.Name(), dut)) + for idx, a := range []attrs.Attributes{dutPort1, dutPort2, dutPort3, dutPort4, dutPort5} { + p := portList[idx] + intf := a.NewOCInterface(p.Name(), dut) + if p.PMD() == ondatra.PMD100GBASEFR { + e := intf.GetOrCreateEthernet() + e.AutoNegotiate = ygot.Bool(false) + e.DuplexMode = oc.Ethernet_DuplexMode_FULL + e.PortSpeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB + } + gnmi.Replace(t, dut, d.Interface(p.Name()).Config(), intf) + } // configure base PBF policies and network-instances configureBaseconfig(t, dut) @@ -820,6 +828,21 @@ func configureOTG(t *testing.T, ate *ondatra.ATEDevice) gosnappi.Config { otgPort4.AddToOTG(topo, p4, &dutPort4) otgPort5.AddToOTG(topo, p5, &dutPort5) + pmd100GFRPorts := []string{} + for _, p := range topo.Ports().Items() { + port := ate.Port(t, p.Name()) + if port.PMD() == ondatra.PMD100GBASEFR { + pmd100GFRPorts = append(pmd100GFRPorts, port.ID()) + } + } + // Disable FEC for 100G-FR ports because Novus does not support it. + if len(pmd100GFRPorts) > 0 { + l1Settings := topo.Layer1().Add().SetName("L1").SetPortNames(pmd100GFRPorts) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } + t.Logf("Pushing config to ATE and starting protocols...") otg.PushConfig(t, topo) t.Logf("starting protocols...") From f5603d1695bf9170bcef6e6c13d6ccdb4ec9f423 Mon Sep 17 00:00:00 2001 From: gforeal <120526274+gforeal@users.noreply.github.com> Date: Thu, 21 Mar 2024 09:58:55 -0700 Subject: [PATCH 38/97] Qos policy config test (#2833) * Update qos_policy_config_test ECN Queue config min/max Threshold etc * Update qos_policy_config_test ECN Queue config min/max Threshold etc --------- Co-authored-by: anksaiki Co-authored-by: rszarecki <46606165+rszarecki@users.noreply.github.com> --- .../tests/qos_policy_config_test/qos_policy_config_test.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go index b43b04be089..e035af3e562 100644 --- a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go +++ b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go @@ -601,8 +601,8 @@ func testECNConfig(t *testing.T) { ecnEnabled: true, dropEnabled: false, minThreshold: uint64(80000), - maxThreshold: math.MaxUint32, - maxDropProbabilityPercent: uint8(1), + maxThreshold: uint64(80001), + maxDropProbabilityPercent: uint8(100), weight: uint32(0), } @@ -620,9 +620,6 @@ func testECNConfig(t *testing.T) { t.Logf("qos ECN QueueManagementProfile config cases: %v", ecnConfig) gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - // TODO: Remove the following t.Skipf() after the config verification code has been tested. - t.Skipf("Skip the QoS config verification until it is tested against a DUT.") - // Verify the QueueManagementProfile is applied by checking the telemetry path state values. wredUniform := gnmi.OC().Qos().QueueManagementProfile("DropProfile").Wred().Uniform() if got, want := gnmi.Get(t, dut, wredUniform.EnableEcn().State()), ecnConfig.ecnEnabled; got != want { From 058e881707022d62ab19e89352a24c315cd43472 Mon Sep 17 00:00:00 2001 From: anksaiki Date: Fri, 22 Mar 2024 00:22:52 -0400 Subject: [PATCH 39/97] Add deviation for 400ZR tunable parameters telemetry (#2838) --- .../metadata.textproto | 1 + .../zr_tunable_parameters_test.go | 5 + internal/deviations/deviations.go | 6 ++ proto/metadata.proto | 3 + proto/metadata_go_proto/metadata.pb.go | 97 +++++++++++-------- 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto b/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto index 7dd07261362..c4187439461 100644 --- a/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto @@ -12,5 +12,6 @@ platform_exceptions: { interface_enabled: true default_network_instance: "default" missing_port_to_optical_channel_component_mapping: true + missing_zr_optical_channel_tunable_parameters_telemetry: true } } diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go index 96f356df552..776805fd36a 100644 --- a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go @@ -196,6 +196,7 @@ func Test400ZRInterfaceFlap(t *testing.T) { }) } func validateOpticsTelemetry(t *testing.T, streams []*samplestream.SampleStream[*oc.Component], frequency uint64, outputPower float64) { + dut := ondatra.DUT(t, "dut") var ocs []*oc.Component_OpticalChannel for _, s := range streams { val := s.Next() @@ -208,6 +209,10 @@ func validateOpticsTelemetry(t *testing.T, streams []*samplestream.SampleStream[ } ocs = append(ocs, v.GetOpticalChannel()) } + if deviations.MissingZROpticalChannelTunableParametersTelemetry(dut) { + t.Log("Skipping Tunable Parameters Telemetry validation. Deviation MissingZROpticalChannelTunableParametersTelemetry enabled.") + return + } for _, oc := range ocs { opm := oc.GetOperationalMode() inst := oc.GetCarrierFrequencyOffset().GetInstant() diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 622c8becb95..f4f5a8eca77 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -874,3 +874,9 @@ func UnsupportedStaticRouteNextHopRecurse(dut *ondatra.DUTDevice) bool { func MissingStaticRouteDropNextHopTelemetry(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetMissingStaticRouteDropNextHopTelemetry() } + +// Device missing 400ZR optical-channel tunable parameters telemetry. +// Arista: https://partnerissuetracker.corp.google.com/issues/330777809 +func MissingZROpticalChannelTunableParametersTelemetry(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetMissingZrOpticalChannelTunableParametersTelemetry() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index c153113d116..b9d115f45ac 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -461,6 +461,9 @@ message Metadata { // Device missing telemetry for static route that has DROP next hop. // Arista: https://partnerissuetracker.corp.google.com/issues/330619816 bool missing_static_route_drop_next_hop_telemetry = 162; + // Device missing 400ZR optical-channel tunable parameters telemetry. + // Arista: https://partnerissuetracker.corp.google.com/issues/330777809 + bool missing_zr_optical_channel_tunable_parameters_telemetry = 163; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 9c67e06edf9..d8f63266324 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -732,6 +732,9 @@ type Metadata_Deviations struct { // Device missing telemetry for static route that has DROP next hop. // Arista: https://partnerissuetracker.corp.google.com/issues/330619816 MissingStaticRouteDropNextHopTelemetry bool `protobuf:"varint,162,opt,name=missing_static_route_drop_next_hop_telemetry,json=missingStaticRouteDropNextHopTelemetry,proto3" json:"missing_static_route_drop_next_hop_telemetry,omitempty"` + // Device missing 400ZR optical-channel tunable parameters telemetry. + // Arista: https://partnerissuetracker.corp.google.com/issues/330777809 + MissingZrOpticalChannelTunableParametersTelemetry bool `protobuf:"varint,163,opt,name=missing_zr_optical_channel_tunable_parameters_telemetry,json=missingZrOpticalChannelTunableParametersTelemetry,proto3" json:"missing_zr_optical_channel_tunable_parameters_telemetry,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1788,6 +1791,13 @@ func (x *Metadata_Deviations) GetMissingStaticRouteDropNextHopTelemetry() bool { return false } +func (x *Metadata_Deviations) GetMissingZrOpticalChannelTunableParametersTelemetry() bool { + if x != nil { + return x.MissingZrOpticalChannelTunableParametersTelemetry + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1851,7 +1861,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x86, 0x5b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfb, 0x5b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1882,7 +1892,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x87, 0x53, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xfc, 0x53, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2543,44 +2553,51 @@ var file_metadata_proto_rawDesc = []byte{ 0x6f, 0x70, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa2, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x26, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x65, 0x78, 0x74, 0x48, - 0x6f, 0x70, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x4a, 0x04, 0x08, 0x54, 0x10, - 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, - 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, - 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, - 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, - 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, - 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, - 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, - 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, - 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, - 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, - 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, - 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, - 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, - 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, - 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, - 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, - 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, - 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, - 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, - 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x70, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x73, 0x0a, 0x37, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x7a, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x63, 0x61, + 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x74, 0x75, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa3, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5a, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, + 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, + 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, + 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, + 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, + 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, + 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, + 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, + 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, + 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, + 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, + 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, + 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, + 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, + 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, + 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, + 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, + 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, + 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From a5fc16e94add8240b95fb49825e49015e03793e4 Mon Sep 17 00:00:00 2001 From: arvbaska1 <123760606+arvbaska1@users.noreply.github.com> Date: Fri, 22 Mar 2024 09:20:52 -0400 Subject: [PATCH 40/97] Changed testbed metadata field to use 8 link tb (#2810) From ea7f75c7e5e7304c137ddaade5ef81053cf2edbc Mon Sep 17 00:00:00 2001 From: prakashbadri-arista <127355794+prakashbadri-arista@users.noreply.github.com> Date: Fri, 22 Mar 2024 23:53:04 -0700 Subject: [PATCH 41/97] Fix basic_encap_test failure due to unexpected traffic distribution ratio (#2839) * Fix basic_encap_test failure due to unexpected traffic distribution ratio The test is passing now the following changes - Increase the number of flows from 1000 to 10000 - Randomize the source/dst port set in the UDP header of the pacKet flows - Enable the extended hashing feature in EOS by setting the right TCAM profile configuration in startup configuration * fix rand.Seed with rand.New --------- Co-authored-by: Pramod Maurya --- .../basic_encap_test/basic_encap_test.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go index d055ec18919..66b26e27181 100644 --- a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go +++ b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go @@ -18,6 +18,7 @@ package basic_encap_test import ( "fmt" "log" + "math/rand" "os" "strconv" "strings" @@ -871,6 +872,15 @@ func clearCapture(t *testing.T, otg *otg.OTG, topo gosnappi.Config) { otg.PushConfig(t, topo) } +func randRange(max int, count int) []uint32 { + rand.New(rand.NewSource(time.Now().UnixNano())) + var result []uint32 + for len(result) < count { + result = append(result, uint32(rand.Intn(max))) + } + return result +} + // getFlow returns a flow of type ipv4, ipv4in4, ipv6in4 or ipv6 with dscp value passed in args. func (fa *flowAttr) getFlow(flowType string, name string, dscp uint32) gosnappi.Flow { flow := fa.topo.Flows().Add().SetName(name) @@ -887,8 +897,8 @@ func (fa *flowAttr) getFlow(flowType string, name string, dscp uint32) gosnappi. v4.TimeToLive().SetValue(ttl) v4.Priority().Dscp().Phb().SetValue(dscp) udp := flow.Packet().Add().Udp() - udp.SrcPort().Increment().SetStart(50001).SetCount(1000) - udp.DstPort().Increment().SetStart(50001).SetCount(1000) + udp.SrcPort().SetValues(randRange(50001, 10000)) + udp.DstPort().SetValues(randRange(50001, 10000)) // add inner ipv4 headers if flowType == "ipv4in4" { @@ -910,8 +920,8 @@ func (fa *flowAttr) getFlow(flowType string, name string, dscp uint32) gosnappi. v6.HopLimit().SetValue(ttl) v6.TrafficClass().SetValue(dscp << 2) udp := flow.Packet().Add().Udp() - udp.SrcPort().Increment().SetStart(50001).SetCount(1000) - udp.DstPort().Increment().SetStart(50001).SetCount(1000) + udp.SrcPort().SetValues(randRange(50001, 10000)) + udp.DstPort().SetValues(randRange(50001, 10000)) } return flow From e42a1f15276f579564677d6b961e8f0f31d0e52a Mon Sep 17 00:00:00 2001 From: prakashbadri-arista <127355794+prakashbadri-arista@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:44:32 -0700 Subject: [PATCH 42/97] Add Arista specific deviation for TE-17.1 (VRF selection policy driven TE) (#2841) - Add static route to a special fictitious IP address pointing to all TE egress interfaces - Add static arp entries to the fictitious IP address pointing to the magic mac address - Publish GRIBI AFT entries with fictitious IP address in the nexthop AFT entry --- .../vrf_policy_driven_te/metadata.textproto | 1 + .../vrf_policy_driven_te_test.go | 114 ++++++++++++++++-- 2 files changed, 105 insertions(+), 10 deletions(-) diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto index 74a4b27399c..43a1c1cbbd9 100644 --- a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto +++ b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto @@ -44,6 +44,7 @@ platform_exceptions: { deprecated_vlan_id: true interface_enabled: true default_network_instance: "default" + gribi_mac_override_static_arp_static_route: true missing_isis_interface_afi_safi_enable: true isis_interface_afi_unsupported: true isis_instance_enabled_required: true diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go index c89bcc016f2..a5ff20c5534 100644 --- a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go +++ b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go @@ -19,6 +19,7 @@ import ( "fmt" "log" "os" + "strconv" "testing" "time" @@ -71,6 +72,7 @@ const ( dscpEncapNoMatch = 30 ipv4OuterSrc111WithMask = "198.51.100.111/32" ipv4OuterSrc222WithMask = "198.51.100.222/32" + magicIp = "192.168.1.1" magicMac = "02:00:00:00:00:01" gribiIPv4EntryDefVRF1 = "192.0.2.101" gribiIPv4EntryDefVRF2 = "192.0.2.102" @@ -471,6 +473,44 @@ func configureVrfSelectionPolicyC(t *testing.T, dut *ondatra.DUTDevice) { gnmi.Replace(t, dut, dutPolFwdPath.Config(), niP) } +// configStaticArp configures static arp entries +func configStaticArp(p string, ipv4addr string, macAddr string) *oc.Interface { + i := &oc.Interface{Name: ygot.String(p)} + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + s := i.GetOrCreateSubinterface(0) + s4 := s.GetOrCreateIpv4() + n4 := s4.GetOrCreateNeighbor(ipv4addr) + n4.LinkLayerAddress = ygot.String(macAddr) + return i +} + +func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + p2 := dut.Port(t, "port2") + p3 := dut.Port(t, "port3") + p4 := dut.Port(t, "port4") + p5 := dut.Port(t, "port5") + p6 := dut.Port(t, "port6") + p7 := dut.Port(t, "port7") + portList := []*ondatra.Port{p2, p3, p4, p5, p6, p7} + for idx, p := range portList { + s := &oc.NetworkInstance_Protocol_Static{ + Prefix: ygot.String(magicIp + "/32"), + NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ + strconv.Itoa(idx): { + Index: ygot.String(strconv.Itoa(idx)), + InterfaceRef: &oc.NetworkInstance_Protocol_Static_NextHop_InterfaceRef{ + Interface: ygot.String(p.Name()), + }, + }, + }, + } + sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) + gnmi.Update(t, dut, sp.Static(magicIp+"/32").Config(), s) + gnmi.Update(t, dut, gnmi.OC().Interface(p.Name()).Config(), configStaticArp(p.Name(), magicIp, magicMac)) + } +} + // configureNetworkInstance configures vrfs DECAP_TE_VRF,ENCAP_TE_VRF_A,ENCAP_TE_VRF_B, // TE_VRF_222, TE_VRF_111. func configNonDefaultNetworkInstance(t *testing.T, dut *ondatra.DUTDevice) { @@ -544,6 +584,9 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { fptest.SetPortSpeed(t, dut.Port(t, pName)) } } + if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { + staticARPWithMagicUniversalIP(t, dut) + } } func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfList []string, dutAreaAddress, dutSysID string) { @@ -709,48 +752,99 @@ func verifyBgpTelemetry(t *testing.T, dut *ondatra.DUTDevice) { } } -func configGribiBaselineAFT(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice, args *testArgs) { - t.Helper() - - // Programming AFT entries for prefixes in DEFAULT VRF +func programAftWithMagicIp(t *testing.T, dut *ondatra.DUTDevice, args *testArgs) { args.client.Modify().AddEntry(t, fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(11).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port2").Name()), + WithIndex(11).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port2").Name()). + WithIPAddress(magicIp), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(12).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port3").Name()), + WithIndex(12).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port3").Name()). + WithIPAddress(magicIp), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(11).AddNextHop(11, 1).AddNextHop(12, 3), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF1+"/"+maskLen32).WithNextHopGroup(11), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(13).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port4").Name()), + WithIndex(13).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port4").Name()). + WithIPAddress(magicIp), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(12).AddNextHop(13, 2), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF2+"/"+maskLen32).WithNextHopGroup(12), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(14).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port5").Name()), + WithIndex(14).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port5").Name()). + WithIPAddress(magicIp), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(13).AddNextHop(14, 1), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF3+"/"+maskLen32).WithNextHopGroup(13), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(15).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port6").Name()), + WithIndex(15).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port6").Name()). + WithIPAddress(magicIp), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(14).AddNextHop(15, 1), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF4+"/"+maskLen32).WithNextHopGroup(14), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(16).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port7").Name()), + WithIndex(16).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port7").Name()). + WithIPAddress(magicIp), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(15).AddNextHop(16, 1), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF5+"/"+maskLen32).WithNextHopGroup(15), ) +} + +func configGribiBaselineAFT(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice, args *testArgs) { + t.Helper() + + if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { + programAftWithMagicIp(t, dut, args) + } else { + // Programming AFT entries for prefixes in DEFAULT VRF + args.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(11).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port2").Name()), + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(12).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port3").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(11).AddNextHop(11, 1).AddNextHop(12, 3), + fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(gribiIPv4EntryDefVRF1+"/"+maskLen32).WithNextHopGroup(11), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(13).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port4").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(12).AddNextHop(13, 2), + fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(gribiIPv4EntryDefVRF2+"/"+maskLen32).WithNextHopGroup(12), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(14).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port5").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(13).AddNextHop(14, 1), + fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(gribiIPv4EntryDefVRF3+"/"+maskLen32).WithNextHopGroup(13), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(15).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port6").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(14).AddNextHop(15, 1), + fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(gribiIPv4EntryDefVRF4+"/"+maskLen32).WithNextHopGroup(14), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(16).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port7").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(15).AddNextHop(16, 1), + fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(gribiIPv4EntryDefVRF5+"/"+maskLen32).WithNextHopGroup(15), + ) + } if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { t.Logf("Could not program entries via client, got err, check error codes: %v", err) } From f7cd7e6d56b53ea8aa9dfa1b0a60b19b57704b22 Mon Sep 17 00:00:00 2001 From: Yiwen Hu <163206410+g-yiwenhu@users.noreply.github.com> Date: Tue, 26 Mar 2024 18:20:34 +0000 Subject: [PATCH 43/97] ZR inventory test (#2817) * ZR inventory test * ZR inventory test * Fix bugs * Fix bugs --- .../tests/zr_inventory_test/README.md | 4 +- .../zr_inventory_test/metadata.textproto | 14 ++ .../zr_inventory_test/zr_inventory_test.go | 158 ++++++++++++++++++ 3 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_inventory_test/zr_inventory_test.go diff --git a/feature/platform/transceiver/tests/zr_inventory_test/README.md b/feature/platform/transceiver/tests/zr_inventory_test/README.md index bbb78e3bf09..d1cecb19411 100644 --- a/feature/platform/transceiver/tests/zr_inventory_test/README.md +++ b/feature/platform/transceiver/tests/zr_inventory_test/README.md @@ -1,4 +1,4 @@ -# TRANSCEIVER-7: Telemetry: 400ZR module inventory information. +# TRANSCEIVER-7: Telemetry: 400ZR Optics inventory info streaming ## Summary @@ -30,7 +30,7 @@ Validate 400ZR modules report correct inventory information. streaming telemetry paths above. * Reset the optic by enabling and disabling the transceiver state through /components/component/transceiver/config/enabled. - * Wait atleast 20 seconds in between toggling transceiver state. + * Wait at least 20 seconds in between toggling transceiver state. * Verify the ZR optics still reports correct inventory information. * Telemetry subscription should be ON_CHANGE and streamed data should be of type String. diff --git a/feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto b/feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto new file mode 100644 index 00000000000..e683efdcddf --- /dev/null +++ b/feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto @@ -0,0 +1,14 @@ +# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata +uuid: "376d3561-4271-4efc-be63-3eec7b56b86d" +plan_id: "TRANSCEIVER-7" +description: "Telemetry: 400ZR Optics inventory info streaming" +testbed: TESTBED_DUT_400ZR +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + } +} diff --git a/feature/platform/transceiver/tests/zr_inventory_test/zr_inventory_test.go b/feature/platform/transceiver/tests/zr_inventory_test/zr_inventory_test.go new file mode 100644 index 00000000000..9e09d65b9c1 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_inventory_test/zr_inventory_test.go @@ -0,0 +1,158 @@ +package zr_inventory_test + +import ( + "fmt" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +const ( + dp16QAM = 1 + samplingInterval = 10 * time.Second + timeout = 5 * time.Minute + waitInterval = 30 * time.Second +) + +const ( + frequency = 193100000 + targetOutputPower = -10 +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func configInterface(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port, frequency uint64, targetOutputPower float64) { + d := &oc.Root{} + i := d.GetOrCreateInterface(dp.Name()) + i.Enabled = ygot.Bool(true) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp.Name()).Config(), i) + c := opticalChannelComponentFromPort(t, dut1, dp) + gnmi.Replace(t, dut1, gnmi.OC().Component(c).OpticalChannel().Config(), &oc.Component_OpticalChannel{ + TargetOutputPower: ygot.Float64(targetOutputPower), + Frequency: ygot.Uint64(frequency), + }) +} + +func verifyAllInventoryValues(t *testing.T, pStreamsStr []*samplestream.SampleStream[string], pStreamsUnion []*samplestream.SampleStream[oc.Component_Type_Union]) { + for _, stream := range pStreamsStr { + inventoryStr := stream.Next() + if inventoryStr == nil { + t.Fatalf("Inventory telemetry %v was not streamed in the most recent subscription interval", stream) + } + inventoryVal, ok := inventoryStr.Val() + if !ok { + t.Fatalf("Inventory telemetry %q is not present or valid, expected ", inventoryStr) + } else { + t.Logf("Inventory telemetry %q is valid: %q", inventoryStr, inventoryVal) + } + } + + for _, stream := range pStreamsUnion { + inventoryUnion := stream.Next() + if inventoryUnion == nil { + t.Fatalf("Inventory telemetry %v was not streamed in the most recent subscription interval", stream) + } + inventoryVal, ok := inventoryUnion.Val() + if !ok { + t.Fatalf("Inventory telemetry %q is not present or valid, expected ", inventoryUnion) + } else { + t.Logf("Inventory telemetry %q is valid: %q", inventoryUnion, inventoryVal) + } + + } +} + +func TestInventory(t *testing.T) { + dut1 := ondatra.DUT(t, "dut") + dp1 := dut1.Port(t, "port1") + dp2 := dut1.Port(t, "port2") + fptest.ConfigureDefaultNetworkInstance(t, dut1) + + // Derive transceiver names from ports. + tr1 := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) + tr2 := gnmi.Get(t, dut1, gnmi.OC().Interface(dp2.Name()).Transceiver().State()) + + if (dp1.PMD() != ondatra.PMD400GBASEZR) || (dp2.PMD() != ondatra.PMD400GBASEZR) { + t.Fatalf("Transceivers types (%v, %v): (%v, %v) are not 400ZR, expected %v", tr1, tr2, dp1.PMD(), dp2.PMD(), ondatra.PMD400GBASEZR) + } + component1 := gnmi.OC().Component(tr1) + + configInterface(t, dut1, dp1, frequency, targetOutputPower) + configInterface(t, dut1, dp2, frequency, targetOutputPower) + // Wait for channels to be up. + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + + var p1StreamsStr []*samplestream.SampleStream[string] + var p1StreamsUnion []*samplestream.SampleStream[oc.Component_Type_Union] + p1StreamsStr = append(p1StreamsStr, + samplestream.New(t, dut1, component1.SerialNo().State(), samplingInterval), + samplestream.New(t, dut1, component1.PartNo().State(), samplingInterval), + samplestream.New(t, dut1, component1.MfgName().State(), samplingInterval), + samplestream.New(t, dut1, component1.MfgDate().State(), samplingInterval), + samplestream.New(t, dut1, component1.HardwareVersion().State(), samplingInterval), + samplestream.New(t, dut1, component1.FirmwareVersion().State(), samplingInterval), + samplestream.New(t, dut1, component1.Description().State(), samplingInterval), + ) + p1StreamsUnion = append(p1StreamsUnion, samplestream.New(t, dut1, component1.Type().State(), samplingInterval)) + + verifyAllInventoryValues(t, p1StreamsStr, p1StreamsUnion) + + // Disable or shut down the interface on the DUT. + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Enabled().Config(), false) + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp2.Name()).Enabled().Config(), false) + // Wait for channels to be down. + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_DOWN) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_DOWN) + + t.Logf("Interfaces are down: %v, %v", dp1.Name(), dp2.Name()) + verifyAllInventoryValues(t, p1StreamsStr, p1StreamsUnion) + + time.Sleep(waitInterval) + // Re-enable interfaces. + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Enabled().Config(), true) + gnmi.Replace(t, dut1, gnmi.OC().Interface(dp2.Name()).Enabled().Config(), true) + // Wait for channels to be up. + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) + + t.Logf("Interfaces are up: %v, %v", dp1.Name(), dp2.Name()) + verifyAllInventoryValues(t, p1StreamsStr, p1StreamsUnion) +} + +func opticalChannelComponentFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { + t.Helper() + if deviations.MissingPortToOpticalChannelMapping(dut) { + switch dut.Vendor() { + case ondatra.ARISTA: + transceiverName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).Transceiver().State()) + return fmt.Sprintf("%s-Optical0", transceiverName) + default: + t.Fatal("Manual Optical channel name required when deviation missing_port_to_optical_channel_component_mapping applied.") + } + } + compName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).HardwarePort().State()) + for { + comp, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(compName).State()).Val() + if !ok { + t.Fatalf("Recursive optical channel lookup failed for port: %s, component %s not found.", p.Name(), compName) + } + if comp.GetType() == oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL { + return compName + } + if comp.GetParent() == "" { + t.Fatalf("Recursive optical channel lookup failed for port: %s, parent of component %s not found.", p.Name(), compName) + } + compName = comp.GetParent() + } +} From 641593bb49ee0d25c39922eba4282228ecb77a96 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Tue, 26 Mar 2024 12:37:14 -0700 Subject: [PATCH 44/97] Update description and add paths to coverage (#2798) --- .../otg_tests/link_bandwidth_test/README.md | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md b/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md index 743a2401fcd..22ad233b580 100644 --- a/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md +++ b/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md @@ -1,9 +1,9 @@ -# RT-7.5: BGP Policy - Set Link Bandwidth Community +# RT-7.5: BGP Policy - Match and Set Link Bandwidth Community ## Summary -Configure bgp policy to add statically configured BGP link bandwidth -communities to routes based on a prefix match. +Configure bgp policy to match, add and delete statically configured BGP link +bandwidth communities to routes based on a prefix match. ## Testbed type @@ -45,7 +45,7 @@ communities to routes based on a prefix match. * ext-community-member = [ "link-bandwidth:100:1M" ] * Create an ext-community-set named 'linkbw_2G' with members as follows: * ext-community-member = [ "link-bandwidth:100:2G" ] - * Create an community-set named 'regex_match_as100' with members as follows: + * Create an community-set named 'regex_match_comm100' with members as follows: * community-member = [ "^100:.*$" ] * Create an ext-community-set named 'linkbw_any' with members as follows: * ext-community-member = [ "^link-bandwidth:.*:.*$" ] @@ -65,7 +65,7 @@ communities to routes based on a prefix match. * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` named **'not_match_100_set_linkbw_1M'** with the following `statements` * statement[name='1-megabit-match']/ - * conditions/bgp-conditions/match-community-set/config/community-set = 'regex_match_as100' + * conditions/bgp-conditions/match-community-set/config/community-set = 'regex_match_comm100' * conditions/bgp-conditions/match-community-set/config/match-set-options = INVERT * actions/bgp-actions/set-ext-community/reference/config/ext-community-set-refs = 'linkbw_1M' * actions/config/policy-result = NEXT_STATEMENT @@ -75,7 +75,7 @@ communities to routes based on a prefix match. * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` named 'match_100_set_linkbw_2G' with the following `statements` * statement[name='2-gigabit-match']/ - * conditions/bgp-conditions/match-community-set/config/community-set = 'regex_match_as100' + * conditions/bgp-conditions/match-community-set/config/community-set = 'regex_match_comm100' * conditions/bgp-conditions/match-community-set/config/match-set-options = ANY * actions/bgp-actions/set-ext-community/reference/config/ext-community-set-refs = 'linkbw_2G' * actions/config/policy-result = NEXT_STATEMENT @@ -116,7 +116,7 @@ communities to routes based on a prefix match. * `/network-instances/network-instance/protocols/protocol/bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-in-post/routes/route/state/ext-community-index` * Expected community values for each policy - | | zero_linkbw | not_match_100_set_linkbw_1M | + | | set_linkbw_0 | not_match_100_set_linkbw_1M | | ------------ | -------------------------------------- | --------------------------- | | prefix-set-1 | [ "link-bandwidth:100:0" ] | [none] | | prefix-set-2 | [ "100:100", "link-bandwidth:100:0" ] | [ "100:100" ] | @@ -158,11 +158,16 @@ communities to routes based on a prefix match. * /routing-policy/policy-definitions/policy-definition/config/name * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name +* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result +* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-ext-community/config/options +* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/config/method * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-ext-community/reference/config/ext-community-set-refs +* /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-local-pref + ### Policy for community-set match configuration -* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/config/community-set +* /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-ext-community-set/config/community-set * /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-ext-community-set/config/match-set-options ### Policy attachment point configuration From 2f20e39f9f2830498302d856d215f7271faeeda9 Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Tue, 26 Mar 2024 14:21:32 -0700 Subject: [PATCH 45/97] Validate textproto files in PR check (#2846) --- .github/workflows/protobufs.yml | 56 +++---------------- Makefile | 43 ++++++++++---- feature/acl/feature.textproto | 2 + .../metadata.textproto | 2 +- feature/aft/feature.textproto | 3 + feature/bgp/addpath/feature.textproto | 3 + feature/bgp/aspath/feature.textproto | 3 + feature/bgp/bestpath/feature.textproto | 3 + .../bgp/dynamicneighbors/feature.textproto | 3 + feature/bgp/feature.textproto | 3 + feature/bgp/gracefulrestart/feature.textproto | 3 + feature/bgp/multihop/feature.textproto | 3 + feature/bgp/multipath/feature.textproto | 3 + feature/bgp/policybase/feature.textproto | 3 + .../import_export_multi/metadata.textproto | 2 +- .../nested_policies/metadata.textproto | 2 +- feature/bgp/prefixlimit/feature.textproto | 3 + feature/bgp/routereflector/feature.textproto | 3 + .../gribi_ip4_entry/feature.textproto | 3 + .../feature.textproto | 3 + .../telemetry_port_speed/feature.textproto | 3 + .../backup_nhg_action_pbf/metadata.textproto | 2 +- .../feature.textproto | 3 + .../feature.textproto | 3 + .../aggregate_interfaces/feature.textproto | 3 + .../policy/policy_base/feature.textproto | 3 + .../policy_vrf_selection/feature.textproto | 3 + .../route_redistribution/feature.textproto | 3 + .../telemetry_only/feature.textproto | 3 + feature/gnoi/factory_reset/feature.textproto | 3 + feature/gnoi/file/feature.textproto | 3 + feature/gnoi/healthz/feature.textproto | 3 + feature/gnoi/os/feature.textproto | 3 + .../feature.textproto | 3 + feature/gnoi/system/feature.textproto | 3 + feature/gribi/feature.textproto | 3 + .../metadata.textproto | 2 +- feature/interface/aggregate/feature.textproto | 3 + feature/interface/holdtime/feature.textproto | 3 + feature/interface/ip/feature.textproto | 3 + feature/interface/singleton/feature.textproto | 3 + feature/interface/staticarp/feature.textproto | 3 + feature/isis/auth/feature.textproto | 2 + feature/isis/feature.textproto | 3 + .../link_state_database/feature.textproto | 3 + .../weighted_ecmp_test/metadata.textproto | 2 +- feature/lldp/feature.textproto | 3 + feature/localaggregates/feature.textproto | 3 + feature/networkinstance/feature.textproto | 3 + .../metadata.textproto | 2 +- .../platform/controllercard/feature.textproto | 3 + feature/platform/fabric/feature.textproto | 3 + .../metadata.textproto | 2 +- .../tests/zr_cd_test/metadata.textproto | 2 +- feature/qos/ecn/feature.textproto | 3 + feature/qos/feature.textproto | 3 + feature/security/gnsi/acctz/feature.textproto | 3 + feature/security/gnsi/authz/feature.textproto | 3 + feature/security/gnsi/certz/feature.textproto | 3 + .../gnsi/credentialz/feature.textproto | 3 + feature/sflow/feature.textproto | 3 + .../sflow_base_test/metadata.textproto | 2 +- feature/staticroute/feature.textproto | 3 + feature/system/aaa/feature.textproto | 3 + feature/system/attestz/feature.textproto | 3 + feature/system/bootz/feature.textproto | 3 + feature/system/feature.textproto | 3 + .../system/gnmi/cliorigin/feature.textproto | 3 + feature/system/gnmi/feature.textproto | 3 + feature/system/gnmi/get/feature.textproto | 3 + .../system/gnmi/metadata/feature.textproto | 3 + .../metadata.textproto | 2 +- feature/system/gnmi/set/feature.textproto | 3 + .../logging/remote_syslog/feature.textproto | 3 + feature/system/ntp/feature.textproto | 3 + topologies/kne/arista/ceos/dut.textproto | 2 + topologies/kne/arista/ceos/dutate.textproto | 2 + .../kne/arista/ceos/dutate_lag.textproto | 2 + topologies/kne/arista/ceos/dutdut.textproto | 2 + .../kne/arista/ceos/dutdutate.textproto | 2 + topologies/kne/arista/ceos/topology.textproto | 2 + topologies/kne/cisco/8000e/dut.textproto | 2 + topologies/kne/cisco/8000e/dutate.textproto | 2 + .../kne/cisco/8000e/dutate_lag.textproto | 2 + topologies/kne/cisco/8000e/dutdut.textproto | 2 + .../kne/cisco/8000e/dutdutate.textproto | 2 + topologies/kne/cisco/8000e/topology.textproto | 2 + topologies/kne/cisco/xrd/dut.textproto | 2 + topologies/kne/cisco/xrd/dutate.textproto | 2 + topologies/kne/cisco/xrd/dutate_lag.textproto | 2 + topologies/kne/cisco/xrd/dutdut.textproto | 2 + topologies/kne/cisco/xrd/dutdutate.textproto | 2 + topologies/kne/cisco/xrd/topology.textproto | 2 + topologies/kne/juniper/ncptx/dut.textproto | 2 + topologies/kne/juniper/ncptx/dutate.textproto | 2 + .../kne/juniper/ncptx/dutate_lag.textproto | 2 + topologies/kne/juniper/ncptx/dutdut.textproto | 2 + .../kne/juniper/ncptx/dutdutate.textproto | 2 + .../kne/juniper/ncptx/topology.textproto | 2 + topologies/kne/nokia/srlinux/dut.textproto | 2 + topologies/kne/nokia/srlinux/dutate.textproto | 2 + .../kne/nokia/srlinux/dutate_lag.textproto | 2 + topologies/kne/nokia/srlinux/dutdut.textproto | 2 + .../kne/nokia/srlinux/dutdutate.textproto | 2 + .../kne/nokia/srlinux/topology.textproto | 2 + .../kne/openconfig/lemming/dut.textproto | 2 + .../kne/openconfig/lemming/dutate.textproto | 2 + .../openconfig/lemming/dutate_lag.textproto | 2 + .../kne/openconfig/lemming/dutdut.textproto | 2 + .../openconfig/lemming/dutdutate.textproto | 2 + .../kne/openconfig/lemming/topology.textproto | 2 + topologies/proto/binding/binding.pb.go | 9 +-- topologies/proto/generate.sh | 35 ------------ 113 files changed, 313 insertions(+), 108 deletions(-) delete mode 100755 topologies/proto/generate.sh diff --git a/.github/workflows/protobufs.yml b/.github/workflows/protobufs.yml index 9adfc76c18d..e645507fc8e 100644 --- a/.github/workflows/protobufs.yml +++ b/.github/workflows/protobufs.yml @@ -33,56 +33,16 @@ jobs: - name: Lint protobufs run: | go install github.com/googleapis/api-linter/cmd/api-linter@latest - # Set directory to hold symlink - readonly PROTOBUF_IMPORT_DIR='protobuf-import' - mkdir -p "${PROTOBUF_IMPORT_DIR}" - # Remove any existing symlinks & empty directories - find "${PROTOBUF_IMPORT_DIR}" -type l -delete - find "${PROTOBUF_IMPORT_DIR}" -type d -empty -delete - # Download the required dependencies - go mod download - # Copy all of the proto files into the right directory. - fp_proto_dir="${PROTOBUF_IMPORT_DIR}/github.com/openconfig/featureprofiles" - mkdir -p "${fp_proto_dir}" - cp --parents `find -name \*.proto` "${fp_proto_dir}" - # Get ondatra modules we use and create required directory structure - go list -f "${PROTOBUF_IMPORT_DIR}/{{ .Path }}" -m github.com/openconfig/ondatra | xargs -L1 dirname | sort | uniq | xargs mkdir -p - # Create symlink - go list -f "{{ .Dir }} "${PROTOBUF_IMPORT_DIR}"/{{ .Path }}" -m github.com/openconfig/ondatra | xargs -L1 -- ln -s - cd "${fp_proto_dir}" - find . -name \*.proto -exec api-linter -I"${OLDPWD}"/"${PROTOBUF_IMPORT_DIR}" --disable-rule all --enable-rule core {} \+ - - name: Compile topology binding textprotos + make protoimports + cd protobuf-import + find github.com/openconfig/featureprofiles/ -name \*.proto -exec api-linter --disable-rule all --enable-rule core {} \+ + - name: Validate textprotos run: | - fail=0 - # Set directory to hold symlink - readonly PROTOBUF_IMPORT_DIR='protobuf-import' - mkdir -p "${PROTOBUF_IMPORT_DIR}" - # Remove any existing symlinks & empty directories - find "${PROTOBUF_IMPORT_DIR}" -type l -delete - find "${PROTOBUF_IMPORT_DIR}" -type d -empty -delete - # Download the required dependencies - go mod download - # Get ondatra modules we use and create required directory structure - go list -f "${PROTOBUF_IMPORT_DIR}/{{ .Path }}" -m github.com/openconfig/ondatra | xargs -L1 dirname | sort | uniq | xargs mkdir -p - # Create symlink - go list -f "{{ .Dir }} \"${PROTOBUF_IMPORT_DIR}\"/{{ .Path }}" -m github.com/openconfig/ondatra | xargs -L1 -- ln -s - for i in `find topologies/ -type f -name "*.binding"`; do - if ! output=$(protoc -I="${PROTOBUF_IMPORT_DIR}" --proto_path=topologies/proto --encode=openconfig.testing.Binding topologies/proto/binding.proto < $i 2>&1 >/dev/null); then - fail=1 - echo -e "Compile $i failed:\n$output\n" - fi - done - if [ "$fail" == "1" ]; then exit 1; fi - - name: Compile feature profile textprotos - run: | - fail=0 - for i in `find feature/ -type f -name "feature.textproto"`; do - if ! output=$(protoc --encode=openconfig.profiles.FeatureProfile proto/feature.proto < $i 2>&1 >/dev/null); then - fail=1 - echo -e "Compile $i failed:\n$output\n" - fi + go install github.com/bstoll/textproto-validator@latest + make protoimports + for i in `find . -name \*.textproto`; do + textproto-validator -I ./protobuf-import $i done - if [ "$fail" == "1" ]; then exit 1; fi validate_oc_paths: name: Validate OpenConfig Paths diff --git a/Makefile b/Makefile index 45756fbd5f5..ffe2ca29f5e 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,16 @@ # 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. + +ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) +GO_PROTOS:=proto/feature_go_proto/feature.pb.go proto/metadata_go_proto/metadata.pb.go proto/ocpaths_go_proto/ocpaths.pb.go proto/ocrpcs_go_proto/ocrpcs.pb.go proto/nosimage_go_proto/nosimage.pb.go topologies/proto/binding/binding.pb.go + +.PHONY: all clean protos validate_paths protoimports +all: openconfig_public protos validate_paths + openconfig_public: tools/clone_oc_public.sh openconfig_public -.PHONY: validate_paths validate_paths: openconfig_public proto/feature_go_proto/feature.pb.go go run -v tools/validate_paths.go \ -alsologtostderr \ @@ -23,12 +29,9 @@ validate_paths: openconfig_public proto/feature_go_proto/feature.pb.go --yang_skip_roots=$(CURDIR)/openconfig_public/release/models/wifi \ --feature_files=${FEATURE_FILES} -proto/feature_go_proto/feature.pb.go: proto/feature.proto - mkdir -p proto/feature_go_proto - protoc --proto_path=proto --go_out=./ --go_opt=Mfeature.proto=proto/feature_go_proto feature.proto +protos: $(GO_PROTOS) -proto/metadata_go_proto/metadata.pb.go: proto/metadata.proto - mkdir -p proto/metadata_go_proto +protoimports: # Set directory to hold symlink mkdir -p protobuf-import # Remove any existing symlinks & empty directories @@ -36,10 +39,21 @@ proto/metadata_go_proto/metadata.pb.go: proto/metadata.proto find protobuf-import -type d -empty -delete # Download the required dependencies go mod download - # Get ondatra modules we use and create required directory structure + # Get ondatra & kne modules we use and create required directory structure go list -f 'protobuf-import/{{ .Path }}' -m github.com/openconfig/ondatra | xargs -L1 dirname | sort | uniq | xargs mkdir -p - # Create symlink + go list -f 'protobuf-import/{{ .Path }}' -m github.com/openconfig/kne | xargs -L1 dirname | sort | uniq | xargs mkdir -p + # Create symlinks go list -f '{{ .Dir }} protobuf-import/{{ .Path }}' -m github.com/openconfig/ondatra | xargs -L1 -- ln -s + go list -f '{{ .Dir }} protobuf-import/{{ .Path }}' -m github.com/openconfig/kne | xargs -L1 -- ln -s + ln -s $(ROOT_DIR) protobuf-import/github.com/openconfig/featureprofiles + +proto/feature_go_proto/feature.pb.go: proto/feature.proto + mkdir -p proto/feature_go_proto + protoc --proto_path=proto --go_out=./ --go_opt=Mfeature.proto=proto/feature_go_proto feature.proto + goimports -w proto/feature_go_proto/feature.pb.go + +proto/metadata_go_proto/metadata.pb.go: proto/metadata.proto protoimports + mkdir -p proto/metadata_go_proto protoc -I='protobuf-import' --proto_path=proto --go_out=./ --go_opt=Mmetadata.proto=proto/metadata_go_proto metadata.proto goimports -w proto/metadata_go_proto/metadata.pb.go @@ -53,7 +67,16 @@ proto/ocrpcs_go_proto/ocrpcs.pb.go: proto/ocrpcs.proto protoc --proto_path=proto --go_out=./ --go_opt=Mocrpcs.proto=proto/ocrpcs_go_proto ocrpcs.proto goimports -w proto/ocrpcs_go_proto/ocrpcs.pb.go -proto/nosimage_go_proto/nosimage.pb.go: proto/nosimage.proto +proto/nosimage_go_proto/nosimage.pb.go: proto/nosimage.proto protoimports mkdir -p proto/nosimage_go_proto - protoc -I="${GOPATH}/src" --proto_path=proto --go_out=./proto/nosimage_go_proto --go_opt=paths=source_relative --go_opt=Mnosimage.proto=proto/nosimage_go_proto --go_opt=Mgithub.com/openconfig/featureprofiles/proto/ocpaths.proto=github.com/openconfig/featureprofiles/proto/ocpaths_go_proto --go_opt=Mgithub.com/openconfig/featureprofiles/proto/ocrpcs.proto=github.com/openconfig/featureprofiles/proto/ocrpcs_go_proto nosimage.proto + protoc -I='protobuf-import' --proto_path=proto --go_out=./proto/nosimage_go_proto --go_opt=paths=source_relative --go_opt=Mnosimage.proto=proto/nosimage_go_proto --go_opt=Mgithub.com/openconfig/featureprofiles/proto/ocpaths.proto=github.com/openconfig/featureprofiles/proto/ocpaths_go_proto --go_opt=Mgithub.com/openconfig/featureprofiles/proto/ocrpcs.proto=github.com/openconfig/featureprofiles/proto/ocrpcs_go_proto nosimage.proto goimports -w proto/nosimage_go_proto/nosimage.pb.go + +topologies/proto/binding/binding.pb.go: topologies/proto/binding.proto protoimports + mkdir -p topologies/proto/binding + protoc -I='protobuf-import' --proto_path=topologies/proto --go_out=. --go_opt=Mbinding.proto=topologies/proto/binding binding.proto + goimports -w topologies/proto/binding/binding.pb.go + +clean: + rm -f $(GO_PROTOS) + rm -rf protobuf-import openconfig_public diff --git a/feature/acl/feature.textproto b/feature/acl/feature.textproto index d29f33b888a..a85969cdf78 100644 --- a/feature/acl/feature.textproto +++ b/feature/acl/feature.textproto @@ -11,6 +11,8 @@ # 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. +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "acl" diff --git a/feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto b/feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto index 7decf64f6e7..1031dcd2e0c 100644 --- a/feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto +++ b/feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "ef34466c-37da-4133-8d03-40ebe2a5168a" diff --git a/feature/aft/feature.textproto b/feature/aft/feature.textproto index f85d65be8d0..b8ec741be44 100644 --- a/feature/aft/feature.textproto +++ b/feature/aft/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "aft" diff --git a/feature/bgp/addpath/feature.textproto b/feature/bgp/addpath/feature.textproto index 8500d916f14..36293f0cccd 100644 --- a/feature/bgp/addpath/feature.textproto +++ b/feature/bgp/addpath/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_addpath" diff --git a/feature/bgp/aspath/feature.textproto b/feature/bgp/aspath/feature.textproto index 1faad483376..e82b142eb54 100644 --- a/feature/bgp/aspath/feature.textproto +++ b/feature/bgp/aspath/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_aspath" diff --git a/feature/bgp/bestpath/feature.textproto b/feature/bgp/bestpath/feature.textproto index 05e2c3ed899..48d03763a8f 100644 --- a/feature/bgp/bestpath/feature.textproto +++ b/feature/bgp/bestpath/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_bestpath" diff --git a/feature/bgp/dynamicneighbors/feature.textproto b/feature/bgp/dynamicneighbors/feature.textproto index 9d374d8eaa6..10b2877f662 100644 --- a/feature/bgp/dynamicneighbors/feature.textproto +++ b/feature/bgp/dynamicneighbors/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_dynamicneighbors" diff --git a/feature/bgp/feature.textproto b/feature/bgp/feature.textproto index 943c9169ad1..fcc9e02b447 100644 --- a/feature/bgp/feature.textproto +++ b/feature/bgp/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp" diff --git a/feature/bgp/gracefulrestart/feature.textproto b/feature/bgp/gracefulrestart/feature.textproto index 8de12815c8c..4e28255f0f0 100644 --- a/feature/bgp/gracefulrestart/feature.textproto +++ b/feature/bgp/gracefulrestart/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_gracefulrestart" diff --git a/feature/bgp/multihop/feature.textproto b/feature/bgp/multihop/feature.textproto index 1a685ee3ca2..d5a4431e9e8 100644 --- a/feature/bgp/multihop/feature.textproto +++ b/feature/bgp/multihop/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_multihop" diff --git a/feature/bgp/multipath/feature.textproto b/feature/bgp/multipath/feature.textproto index 088fa111aa5..af19a786e95 100644 --- a/feature/bgp/multipath/feature.textproto +++ b/feature/bgp/multipath/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_multipath" diff --git a/feature/bgp/policybase/feature.textproto b/feature/bgp/policybase/feature.textproto index d8863bca301..645d0930e23 100644 --- a/feature/bgp/policybase/feature.textproto +++ b/feature/bgp/policybase/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_policybase" diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto b/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto index fdbbd48c5b7..079f8dfbd6f 100644 --- a/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto @@ -4,4 +4,4 @@ plan_id: "RT-7.11" description: "BGP Policy - Import/Export Policy Action Using Multiple Criteria" testbed: TESTBED_DUT_ATE_2LINKS -tags: TAGS_AGGREGATION, TAGS_DATACENTER_EDGE +tags: [TAGS_AGGREGATION, TAGS_DATACENTER_EDGE] diff --git a/feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto b/feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto index aa30373eed8..e6691f8f821 100644 --- a/feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/nested_policies/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "aa9b83cb-fd87-4098-ab3d-db05c66fc3c0" plan_id: "RT-1.30" diff --git a/feature/bgp/prefixlimit/feature.textproto b/feature/bgp/prefixlimit/feature.textproto index 23aec8e81c3..0ecbb09d46a 100644 --- a/feature/bgp/prefixlimit/feature.textproto +++ b/feature/bgp/prefixlimit/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_prefixlimit" diff --git a/feature/bgp/routereflector/feature.textproto b/feature/bgp/routereflector/feature.textproto index 7bdb66535ea..a1b04315f79 100644 --- a/feature/bgp/routereflector/feature.textproto +++ b/feature/bgp/routereflector/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "bgp_routereflector" diff --git a/feature/experimental/basic_entries_installed_in_gribi/gribi_ip4_entry/feature.textproto b/feature/experimental/basic_entries_installed_in_gribi/gribi_ip4_entry/feature.textproto index ed5c0b71946..14e9565fdd7 100644 --- a/feature/experimental/basic_entries_installed_in_gribi/gribi_ip4_entry/feature.textproto +++ b/feature/experimental/basic_entries_installed_in_gribi/gribi_ip4_entry/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_basic_entries_installed_in_gribi_gribi_ip4_entry" diff --git a/feature/experimental/gnmi_service/benchmarking_drained_configuration_convergence_time/feature.textproto b/feature/experimental/gnmi_service/benchmarking_drained_configuration_convergence_time/feature.textproto index 9893a032bf4..fc6bb224159 100644 --- a/feature/experimental/gnmi_service/benchmarking_drained_configuration_convergence_time/feature.textproto +++ b/feature/experimental/gnmi_service/benchmarking_drained_configuration_convergence_time/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_gnmi_service_benchmarking_drained_configuration_convergence_time" diff --git a/feature/experimental/gnmi_service/telemetry_port_speed/feature.textproto b/feature/experimental/gnmi_service/telemetry_port_speed/feature.textproto index 29b1af29b18..f7a6d7df109 100644 --- a/feature/experimental/gnmi_service/telemetry_port_speed/feature.textproto +++ b/feature/experimental/gnmi_service/telemetry_port_speed/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_gnmi_service_telemetry_port_speed" diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto b/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto index 1de5ed3f110..f7a83ce9600 100644 --- a/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto +++ b/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "e4ec3769-86eb-41c8-8600-f8835cdcf0a6" diff --git a/feature/experimental/hierarchical_gribi_entries/base_hierarchical_route_installation/feature.textproto b/feature/experimental/hierarchical_gribi_entries/base_hierarchical_route_installation/feature.textproto index 36675d5be9c..f4d10b21f31 100644 --- a/feature/experimental/hierarchical_gribi_entries/base_hierarchical_route_installation/feature.textproto +++ b/feature/experimental/hierarchical_gribi_entries/base_hierarchical_route_installation/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_hierarchical_gribi_entries_base_hierarchical_route_installation" diff --git a/feature/experimental/hierarchical_gribi_entries/traffic_balancing_according_to_weights/feature.textproto b/feature/experimental/hierarchical_gribi_entries/traffic_balancing_according_to_weights/feature.textproto index a18ae203662..2f8a1e24a06 100644 --- a/feature/experimental/hierarchical_gribi_entries/traffic_balancing_according_to_weights/feature.textproto +++ b/feature/experimental/hierarchical_gribi_entries/traffic_balancing_according_to_weights/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_hierarchical_gribi_entries_traffic_balancing_according_to_weights" diff --git a/feature/experimental/lacp_and_base_interface/aggregate_interfaces/feature.textproto b/feature/experimental/lacp_and_base_interface/aggregate_interfaces/feature.textproto index a96add04cd9..b9f58a8ae68 100644 --- a/feature/experimental/lacp_and_base_interface/aggregate_interfaces/feature.textproto +++ b/feature/experimental/lacp_and_base_interface/aggregate_interfaces/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_lacp_and_base_interface_aggregate_interfaces" diff --git a/feature/experimental/policy/policy_base/feature.textproto b/feature/experimental/policy/policy_base/feature.textproto index e1e3a20a9e4..e0799b0980c 100644 --- a/feature/experimental/policy/policy_base/feature.textproto +++ b/feature/experimental/policy/policy_base/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_policy_policy_base" diff --git a/feature/experimental/policy/policy_vrf_selection/feature.textproto b/feature/experimental/policy/policy_vrf_selection/feature.textproto index 8a0ef73150f..a5262ef5612 100644 --- a/feature/experimental/policy/policy_vrf_selection/feature.textproto +++ b/feature/experimental/policy/policy_vrf_selection/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_policy_policy_vrf_selection" diff --git a/feature/experimental/route_redistribution/feature.textproto b/feature/experimental/route_redistribution/feature.textproto index b91b55c46c8..fa276b3ca6b 100644 --- a/feature/experimental/route_redistribution/feature.textproto +++ b/feature/experimental/route_redistribution/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_route_redistribution" diff --git a/feature/experimental/telemetry_only/feature.textproto b/feature/experimental/telemetry_only/feature.textproto index b8f75e48085..829203c9478 100644 --- a/feature/experimental/telemetry_only/feature.textproto +++ b/feature/experimental/telemetry_only/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "experimental_telemetry_only" diff --git a/feature/gnoi/factory_reset/feature.textproto b/feature/gnoi/factory_reset/feature.textproto index df72586373f..eaa711ccaa3 100644 --- a/feature/gnoi/factory_reset/feature.textproto +++ b/feature/gnoi/factory_reset/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "gnoi_factory_reset" diff --git a/feature/gnoi/file/feature.textproto b/feature/gnoi/file/feature.textproto index 151fc0b1102..fda97967dee 100644 --- a/feature/gnoi/file/feature.textproto +++ b/feature/gnoi/file/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "gnoi_file" diff --git a/feature/gnoi/healthz/feature.textproto b/feature/gnoi/healthz/feature.textproto index fdfdc06fe22..b7fcef86a4e 100644 --- a/feature/gnoi/healthz/feature.textproto +++ b/feature/gnoi/healthz/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "gnoi_healthz" diff --git a/feature/gnoi/os/feature.textproto b/feature/gnoi/os/feature.textproto index 6054dc78c1e..765f2044a91 100644 --- a/feature/gnoi/os/feature.textproto +++ b/feature/gnoi/os/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "gnoi_os" diff --git a/feature/gnoi/packet_link_qualification/feature.textproto b/feature/gnoi/packet_link_qualification/feature.textproto index 8d710ba0d81..e03f8b71b8f 100644 --- a/feature/gnoi/packet_link_qualification/feature.textproto +++ b/feature/gnoi/packet_link_qualification/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "gnoi_packet_link_qualification" diff --git a/feature/gnoi/system/feature.textproto b/feature/gnoi/system/feature.textproto index 6a9904718c6..32f544193ad 100644 --- a/feature/gnoi/system/feature.textproto +++ b/feature/gnoi/system/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "gnoi_system" diff --git a/feature/gribi/feature.textproto b/feature/gribi/feature.textproto index 3fca4d03ce8..6245f883738 100644 --- a/feature/gribi/feature.textproto +++ b/feature/gribi/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "gribi" diff --git a/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/metadata.textproto b/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/metadata.textproto index c84b014a0e7..896ce8a0e42 100644 --- a/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/metadata.textproto +++ b/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "6cd082df-8344-4d75-b148-db572c387433" diff --git a/feature/interface/aggregate/feature.textproto b/feature/interface/aggregate/feature.textproto index 8be6a9fbbc5..5345b167a3f 100644 --- a/feature/interface/aggregate/feature.textproto +++ b/feature/interface/aggregate/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "interface_aggregate" diff --git a/feature/interface/holdtime/feature.textproto b/feature/interface/holdtime/feature.textproto index 881dc8f0047..26920b39624 100644 --- a/feature/interface/holdtime/feature.textproto +++ b/feature/interface/holdtime/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "interface_holdtime" diff --git a/feature/interface/ip/feature.textproto b/feature/interface/ip/feature.textproto index fefb8ec57b8..b03ede8d819 100644 --- a/feature/interface/ip/feature.textproto +++ b/feature/interface/ip/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "interface_ip" diff --git a/feature/interface/singleton/feature.textproto b/feature/interface/singleton/feature.textproto index 35588043c7e..62fad1c9fc6 100644 --- a/feature/interface/singleton/feature.textproto +++ b/feature/interface/singleton/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "interface_singleton" diff --git a/feature/interface/staticarp/feature.textproto b/feature/interface/staticarp/feature.textproto index db7a4240b41..0dfd3be72c5 100644 --- a/feature/interface/staticarp/feature.textproto +++ b/feature/interface/staticarp/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "interface_staticarp" diff --git a/feature/isis/auth/feature.textproto b/feature/isis/auth/feature.textproto index 8f1c6148786..0300d1bc3ad 100644 --- a/feature/isis/auth/feature.textproto +++ b/feature/isis/auth/feature.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "isis_auth" diff --git a/feature/isis/feature.textproto b/feature/isis/feature.textproto index cef1e4f81f6..aaa62b80e57 100644 --- a/feature/isis/feature.textproto +++ b/feature/isis/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "isis" version: 3 diff --git a/feature/isis/link_state_database/feature.textproto b/feature/isis/link_state_database/feature.textproto index 1cbee0d69ae..bb823bb97d6 100644 --- a/feature/isis/link_state_database/feature.textproto +++ b/feature/isis/link_state_database/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "isis_link_state_database" version: 1 diff --git a/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto b/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto index 560a8eb30ed..505f52a5505 100644 --- a/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto +++ b/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "2beaac46-9b7b-49c4-9bde-62ad530aa5c4" diff --git a/feature/lldp/feature.textproto b/feature/lldp/feature.textproto index 4016a95d96f..50ba028ca87 100644 --- a/feature/lldp/feature.textproto +++ b/feature/lldp/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "lldp" version: 1 diff --git a/feature/localaggregates/feature.textproto b/feature/localaggregates/feature.textproto index 445dadfead2..dc5c76ea7fa 100644 --- a/feature/localaggregates/feature.textproto +++ b/feature/localaggregates/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "localaggregates" diff --git a/feature/networkinstance/feature.textproto b/feature/networkinstance/feature.textproto index 98cef284592..10e9b7da93c 100644 --- a/feature/networkinstance/feature.textproto +++ b/feature/networkinstance/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "networkinstance" diff --git a/feature/p4rt/otg_tests/p4rt_daemon_failure_test/metadata.textproto b/feature/p4rt/otg_tests/p4rt_daemon_failure_test/metadata.textproto index 53b71895f77..d9063936e7a 100644 --- a/feature/p4rt/otg_tests/p4rt_daemon_failure_test/metadata.textproto +++ b/feature/p4rt/otg_tests/p4rt_daemon_failure_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "78f99d29-c7db-4e6d-8284-614154efc0d1" diff --git a/feature/platform/controllercard/feature.textproto b/feature/platform/controllercard/feature.textproto index c406648800d..d8b1bda06cb 100644 --- a/feature/platform/controllercard/feature.textproto +++ b/feature/platform/controllercard/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "platform_controllercard" version: 1 diff --git a/feature/platform/fabric/feature.textproto b/feature/platform/fabric/feature.textproto index b0ec826b2db..b86f5634e1f 100644 --- a/feature/platform/fabric/feature.textproto +++ b/feature/platform/fabric/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "platform_fabric" version: 1 diff --git a/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/metadata.textproto b/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/metadata.textproto index 52f4163134e..7c618627449 100644 --- a/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/metadata.textproto +++ b/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "ef804c64-84dd-432d-ab38-630e9c82b42d" diff --git a/feature/platform/transceiver/tests/zr_cd_test/metadata.textproto b/feature/platform/transceiver/tests/zr_cd_test/metadata.textproto index a410a8e7339..5810d2322b9 100644 --- a/feature/platform/transceiver/tests/zr_cd_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_cd_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "6c7ec460-10be-4c71-81f5-888f76ef241b" plan_id: "TRANSCEIVER-1" diff --git a/feature/qos/ecn/feature.textproto b/feature/qos/ecn/feature.textproto index a7840e719cb..b76984b3c87 100644 --- a/feature/qos/ecn/feature.textproto +++ b/feature/qos/ecn/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "qos_ecn" version: 1 diff --git a/feature/qos/feature.textproto b/feature/qos/feature.textproto index 49b504206a7..4e439a3762d 100644 --- a/feature/qos/feature.textproto +++ b/feature/qos/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "qos" version: 1 diff --git a/feature/security/gnsi/acctz/feature.textproto b/feature/security/gnsi/acctz/feature.textproto index 15e0ef02b2b..76c8f93c5c5 100644 --- a/feature/security/gnsi/acctz/feature.textproto +++ b/feature/security/gnsi/acctz/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "security_gnsi_acctz" version: 0 diff --git a/feature/security/gnsi/authz/feature.textproto b/feature/security/gnsi/authz/feature.textproto index ee175c6ff74..183c61709fa 100644 --- a/feature/security/gnsi/authz/feature.textproto +++ b/feature/security/gnsi/authz/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "security_gnsi_authz" diff --git a/feature/security/gnsi/certz/feature.textproto b/feature/security/gnsi/certz/feature.textproto index 92288a1e337..e12f9bcbf7d 100644 --- a/feature/security/gnsi/certz/feature.textproto +++ b/feature/security/gnsi/certz/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "security_gnsi_certz" diff --git a/feature/security/gnsi/credentialz/feature.textproto b/feature/security/gnsi/credentialz/feature.textproto index 964ff8207a1..4bfd23a1c3f 100644 --- a/feature/security/gnsi/credentialz/feature.textproto +++ b/feature/security/gnsi/credentialz/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "security_gnsi_credentialz" diff --git a/feature/sflow/feature.textproto b/feature/sflow/feature.textproto index 2bf860d0b8f..e253000ce58 100644 --- a/feature/sflow/feature.textproto +++ b/feature/sflow/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "sflow" diff --git a/feature/sflow/otg_tests/sflow_base_test/metadata.textproto b/feature/sflow/otg_tests/sflow_base_test/metadata.textproto index 78c6dc422dd..d34f121c0cb 100644 --- a/feature/sflow/otg_tests/sflow_base_test/metadata.textproto +++ b/feature/sflow/otg_tests/sflow_base_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "25b389ff-8526-46e3-acf2-016e86aff406" diff --git a/feature/staticroute/feature.textproto b/feature/staticroute/feature.textproto index ca5a09a3f02..9ee16d1323e 100644 --- a/feature/staticroute/feature.textproto +++ b/feature/staticroute/feature.textproto @@ -1,3 +1,6 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile + id { name: "staticroute" version: 1 diff --git a/feature/system/aaa/feature.textproto b/feature/system/aaa/feature.textproto index b9923cdff62..8dc185c3b3a 100644 --- a/feature/system/aaa/feature.textproto +++ b/feature/system/aaa/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_aaa" diff --git a/feature/system/attestz/feature.textproto b/feature/system/attestz/feature.textproto index 62a7aec8cd7..69517dc0029 100644 --- a/feature/system/attestz/feature.textproto +++ b/feature/system/attestz/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_attestz" diff --git a/feature/system/bootz/feature.textproto b/feature/system/bootz/feature.textproto index 5d47d980b31..e70994d5f07 100644 --- a/feature/system/bootz/feature.textproto +++ b/feature/system/bootz/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_bootz" diff --git a/feature/system/feature.textproto b/feature/system/feature.textproto index e7955038018..177499d7c8e 100644 --- a/feature/system/feature.textproto +++ b/feature/system/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system" diff --git a/feature/system/gnmi/cliorigin/feature.textproto b/feature/system/gnmi/cliorigin/feature.textproto index 7ac0a36ac4a..1d84d99726b 100644 --- a/feature/system/gnmi/cliorigin/feature.textproto +++ b/feature/system/gnmi/cliorigin/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_gnmi_cliorigin" diff --git a/feature/system/gnmi/feature.textproto b/feature/system/gnmi/feature.textproto index ad8b231c431..b6bc47c2e4b 100644 --- a/feature/system/gnmi/feature.textproto +++ b/feature/system/gnmi/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_gnmi" diff --git a/feature/system/gnmi/get/feature.textproto b/feature/system/gnmi/get/feature.textproto index 740a884e128..55fd8121dd9 100644 --- a/feature/system/gnmi/get/feature.textproto +++ b/feature/system/gnmi/get/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_gnmi_get" diff --git a/feature/system/gnmi/metadata/feature.textproto b/feature/system/gnmi/metadata/feature.textproto index 5e3ce2a2739..e85b54ab1db 100644 --- a/feature/system/gnmi/metadata/feature.textproto +++ b/feature/system/gnmi/metadata/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_gnmi_metadata" diff --git a/feature/system/gnmi/metadata/tests/large_set_consistency_test/metadata.textproto b/feature/system/gnmi/metadata/tests/large_set_consistency_test/metadata.textproto index 80bdcf384d9..cae8c3c1a46 100644 --- a/feature/system/gnmi/metadata/tests/large_set_consistency_test/metadata.textproto +++ b/feature/system/gnmi/metadata/tests/large_set_consistency_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "e9cdd09c-14b9-4e3c-b38c-584ef9611c3f" diff --git a/feature/system/gnmi/set/feature.textproto b/feature/system/gnmi/set/feature.textproto index a9b786b86df..30b70f2e858 100644 --- a/feature/system/gnmi/set/feature.textproto +++ b/feature/system/gnmi/set/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_gnmi_set" diff --git a/feature/system/logging/remote_syslog/feature.textproto b/feature/system/logging/remote_syslog/feature.textproto index 0a9e873d314..6c14fbb34ba 100644 --- a/feature/system/logging/remote_syslog/feature.textproto +++ b/feature/system/logging/remote_syslog/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_logging_remote_syslog" diff --git a/feature/system/ntp/feature.textproto b/feature/system/ntp/feature.textproto index a88d35bbf79..ad945baa9dd 100644 --- a/feature/system/ntp/feature.textproto +++ b/feature/system/ntp/feature.textproto @@ -11,6 +11,9 @@ # 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. +# +# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto +# proto-message: FeatureProfile id { name: "system_ntp" diff --git a/topologies/kne/arista/ceos/dut.textproto b/topologies/kne/arista/ceos/dut.textproto index 89719208076..c493398cb19 100644 --- a/topologies/kne/arista/ceos/dut.textproto +++ b/topologies/kne/arista/ceos/dut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "arista-ceos-dut" nodes: { name: "dut" diff --git a/topologies/kne/arista/ceos/dutate.textproto b/topologies/kne/arista/ceos/dutate.textproto index 4c1ea45c1bd..024f2a0f542 100644 --- a/topologies/kne/arista/ceos/dutate.textproto +++ b/topologies/kne/arista/ceos/dutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "arista-ceos-dutate" nodes: { name: "dut" diff --git a/topologies/kne/arista/ceos/dutate_lag.textproto b/topologies/kne/arista/ceos/dutate_lag.textproto index 1cb7bf05a11..46e0c31907e 100644 --- a/topologies/kne/arista/ceos/dutate_lag.textproto +++ b/topologies/kne/arista/ceos/dutate_lag.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "arista-ceos-dutate-lag" nodes: { name: "dut" diff --git a/topologies/kne/arista/ceos/dutdut.textproto b/topologies/kne/arista/ceos/dutdut.textproto index 234b1002f5a..b09d232f2ab 100644 --- a/topologies/kne/arista/ceos/dutdut.textproto +++ b/topologies/kne/arista/ceos/dutdut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "arista-ceos-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/arista/ceos/dutdutate.textproto b/topologies/kne/arista/ceos/dutdutate.textproto index a39cde9d718..b864e64655f 100644 --- a/topologies/kne/arista/ceos/dutdutate.textproto +++ b/topologies/kne/arista/ceos/dutdutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "arista-ceos-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/arista/ceos/topology.textproto b/topologies/kne/arista/ceos/topology.textproto index dd99b31428a..455c4647557 100644 --- a/topologies/kne/arista/ceos/topology.textproto +++ b/topologies/kne/arista/ceos/topology.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "arista-ceos" nodes: { name: "dut1" diff --git a/topologies/kne/cisco/8000e/dut.textproto b/topologies/kne/cisco/8000e/dut.textproto index 387ae75508d..bbf34e15a6b 100644 --- a/topologies/kne/cisco/8000e/dut.textproto +++ b/topologies/kne/cisco/8000e/dut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-8000e-dut" nodes: { name: "dut" diff --git a/topologies/kne/cisco/8000e/dutate.textproto b/topologies/kne/cisco/8000e/dutate.textproto index 1fcf0ace9c3..acddea86948 100644 --- a/topologies/kne/cisco/8000e/dutate.textproto +++ b/topologies/kne/cisco/8000e/dutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-8000e-dutate" nodes: { name: "dut" diff --git a/topologies/kne/cisco/8000e/dutate_lag.textproto b/topologies/kne/cisco/8000e/dutate_lag.textproto index b614136de25..2c15f33bd75 100644 --- a/topologies/kne/cisco/8000e/dutate_lag.textproto +++ b/topologies/kne/cisco/8000e/dutate_lag.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-8000e-dutate-lag" nodes: { name: "dut" diff --git a/topologies/kne/cisco/8000e/dutdut.textproto b/topologies/kne/cisco/8000e/dutdut.textproto index aefa13ecad5..919da1e25ea 100644 --- a/topologies/kne/cisco/8000e/dutdut.textproto +++ b/topologies/kne/cisco/8000e/dutdut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-8000e-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/cisco/8000e/dutdutate.textproto b/topologies/kne/cisco/8000e/dutdutate.textproto index 35b040c836f..407d0cf2a9f 100644 --- a/topologies/kne/cisco/8000e/dutdutate.textproto +++ b/topologies/kne/cisco/8000e/dutdutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-8000e-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/cisco/8000e/topology.textproto b/topologies/kne/cisco/8000e/topology.textproto index e9564924dc8..37d3ef20aa1 100644 --- a/topologies/kne/cisco/8000e/topology.textproto +++ b/topologies/kne/cisco/8000e/topology.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-8000e" nodes: { name: "dut1" diff --git a/topologies/kne/cisco/xrd/dut.textproto b/topologies/kne/cisco/xrd/dut.textproto index 549ed5e792a..839b73c0b40 100644 --- a/topologies/kne/cisco/xrd/dut.textproto +++ b/topologies/kne/cisco/xrd/dut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-xrd-dut" nodes: { name: "dut" diff --git a/topologies/kne/cisco/xrd/dutate.textproto b/topologies/kne/cisco/xrd/dutate.textproto index 3b85637a06f..dfa65bc7d14 100644 --- a/topologies/kne/cisco/xrd/dutate.textproto +++ b/topologies/kne/cisco/xrd/dutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-xrd-dutate" nodes: { name: "dut" diff --git a/topologies/kne/cisco/xrd/dutate_lag.textproto b/topologies/kne/cisco/xrd/dutate_lag.textproto index c7028277fe7..869650071c4 100644 --- a/topologies/kne/cisco/xrd/dutate_lag.textproto +++ b/topologies/kne/cisco/xrd/dutate_lag.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-xrd-dutate-lag" nodes: { name: "dut" diff --git a/topologies/kne/cisco/xrd/dutdut.textproto b/topologies/kne/cisco/xrd/dutdut.textproto index bdcbaf6d757..4f9e85c87bf 100644 --- a/topologies/kne/cisco/xrd/dutdut.textproto +++ b/topologies/kne/cisco/xrd/dutdut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-xrd-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/cisco/xrd/dutdutate.textproto b/topologies/kne/cisco/xrd/dutdutate.textproto index b1a3593bfc8..9ec13b06ae0 100644 --- a/topologies/kne/cisco/xrd/dutdutate.textproto +++ b/topologies/kne/cisco/xrd/dutdutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-xrd-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/cisco/xrd/topology.textproto b/topologies/kne/cisco/xrd/topology.textproto index eeb90ec60b3..5995c6c31ec 100644 --- a/topologies/kne/cisco/xrd/topology.textproto +++ b/topologies/kne/cisco/xrd/topology.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "cisco-xrd" nodes: { name: "dut1" diff --git a/topologies/kne/juniper/ncptx/dut.textproto b/topologies/kne/juniper/ncptx/dut.textproto index 022ef7a0ac9..91270ded372 100644 --- a/topologies/kne/juniper/ncptx/dut.textproto +++ b/topologies/kne/juniper/ncptx/dut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "juniper-ncptx-dut" nodes: { name: "dut" diff --git a/topologies/kne/juniper/ncptx/dutate.textproto b/topologies/kne/juniper/ncptx/dutate.textproto index 88b35a765df..44e80de3a7d 100644 --- a/topologies/kne/juniper/ncptx/dutate.textproto +++ b/topologies/kne/juniper/ncptx/dutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "juniper-ncptx-dutate" nodes: { name: "dut" diff --git a/topologies/kne/juniper/ncptx/dutate_lag.textproto b/topologies/kne/juniper/ncptx/dutate_lag.textproto index 75cffbe01c1..501445d4d68 100644 --- a/topologies/kne/juniper/ncptx/dutate_lag.textproto +++ b/topologies/kne/juniper/ncptx/dutate_lag.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "juniper-ncptx-dutate-lag" nodes: { name: "dut" diff --git a/topologies/kne/juniper/ncptx/dutdut.textproto b/topologies/kne/juniper/ncptx/dutdut.textproto index 18d95178b49..383dab806b1 100644 --- a/topologies/kne/juniper/ncptx/dutdut.textproto +++ b/topologies/kne/juniper/ncptx/dutdut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "juniper-ncptx-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/juniper/ncptx/dutdutate.textproto b/topologies/kne/juniper/ncptx/dutdutate.textproto index 395b14120e5..902ded8e9a3 100644 --- a/topologies/kne/juniper/ncptx/dutdutate.textproto +++ b/topologies/kne/juniper/ncptx/dutdutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "juniper-ncptx-dutdutate" nodes: { name: "dut1" diff --git a/topologies/kne/juniper/ncptx/topology.textproto b/topologies/kne/juniper/ncptx/topology.textproto index 16f7f9c227c..1ce0868d482 100644 --- a/topologies/kne/juniper/ncptx/topology.textproto +++ b/topologies/kne/juniper/ncptx/topology.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "juniper-ncptx" nodes: { name: "dut1" diff --git a/topologies/kne/nokia/srlinux/dut.textproto b/topologies/kne/nokia/srlinux/dut.textproto index e899c143eb6..4861b80218f 100644 --- a/topologies/kne/nokia/srlinux/dut.textproto +++ b/topologies/kne/nokia/srlinux/dut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "nokia-srlinux-dut" nodes: { name: "dut" diff --git a/topologies/kne/nokia/srlinux/dutate.textproto b/topologies/kne/nokia/srlinux/dutate.textproto index 67a6019ddda..3fb4002cdd4 100644 --- a/topologies/kne/nokia/srlinux/dutate.textproto +++ b/topologies/kne/nokia/srlinux/dutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "nokia-srlinux-dutate" nodes: { name: "dut" diff --git a/topologies/kne/nokia/srlinux/dutate_lag.textproto b/topologies/kne/nokia/srlinux/dutate_lag.textproto index d2a249aa2b5..e7738b3f529 100644 --- a/topologies/kne/nokia/srlinux/dutate_lag.textproto +++ b/topologies/kne/nokia/srlinux/dutate_lag.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "nokia-srlinux-dutate-lag" nodes: { name: "dut" diff --git a/topologies/kne/nokia/srlinux/dutdut.textproto b/topologies/kne/nokia/srlinux/dutdut.textproto index a7efd8f1b14..809db2f577f 100644 --- a/topologies/kne/nokia/srlinux/dutdut.textproto +++ b/topologies/kne/nokia/srlinux/dutdut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "nokia-srlinux-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/nokia/srlinux/dutdutate.textproto b/topologies/kne/nokia/srlinux/dutdutate.textproto index 01abc5af46f..95e29436d0e 100644 --- a/topologies/kne/nokia/srlinux/dutdutate.textproto +++ b/topologies/kne/nokia/srlinux/dutdutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "nokia-srlinux-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/nokia/srlinux/topology.textproto b/topologies/kne/nokia/srlinux/topology.textproto index 809a0f49445..52cf5569932 100644 --- a/topologies/kne/nokia/srlinux/topology.textproto +++ b/topologies/kne/nokia/srlinux/topology.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "nokia-srlinux" nodes: { name: "dut1" diff --git a/topologies/kne/openconfig/lemming/dut.textproto b/topologies/kne/openconfig/lemming/dut.textproto index dbbbfb029ac..fac5db0ef7c 100644 --- a/topologies/kne/openconfig/lemming/dut.textproto +++ b/topologies/kne/openconfig/lemming/dut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "openconfig-lemming-dut" nodes: { name: "dut" diff --git a/topologies/kne/openconfig/lemming/dutate.textproto b/topologies/kne/openconfig/lemming/dutate.textproto index ab946444816..7c8e669516f 100644 --- a/topologies/kne/openconfig/lemming/dutate.textproto +++ b/topologies/kne/openconfig/lemming/dutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "openconfig-lemming-dutate" nodes: { name: "dut" diff --git a/topologies/kne/openconfig/lemming/dutate_lag.textproto b/topologies/kne/openconfig/lemming/dutate_lag.textproto index 72f6f440b53..829e68ddf27 100644 --- a/topologies/kne/openconfig/lemming/dutate_lag.textproto +++ b/topologies/kne/openconfig/lemming/dutate_lag.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "openconfig-lemming-dutate-lag" nodes: { name: "dut" diff --git a/topologies/kne/openconfig/lemming/dutdut.textproto b/topologies/kne/openconfig/lemming/dutdut.textproto index ce6470682da..3c9598202b2 100644 --- a/topologies/kne/openconfig/lemming/dutdut.textproto +++ b/topologies/kne/openconfig/lemming/dutdut.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "openconfig-lemming-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/openconfig/lemming/dutdutate.textproto b/topologies/kne/openconfig/lemming/dutdutate.textproto index c0b8c9423c5..6d3c7e204cd 100644 --- a/topologies/kne/openconfig/lemming/dutdutate.textproto +++ b/topologies/kne/openconfig/lemming/dutdutate.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "openconfig-lemming-dutdut" nodes: { name: "dut1" diff --git a/topologies/kne/openconfig/lemming/topology.textproto b/topologies/kne/openconfig/lemming/topology.textproto index fa137660acc..2a23223f525 100644 --- a/topologies/kne/openconfig/lemming/topology.textproto +++ b/topologies/kne/openconfig/lemming/topology.textproto @@ -1,3 +1,5 @@ +# proto-file: github.com/openconfig/kne/proto/topo.proto +# proto-message: Topology name: "openconfig-lemming" nodes: { name: "dut1" diff --git a/topologies/proto/binding/binding.pb.go b/topologies/proto/binding/binding.pb.go index 553f789d413..dcbc653959c 100644 --- a/topologies/proto/binding/binding.pb.go +++ b/topologies/proto/binding/binding.pb.go @@ -21,11 +21,12 @@ package binding import ( + reflect "reflect" + sync "sync" + proto "github.com/openconfig/ondatra/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" ) const ( @@ -615,8 +616,8 @@ type Link struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - A string `protobuf:"bytes,1,opt,name=a,proto3" json:"a,omitempty"` // First port in the format ":". - B string `protobuf:"bytes,2,opt,name=b,proto3" json:"b,omitempty"` // Second port in the format ":". + A string `protobuf:"bytes,1,opt,name=a,proto3" json:"a,omitempty"` // First port in the format ":". + B string `protobuf:"bytes,2,opt,name=b,proto3" json:"b,omitempty"` // Second port in the format ":". } func (x *Link) Reset() { diff --git a/topologies/proto/generate.sh b/topologies/proto/generate.sh deleted file mode 100755 index 5d99e9e0bec..00000000000 --- a/topologies/proto/generate.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# -# Copyright 2022 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 -# -# https://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. - -# This script is used to generate the Feature Profiles topology -# binding proto APIs. - -set -e - -# Set directory to hold symlink -mkdir -p protobuf-import -# Remove any existing symlinks & empty directories -find protobuf-import -type l -delete -find protobuf-import -type d -empty -delete -# Download the required dependencies -go mod download -# Get ondatra modules we use and create required directory structure -go list -f 'protobuf-import/{{ .Path }}' -m github.com/openconfig/ondatra | xargs -L1 dirname | sort | uniq | xargs mkdir -p -go list -f '{{ .Dir }} protobuf-import/{{ .Path }}' -m github.com/openconfig/ondatra | xargs -L1 -- ln -s - -cd "$( dirname "${BASH_SOURCE[0]}" )" - -protoc -I='../../protobuf-import' --proto_path=. --go_out=. --go_opt=module=github.com/openconfig/featureprofiles/topologies/proto *.proto From 140a7923bcc4f26d72e4a4ac26c06c3b4c66f010 Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Tue, 26 Mar 2024 14:58:54 -0700 Subject: [PATCH 46/97] Fix textproto path (#2847) --- .../transceiver/tests/zr_inventory_test/metadata.textproto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto b/feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto index e683efdcddf..1a64604ac45 100644 --- a/feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_inventory_test/metadata.textproto @@ -1,4 +1,4 @@ -# proto-file: third_party/openconfig/featureprofiles/proto/metadata.proto +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata uuid: "376d3561-4271-4efc-be63-3eec7b56b86d" plan_id: "TRANSCEIVER-7" From d58c04a88587fa8651ac3b9a08f03979a7ce4194 Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Tue, 26 Mar 2024 15:42:02 -0700 Subject: [PATCH 47/97] Remove stray metadata.textproto (#2849) --- feature/system/management/metadata.textproto | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 feature/system/management/metadata.textproto diff --git a/feature/system/management/metadata.textproto b/feature/system/management/metadata.textproto deleted file mode 100644 index 205908fe722..00000000000 --- a/feature/system/management/metadata.textproto +++ /dev/null @@ -1,7 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -plan_id: "MGT-1" -description: "Management HA test" -testbed: TESTBED_DUT_ATE_4LINKS -tags: [TAGS_AGGREGATION, TAGS_TRANSIT, TAGS_DATACENTER_EDGE] From 67fff8b485f5c489157b755afef2f3e959b2d1ed Mon Sep 17 00:00:00 2001 From: PRIYA RANJAN NANDA <151918045+priyaranjannanda@users.noreply.github.com> Date: Wed, 27 Mar 2024 05:40:34 +0530 Subject: [PATCH 48/97] TRANSCEIVER-4: Telemetry: 400ZR RX input and TX output power telemetry values streaming. (#2706) * Initial Commit for Transceiver-4 * Added check to verify min<=avg/instant<=max for Rx and Tx power, removed variable d and renamed testData to testDataObj in for loops under TestZrInputOutputPower to avoid confusion --------- Co-authored-by: KandukuriSudheer Co-authored-by: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Co-authored-by: Suprith Hattikal --- .../{README.MD => README.md} | 0 .../metadata.textproto | 7 + .../zr_input_output_power_test.go | 413 ++++++++++++++++++ 3 files changed, 420 insertions(+) rename feature/platform/transceiver/tests/zr_input_output_power_test/{README.MD => README.md} (100%) create mode 100644 feature/platform/transceiver/tests/zr_input_output_power_test/metadata.textproto create mode 100644 feature/platform/transceiver/tests/zr_input_output_power_test/zr_input_output_power_test.go diff --git a/feature/platform/transceiver/tests/zr_input_output_power_test/README.MD b/feature/platform/transceiver/tests/zr_input_output_power_test/README.md similarity index 100% rename from feature/platform/transceiver/tests/zr_input_output_power_test/README.MD rename to feature/platform/transceiver/tests/zr_input_output_power_test/README.md diff --git a/feature/platform/transceiver/tests/zr_input_output_power_test/metadata.textproto b/feature/platform/transceiver/tests/zr_input_output_power_test/metadata.textproto new file mode 100644 index 00000000000..cfabe297f68 --- /dev/null +++ b/feature/platform/transceiver/tests/zr_input_output_power_test/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "67be4256-6965-4a6d-bc68-322c878cbc73" +plan_id: "TRANSCEIVER-4" +description: "Telemetry: 400ZR RX input and TX output power telemetry values streaming." +testbed: TESTBED_DUT_ATE_2LINKS diff --git a/feature/platform/transceiver/tests/zr_input_output_power_test/zr_input_output_power_test.go b/feature/platform/transceiver/tests/zr_input_output_power_test/zr_input_output_power_test.go new file mode 100644 index 00000000000..0ed4461fcee --- /dev/null +++ b/feature/platform/transceiver/tests/zr_input_output_power_test/zr_input_output_power_test.go @@ -0,0 +1,413 @@ +// 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 zr_input_output_power_test + +import ( + "context" + "reflect" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/samplestream" + gnps "github.com/openconfig/gnoi/system" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/testt" + "github.com/openconfig/ygot/ygot" +) + +const ( + opticalChannelTransceiverType = oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL + maxRebootTime = 900 + maxCompWaitTime = 600 + samplingTime = 10000000000 // 10 Seconds. + targetOutputPower = -9 + interfaceFlapTimeOut = 30 // Seconds. + outputFreqLowerBound = 184500000 + outputFreqUpperBound = 196000000 + rxSignalPowerLowerBound = -14 + rxSignalPowerUpperBound = 0 + txOutputPowerLowerBound = -10 + txOutputPowerUpperBound = -6 +) + +type testData struct { + transceiverName string + dut *ondatra.DUTDevice + transceiverOpticalChannelName string + interfaceName string +} + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// Removes any breakout configuration if present, and configures the DUT. +func configureDUT(t *testing.T, dut *ondatra.DUTDevice, transceiverName string) { + port := dut.Port(t, "port1") + // Remove any breakout configuration. + hardwareComponentName := gnmi.Get(t, dut, gnmi.OC().Interface(port.Name()).HardwarePort().State()) + gnmi.Delete(t, dut, gnmi.OC().Component(hardwareComponentName).Port().BreakoutMode().Config()) + + i1 := &oc.Interface{Name: ygot.String(port.Name())} + i1.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + if deviations.ExplicitPortSpeed(dut) { + i1.GetOrCreateEthernet().PortSpeed = fptest.GetIfSpeed(t, port) + } + + gnmi.Replace(t, dut, gnmi.OC().Interface(port.Name()).Config(), i1) + gnmi.Replace(t, dut, gnmi.OC().Component(transceiverName).Transceiver().Enabled().Config(), *ygot.Bool(true)) + t.Logf("Configured port %v", port.Name()) +} + +// Verifies valid Rx Signal power. +func verifyValidRxInputPower(t testing.TB, transceiverOpticalChanelInputPower *oc.Component_OpticalChannel_InputPower, isInterfaceDisabled bool, transceiverOpticalChannelName string, transceiverName string) { + t.Logf("Checking Transceiver = %v Optical Channel Input Power Statistics", transceiverOpticalChannelName) + t.Logf("Optical channel = %v , Instant Input Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelInputPower.GetInstant()) + t.Logf("Optical channel = %v , Average Input Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelInputPower.GetAvg()) + t.Logf("Optical channel = %v , Min Input Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelInputPower.GetMin()) + t.Logf("Optical channel = %v , Max Input Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelInputPower.GetMax()) + + if transceiverInputPowerInstantType := reflect.TypeOf(transceiverOpticalChanelInputPower.GetInstant()).Kind(); transceiverInputPowerInstantType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Instant InputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverInputPowerInstantType) + } + if transceiverInputPowerAvgType := reflect.TypeOf(transceiverOpticalChanelInputPower.GetAvg()).Kind(); transceiverInputPowerAvgType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Avg InputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverInputPowerAvgType) + } + if transceiverInputPowerMinType := reflect.TypeOf(transceiverOpticalChanelInputPower.GetMin()).Kind(); transceiverInputPowerMinType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Min InputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverInputPowerMinType) + } + if transceiverInputPowerMaxType := reflect.TypeOf(transceiverOpticalChanelInputPower.GetMax()).Kind(); transceiverInputPowerMaxType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Max InputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverInputPowerMaxType) + } + + if isInterfaceDisabled { + if transceiverOpticalChanelInputPower.GetInstant() > 0 { + t.Fatalf("[Error]: Expected Optical Channel %v Instant InputPower = %v ,Got =%v", transceiverOpticalChannelName, 0, transceiverOpticalChanelInputPower.GetInstant()) + } + if transceiverOpticalChanelInputPower.GetAvg() > 0 { + t.Fatalf("[Error]: Expected Optical Channel %v Avg InputPower = %v ,Got =%v", transceiverOpticalChannelName, 0, transceiverOpticalChanelInputPower.GetAvg()) + } + if transceiverOpticalChanelInputPower.GetMin() > 0 { + t.Fatalf("[Error]: Expected Optical Channel %v Min InputPower = %v ,Got =%v", transceiverOpticalChannelName, 0, transceiverOpticalChanelInputPower.GetMin()) + } + if transceiverOpticalChanelInputPower.GetMax() > 0 { + t.Fatalf("[Error]: Expected Optical Channel %v Max InputPower = %v ,Got =%v", transceiverOpticalChannelName, 0, transceiverOpticalChanelInputPower.GetMax()) + } + + } else if transceiverOpticalChanelInputPower.GetMin() < rxSignalPowerLowerBound || transceiverOpticalChanelInputPower.GetMax() > rxSignalPowerUpperBound { + t.Fatalf("Transciever %v RX Input power range Expected = %v to %v dbm, Got = %v to %v ", transceiverName, rxSignalPowerLowerBound, rxSignalPowerUpperBound, transceiverOpticalChanelInputPower.GetMin(), transceiverOpticalChanelInputPower.GetMax()) + } else if transceiverOpticalChanelInputPower.GetMin() > transceiverOpticalChanelInputPower.GetAvg() || transceiverOpticalChanelInputPower.GetAvg() > transceiverOpticalChanelInputPower.GetMax() || transceiverOpticalChanelInputPower.GetMin() > transceiverOpticalChanelInputPower.GetInstant() || transceiverOpticalChanelInputPower.GetInstant() > transceiverOpticalChanelInputPower.GetMax() { + t.Fatalf("Transciever %v RX Input power not following min <= avg/instant <= max. Got instant = %v ,min= %v , avg= %v , max =%v ", transceiverName, transceiverOpticalChanelInputPower.GetInstant(), transceiverOpticalChanelInputPower.GetMin(), transceiverOpticalChanelInputPower.GetAvg(), transceiverOpticalChanelInputPower.GetMax()) + } +} + +// Verifies valid Tx Output Power. +func verifyValidTxOutputPower(t testing.TB, transceiverOpticalChanelOutputPower *oc.Component_OpticalChannel_OutputPower, isInterfaceDisabled bool, transceiverOpticalChannelName string, transceiverName string) { + t.Logf("Checking Transceiver = %v Optical Channel Output Power Statistics", transceiverOpticalChannelName) + t.Logf("Optical channel = %v , Instant Output Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelOutputPower.GetInstant()) + t.Logf("Optical channel = %v , Average Output Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelOutputPower.GetAvg()) + t.Logf("Optical channel = %v , Min Output Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelOutputPower.GetMin()) + t.Logf("Optical channel = %v , Max Output Power = %v", transceiverOpticalChannelName, transceiverOpticalChanelOutputPower.GetMax()) + if transceiverOutputPowerInstantType := reflect.TypeOf(transceiverOpticalChanelOutputPower.GetInstant()).Kind(); transceiverOutputPowerInstantType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Instant OutputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverOutputPowerInstantType) + } + if transceiverOutputPowerAvgType := reflect.TypeOf(transceiverOpticalChanelOutputPower.GetAvg()).Kind(); transceiverOutputPowerAvgType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Avg OutputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverOutputPowerAvgType) + } + if transceiverOutputPowerMinType := reflect.TypeOf(transceiverOpticalChanelOutputPower.GetMin()).Kind(); transceiverOutputPowerMinType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Min OutputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverOutputPowerMinType) + } + if transceiverOutputPowerMaxType := reflect.TypeOf(transceiverOpticalChanelOutputPower.GetMax()).Kind(); transceiverOutputPowerMaxType != reflect.Float64 { + t.Fatalf("[Error]: Expected Optical Channel %v Max OutputPower data type = %v , Got =%v", transceiverOpticalChannelName, reflect.Float64, transceiverOutputPowerMaxType) + } + + if isInterfaceDisabled { + + if transceiverOpticalChanelOutputPower.GetInstant() != -40 { + t.Fatalf("[Error]: Expected Optical Channel %v Instant OutputPower = %v ,Got =%v", transceiverOpticalChannelName, -40, transceiverOpticalChanelOutputPower.GetInstant()) + } + if transceiverOpticalChanelOutputPower.GetAvg() != -40 { + t.Fatalf("[Error]: Expected Optical Channel %v Avg OutputPower = %v ,Got =%v", transceiverOpticalChannelName, -40, transceiverOpticalChanelOutputPower.GetAvg()) + } + if transceiverOpticalChanelOutputPower.GetMin() != -40 { + t.Fatalf("[Error]: Expected Optical Channel %v Min OutputPower = %v ,Got =%v", transceiverOpticalChannelName, -40, transceiverOpticalChanelOutputPower.GetMin()) + } + if transceiverOpticalChanelOutputPower.GetMax() != -40 { + t.Fatalf("[Error]: Expected Optical Channel %v Max OutputPower = %v ,Got =%v", transceiverOpticalChannelName, -40, transceiverOpticalChanelOutputPower.GetMax()) + } + + } else if transceiverOpticalChanelOutputPower.GetMin() < txOutputPowerLowerBound || transceiverOpticalChanelOutputPower.GetMax() > txOutputPowerUpperBound { + t.Fatalf("[Error]:Transciever %v TX Output power range Expected = %v to %v dbm, Got = %v to %v ", transceiverName, txOutputPowerLowerBound, txOutputPowerUpperBound, transceiverOpticalChanelOutputPower.GetMin(), transceiverOpticalChanelOutputPower.GetMax()) + } else if transceiverOpticalChanelOutputPower.GetMin() > transceiverOpticalChanelOutputPower.GetAvg() || transceiverOpticalChanelOutputPower.GetAvg() > transceiverOpticalChanelOutputPower.GetMax() || transceiverOpticalChanelOutputPower.GetMin() > transceiverOpticalChanelOutputPower.GetInstant() || transceiverOpticalChanelOutputPower.GetInstant() > transceiverOpticalChanelOutputPower.GetMax() { + t.Fatalf("Transciever %v TX Output power not following min <= avg/instant <= max . Got instant = %v ,min= %v , avg= %v , max =%v ", transceiverName, transceiverOpticalChanelOutputPower.GetInstant(), transceiverOpticalChanelOutputPower.GetMin(), transceiverOpticalChanelOutputPower.GetAvg(), transceiverOpticalChanelOutputPower.GetMax()) + } +} + +// Verifies whether inputPower , outputPower ,Frequency are as expected. +func verifyInputOutputPower(t *testing.T, tc *testData) { + transceiverComponentPath := gnmi.OC().Component(tc.transceiverName) + transceiverOpticalChannelPath := gnmi.OC().Component(tc.transceiverOpticalChannelName) + t.Logf("Checking if transceiver = %v is Enabled", tc.transceiverName) + + isTransceiverEnabled := gnmi.Get(t, tc.dut, transceiverComponentPath.Transceiver().Enabled().State()) + if isTransceiverEnabled != true { + t.Errorf("[Error]:Tranciever %v is not enabled ", tc.transceiverName) + } + t.Logf("Transceiver = %v is in Enabled state", tc.transceiverName) + + t.Logf("Checking Transceiver = %v Output Frequency ", tc.transceiverName) + outputFrequency := gnmi.Get(t, tc.dut, transceiverComponentPath.Transceiver().Channel(0).OutputFrequency().State()) + t.Logf("Transceiver = %v Output Frequency = %v ", tc.transceiverName, outputFrequency) + if reflect.TypeOf(outputFrequency).Kind() != reflect.Uint64 { + t.Errorf("[Error]: Expected output frequency data type =%v Got = %v", reflect.Uint64, reflect.TypeOf(outputFrequency)) + } + + if outputFrequency > outputFreqUpperBound || outputFrequency < outputFreqLowerBound { + t.Errorf("[Error]: Output Frequency is not a valid frequency %v =%v, Got = %v", outputFreqLowerBound, outputFreqUpperBound, outputFrequency) + } + t.Logf("Transceiver = %v Output Frequency is in the expected range", tc.transceiverName) + + opticalInputPowerStream := samplestream.New(t, tc.dut, transceiverOpticalChannelPath.OpticalChannel().InputPower().State(), 10*time.Second) + defer opticalInputPowerStream.Close() + transceiverOpticalOutputPowerStream := samplestream.New(t, tc.dut, transceiverOpticalChannelPath.OpticalChannel().OutputPower().State(), 10*time.Second) + defer transceiverOpticalOutputPowerStream.Close() + + transceiverOpticalChanelOutputPower, ok := transceiverOpticalOutputPowerStream.Next().Val() + if !ok { + t.Errorf("[Error]:Trasceiver = %v Output Power not received !", tc.transceiverOpticalChannelName) + } + + transceiverOpticalChanelInputPower, ok := opticalInputPowerStream.Next().Val() + if !ok { + t.Errorf("[Error]:Trasceiver = %v Power not received !", tc.transceiverOpticalChannelName) + } + + verifyValidTxOutputPower(t, transceiverOpticalChanelOutputPower, false, tc.transceiverOpticalChannelName, tc.transceiverName) + verifyValidRxInputPower(t, transceiverOpticalChanelInputPower, false, tc.transceiverOpticalChannelName, tc.transceiverName) + + rxTotalInputPowerSamplingTime := gnmi.Get(t, tc.dut, transceiverComponentPath.Transceiver().Channel(0).InputPower().Interval().State()) + rxTotalInputPowerStream := samplestream.New(t, tc.dut, transceiverComponentPath.Transceiver().Channel(0).InputPower().State(), time.Nanosecond*time.Duration(rxTotalInputPowerSamplingTime)) + defer rxTotalInputPowerStream.Close() + nexInputPower := rxTotalInputPowerStream.Next() + transceiverRxTotalInputPower, got := nexInputPower.Val() + + if transceiverRxTotalInputPower == nil || got == false { + t.Errorf("[Error]:Didn't recieve Rx total InputPower sample in 10 seconds for the transceiever = %v", tc.transceiverName) + } + + t.Logf("Transceiver = %v RX Total Instant Input Power = %v", tc.transceiverName, transceiverRxTotalInputPower.GetInstant()) + t.Logf("Transceiver = %v RX Total Average Input Power = %v", tc.transceiverName, transceiverRxTotalInputPower.GetAvg()) + t.Logf("Transceiver = %v RX Total Min Input Power = %v", tc.transceiverName, transceiverRxTotalInputPower.GetMin()) + t.Logf("Transceiver = %v RX Total channel Max Input Power = %v", tc.transceiverName, transceiverRxTotalInputPower.GetMax()) + + if transceiverOpticalChanelInputPower == nil || got == false { + t.Errorf("[Error]:Didn't recieve Optical channel InputPower sample in 10 seconds for the transceiever = %v", tc.transceiverName) + } + if transceiverOpticalChanelInputPower.GetMax() > transceiverRxTotalInputPower.GetMax() { + t.Errorf("[Error]:Transciever %v RX Signal Power = %v is more than Total RX Signal Power = %v ", tc.transceiverName, transceiverOpticalChanelInputPower.GetMax(), transceiverRxTotalInputPower.GetMax()) + } + +} + +// Reboots the device and verifies Rx InputPower, TxOutputPower data while components are booting. +func dutRebootRxInputTxOutputPowerCheck(t *testing.T, tc *testData) { + gnoiClient, err := tc.dut.RawAPIs().BindingDUT().DialGNOI(context.Background()) + if err != nil { + t.Fatalf("Failed to connect to gnoi server, err: %v", err) + } + rebootRequest := &gnps.RebootRequest{ + Method: gnps.RebootMethod_COLD, + Force: true, + } + preRebootCompStatus := gnmi.GetAll(t, tc.dut, gnmi.OC().ComponentAny().OperStatus().State()) + preRebootCompDebug := gnmi.GetAll(t, tc.dut, gnmi.OC().ComponentAny().State()) + preCompMatrix := []string{} + for _, preComp := range preRebootCompDebug { + if preComp.GetOperStatus() != oc.PlatformTypes_COMPONENT_OPER_STATUS_UNSET { + preCompMatrix = append(preCompMatrix, preComp.GetName()+":"+preComp.GetOperStatus().String()) + } + } + + bootTimeBeforeReboot := gnmi.Get(t, tc.dut, gnmi.OC().System().BootTime().State()) + t.Logf("DUT boot time before reboot: %v", bootTimeBeforeReboot) + var currentTime string + currentTime = gnmi.Get(t, tc.dut, gnmi.OC().System().CurrentDatetime().State()) + t.Logf("Time Before Reboot : %v", currentTime) + rebootResponse, err := gnoiClient.System().Reboot(context.Background(), rebootRequest) + t.Logf("Got Reboot response: %v, err: %v", rebootResponse, err) + if err != nil { + t.Fatalf("Failed to reboot chassis with unexpected err: %v", err) + } + for { + if errMsg := testt.CaptureFatal(t, func(t testing.TB) { + currentTime = gnmi.Get(t, tc.dut, gnmi.OC().System().CurrentDatetime().State()) + }); errMsg != nil { + t.Log("Reboot is started") + break + } + t.Log("Wait for reboot to be started") + time.Sleep(30 * time.Second) + } + startReboot := time.Now() + t.Logf("Waiting for DUT to boot up by polling the telemetry output.") + for { + if errMsg := testt.CaptureFatal(t, func(t testing.TB) { + currentTime = gnmi.Get(t, tc.dut, gnmi.OC().System().CurrentDatetime().State()) + }); errMsg == nil { + t.Logf("Device rebooted successfully with received time: %v", currentTime) + break + } + if uint64(time.Since(startReboot).Seconds()) > maxRebootTime { + t.Fatalf("Check boot time: got %v, want < %v", time.Since(startReboot), maxRebootTime) + } + } + time.Sleep(30 * time.Second) + startComp := time.Now() + for { + + postRebootCompStatus := gnmi.GetAll(t, tc.dut, gnmi.OC().ComponentAny().OperStatus().State()) + postRebootCompDebug := gnmi.GetAll(t, tc.dut, gnmi.OC().ComponentAny().State()) + postCompMatrix := []string{} + + if verErrMsg := testt.CaptureFatal(t, func(t testing.TB) { + interfaceEnabled := gnmi.Get(t, tc.dut, gnmi.OC().Interface(tc.interfaceName).Enabled().Config()) + transceiverOpticalChannelPath := gnmi.OC().Component(tc.transceiverOpticalChannelName) + transceiverOpticalChanelInputPower := gnmi.Get(t, tc.dut, transceiverOpticalChannelPath.OpticalChannel().InputPower().State()) + transceiverOpticalChanelOutputPower := gnmi.Get(t, tc.dut, transceiverOpticalChannelPath.OpticalChannel().OutputPower().State()) + verifyValidRxInputPower(t, transceiverOpticalChanelInputPower, !interfaceEnabled, tc.transceiverOpticalChannelName, tc.transceiverName) + verifyValidTxOutputPower(t, transceiverOpticalChanelOutputPower, !interfaceEnabled, tc.transceiverOpticalChannelName, tc.transceiverName) + }); strings.HasPrefix(*verErrMsg, "[Error]") { + t.Fatal(*verErrMsg) + } + + for _, postComp := range postRebootCompDebug { + if postComp.GetOperStatus() != oc.PlatformTypes_COMPONENT_OPER_STATUS_UNSET { + postCompMatrix = append(postCompMatrix, postComp.GetName()+":"+postComp.GetOperStatus().String()) + } + } + if len(preRebootCompStatus) == len(postRebootCompStatus) { + if rebootDiff := cmp.Diff(preCompMatrix, postCompMatrix); rebootDiff == "" { + time.Sleep(10 * time.Second) + break + } + } + if uint64(time.Since(startComp).Seconds()) > maxCompWaitTime { + t.Logf("DUT components status post reboot: %v", postRebootCompStatus) + if rebootDiff := cmp.Diff(preCompMatrix, postCompMatrix); rebootDiff != "" { + t.Logf("[DEBUG] Unexpected diff after reboot (-component missing from pre reboot, +component added from pre reboot): %v ", rebootDiff) + } + t.Fatalf("There's a difference in components obtained in pre reboot: %v and post reboot: %v.", len(preRebootCompStatus), len(postRebootCompStatus)) + break + } + time.Sleep(10 * time.Second) + } + +} + +// Verifies Rx InputPower, TxOutputPower data is streamed correctly after interface flaps. +func verifyRxInputTxOutputAfterFlap(t *testing.T, tc *testData) { + + interfacePath := gnmi.OC().Interface(tc.interfaceName) + + transceiverOpticalChannelPath := gnmi.OC().Component(tc.transceiverOpticalChannelName) + opticalInputPowerStream := samplestream.New(t, tc.dut, transceiverOpticalChannelPath.OpticalChannel().InputPower().State(), 10*time.Second) + defer opticalInputPowerStream.Close() + transceiverOpticalOutputPowerStream := samplestream.New(t, tc.dut, transceiverOpticalChannelPath.OpticalChannel().OutputPower().State(), 10*time.Second) + defer transceiverOpticalOutputPowerStream.Close() + + transceiverOpticalChanelInputPower, _ := opticalInputPowerStream.Next().Val() + transceiverOpticalChanelOutputPower, _ := transceiverOpticalOutputPowerStream.Next().Val() + + verifyValidRxInputPower(t, transceiverOpticalChanelInputPower, false, tc.transceiverOpticalChannelName, tc.transceiverName) + verifyValidTxOutputPower(t, transceiverOpticalChanelOutputPower, false, tc.transceiverOpticalChannelName, tc.transceiverName) + + t.Logf("Disbaling the interface = %v ", tc.interfaceName) + gnmi.Replace(t, tc.dut, interfacePath.Enabled().Config(), *ygot.Bool(false)) + gnmi.Await(t, tc.dut, interfacePath.Enabled().State(), time.Minute, *ygot.Bool(false)) + + t.Logf("Disabled the interface = %v", tc.interfaceName) + transceiverOpticalChanelInputPower, _ = opticalInputPowerStream.Nexts(5)[4].Val() + transceiverOpticalChanelOutputPower, _ = transceiverOpticalOutputPowerStream.Nexts(5)[4].Val() + verifyValidRxInputPower(t, transceiverOpticalChanelInputPower, true, tc.transceiverOpticalChannelName, tc.transceiverName) + verifyValidTxOutputPower(t, transceiverOpticalChanelOutputPower, true, tc.transceiverOpticalChannelName, tc.transceiverName) + + t.Logf("Re-enabling the interface = %v ", tc.interfaceName) + gnmi.Replace(t, tc.dut, interfacePath.Enabled().Config(), *ygot.Bool(true)) + gnmi.Await(t, tc.dut, interfacePath.Enabled().State(), time.Minute, *ygot.Bool(true)) + t.Logf("Re-enabled the interface = %v", tc.interfaceName) + + transceiverOpticalChanelInputPower, _ = opticalInputPowerStream.Nexts(5)[4].Val() + transceiverOpticalChanelOutputPower, _ = transceiverOpticalOutputPowerStream.Nexts(5)[4].Val() + verifyValidRxInputPower(t, transceiverOpticalChanelInputPower, false, tc.transceiverOpticalChannelName, tc.transceiverName) + verifyValidTxOutputPower(t, transceiverOpticalChanelOutputPower, false, tc.transceiverOpticalChannelName, tc.transceiverName) + +} + +func TestZrInputOutputPower(t *testing.T) { + dut1 := ondatra.DUT(t, "dut1") + dut2 := ondatra.DUT(t, "dut2") + + transceiver1Port := dut1.Port(t, "port1") + transceiver2Port := dut2.Port(t, "port1") + transceiver1Name := gnmi.Get(t, dut1, gnmi.OC().Interface(transceiver1Port.Name()).Transceiver().State()) + transceiver2Name := gnmi.Get(t, dut2, gnmi.OC().Interface(transceiver2Port.Name()).Transceiver().State()) + + configureDUT(t, dut1, transceiver1Name) + configureDUT(t, dut2, transceiver2Name) + + transceiver1OpticalChannelName := gnmi.Get(t, dut1, gnmi.OC().Component(transceiver1Name).Transceiver().Channel(0).AssociatedOpticalChannel().State()) + transceiver2OpticalChannelName := gnmi.Get(t, dut2, gnmi.OC().Component(transceiver2Name).Transceiver().Channel(0).AssociatedOpticalChannel().State()) + + testCases := []testData{ + { + transceiverName: transceiver1Name, + dut: dut1, + transceiverOpticalChannelName: transceiver1OpticalChannelName, + interfaceName: transceiver1Port.Name(), + }, + { + transceiverName: transceiver2Name, + dut: dut2, + transceiverOpticalChannelName: transceiver2OpticalChannelName, + interfaceName: transceiver2Port.Name(), + }, + } + + t.Run("RT-4.1: Testing Input, Output Power telemetry", func(t *testing.T) { + for _, testDataObj := range testCases { + verifyInputOutputPower(t, &testDataObj) + } + }) + + t.Run("RT-4.2: Testing Rx Input Power, Tx Output Power telemetry during DUT reboot", func(t *testing.T) { + for _, testDataObj := range testCases { + dutRebootRxInputTxOutputPowerCheck(t, &testDataObj) + } + }) + t.Run("RT-4.3: Interface flap Rx Input Power Tx Output Power telemetry test", func(t *testing.T) { + for _, testDataObj := range testCases { + verifyRxInputTxOutputAfterFlap(t, &testDataObj) + } + }) + + // Todo: ## TRANSCEIVER-4.4 . + +} From 70d9299229b7486a662a35799f45fd5539e3e23d Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Wed, 27 Mar 2024 12:32:00 +0530 Subject: [PATCH 49/97] added deviations to fix encap frr test (#2837) * added deviations to fix encap frr test * ci fix * nh update by creating new nh and attaching with existing nhg --- .../otg_tests/encap_frr/encap_frr_test.go | 227 +++++++++++++----- .../otg_tests/encap_frr/metadata.textproto | 8 + 2 files changed, 175 insertions(+), 60 deletions(-) diff --git a/feature/gribi/otg_tests/encap_frr/encap_frr_test.go b/feature/gribi/otg_tests/encap_frr/encap_frr_test.go index 135ecc28b7b..46e80f2bef2 100644 --- a/feature/gribi/otg_tests/encap_frr/encap_frr_test.go +++ b/feature/gribi/otg_tests/encap_frr/encap_frr_test.go @@ -90,11 +90,11 @@ const ( niEncapTeVrfB = "ENCAP_TE_VRF_B" niTeVrf111 = "TE_VRF_111" niTeVrf222 = "TE_VRF_222" - niDefault = "DEFAULT" tolerancePct = 2 tolerance = 0.2 encapFlow = "encapFlow" correspondingHopLimit = 64 + magicIP = "192.168.1.1" magicMac = "02:00:00:00:00:01" gribiIPv4EntryDefVRF1 = "192.0.2.101" gribiIPv4EntryDefVRF2 = "192.0.2.102" @@ -125,6 +125,7 @@ const ( ateSrcNetCIDR = "198.51.100.0/24" ateSrcNetFirstIP = "198.51.100.1" ateSrcNetCount = 250 + ipOverIPProtocol = 4 checkEncap = true wantLoss = true @@ -213,7 +214,7 @@ type testArgs struct { } type policyFwRule struct { - SeqId uint32 + SeqID uint32 family string protocol oc.UnionUint8 dscpSet []uint8 @@ -349,42 +350,42 @@ func configureVrfSelectionPolicy(t *testing.T, dut *ondatra.DUTDevice) { d := &oc.Root{} dutPolFwdPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding() - pfRule1 := &policyFwRule{SeqId: 1, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc222Addr + "/32", + pfRule1 := &policyFwRule{SeqID: 1, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc222Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfA, decapFallbackNi: niTeVrf222} - pfRule2 := &policyFwRule{SeqId: 2, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc222Addr + "/32", + pfRule2 := &policyFwRule{SeqID: 2, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc222Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfA, decapFallbackNi: niTeVrf222} - pfRule3 := &policyFwRule{SeqId: 3, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc111Addr + "/32", + pfRule3 := &policyFwRule{SeqID: 3, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc111Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfA, decapFallbackNi: niTeVrf111} - pfRule4 := &policyFwRule{SeqId: 4, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc111Addr + "/32", + pfRule4 := &policyFwRule{SeqID: 4, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, sourceAddr: ipv4OuterSrc111Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfA, decapFallbackNi: niTeVrf111} - pfRule5 := &policyFwRule{SeqId: 5, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc222Addr + "/32", + pfRule5 := &policyFwRule{SeqID: 5, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc222Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfB, decapFallbackNi: niTeVrf222} - pfRule6 := &policyFwRule{SeqId: 6, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc222Addr + "/32", + pfRule6 := &policyFwRule{SeqID: 6, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc222Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfB, decapFallbackNi: niTeVrf222} - pfRule7 := &policyFwRule{SeqId: 7, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc111Addr + "/32", + pfRule7 := &policyFwRule{SeqID: 7, family: "ipv4", protocol: 4, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc111Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfB, decapFallbackNi: niTeVrf111} - pfRule8 := &policyFwRule{SeqId: 8, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc111Addr + "/32", + pfRule8 := &policyFwRule{SeqID: 8, family: "ipv4", protocol: 41, dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, sourceAddr: ipv4OuterSrc111Addr + "/32", decapNi: niDecapTeVrf, postDecapNi: niEncapTeVrfB, decapFallbackNi: niTeVrf111} - pfRule9 := &policyFwRule{SeqId: 9, family: "ipv4", protocol: 4, sourceAddr: ipv4OuterSrc222Addr + "/32", - decapNi: niDecapTeVrf, postDecapNi: niDefault, decapFallbackNi: niTeVrf222} - pfRule10 := &policyFwRule{SeqId: 10, family: "ipv4", protocol: 41, sourceAddr: ipv4OuterSrc222Addr + "/32", - decapNi: niDecapTeVrf, postDecapNi: niDefault, decapFallbackNi: niTeVrf222} - pfRule11 := &policyFwRule{SeqId: 11, family: "ipv4", protocol: 4, sourceAddr: ipv4OuterSrc111Addr + "/32", - decapNi: niDecapTeVrf, postDecapNi: niDefault, decapFallbackNi: niTeVrf111} - pfRule12 := &policyFwRule{SeqId: 12, family: "ipv4", protocol: 41, sourceAddr: ipv4OuterSrc111Addr + "/32", - decapNi: niDecapTeVrf, postDecapNi: niDefault, decapFallbackNi: niTeVrf111} + pfRule9 := &policyFwRule{SeqID: 9, family: "ipv4", protocol: 4, sourceAddr: ipv4OuterSrc222Addr + "/32", + decapNi: niDecapTeVrf, postDecapNi: deviations.DefaultNetworkInstance(dut), decapFallbackNi: niTeVrf222} + pfRule10 := &policyFwRule{SeqID: 10, family: "ipv4", protocol: 41, sourceAddr: ipv4OuterSrc222Addr + "/32", + decapNi: niDecapTeVrf, postDecapNi: deviations.DefaultNetworkInstance(dut), decapFallbackNi: niTeVrf222} + pfRule11 := &policyFwRule{SeqID: 11, family: "ipv4", protocol: 4, sourceAddr: ipv4OuterSrc111Addr + "/32", + decapNi: niDecapTeVrf, postDecapNi: deviations.DefaultNetworkInstance(dut), decapFallbackNi: niTeVrf111} + pfRule12 := &policyFwRule{SeqID: 12, family: "ipv4", protocol: 41, sourceAddr: ipv4OuterSrc111Addr + "/32", + decapNi: niDecapTeVrf, postDecapNi: deviations.DefaultNetworkInstance(dut), decapFallbackNi: niTeVrf111} - pfRule13 := &policyFwRule{SeqId: 13, family: "ipv4", dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, + pfRule13 := &policyFwRule{SeqID: 13, family: "ipv4", dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, networkInstance: niEncapTeVrfA} - pfRule14 := &policyFwRule{SeqId: 14, family: "ipv6", dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, + pfRule14 := &policyFwRule{SeqID: 14, family: "ipv6", dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, networkInstance: niEncapTeVrfA} - pfRule15 := &policyFwRule{SeqId: 15, family: "ipv4", dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, + pfRule15 := &policyFwRule{SeqID: 15, family: "ipv4", dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, networkInstance: niEncapTeVrfB} - pfRule16 := &policyFwRule{SeqId: 16, family: "ipv6", dscpSet: []uint8{dscpEncapA1, dscpEncapA2}, + pfRule16 := &policyFwRule{SeqID: 16, family: "ipv6", dscpSet: []uint8{dscpEncapB1, dscpEncapB2}, networkInstance: niEncapTeVrfB} - pfRule17 := &policyFwRule{SeqId: 17, networkInstance: niDefault} + pfRule17 := &policyFwRule{SeqID: 17, networkInstance: deviations.DefaultNetworkInstance(dut)} pfRuleList := []*policyFwRule{pfRule1, pfRule2, pfRule3, pfRule4, pfRule5, pfRule6, pfRule7, pfRule8, pfRule9, pfRule10, pfRule11, pfRule12, pfRule13, pfRule14, @@ -396,7 +397,7 @@ func configureVrfSelectionPolicy(t *testing.T, dut *ondatra.DUTDevice) { niPf.SetType(oc.Policy_Type_VRF_SELECTION_POLICY) for _, pfRule := range pfRuleList { - pfR := niPf.GetOrCreateRule(pfRule.SeqId) + pfR := niPf.GetOrCreateRule(pfRule.SeqID) if pfRule.family == "ipv4" { pfRProtoIP := pfR.GetOrCreateIpv4() @@ -455,45 +456,122 @@ func configNonDefaultNetworkInstance(t *testing.T, dut *ondatra.DUTDevice) { } } +// configStaticArp configures static arp entries +func configStaticArp(p string, ipv4addr string, macAddr string) *oc.Interface { + i := &oc.Interface{Name: ygot.String(p)} + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + s := i.GetOrCreateSubinterface(0) + s4 := s.GetOrCreateIpv4() + n4 := s4.GetOrCreateNeighbor(ipv4addr) + n4.LinkLayerAddress = ygot.String(macAddr) + return i +} + +func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + sb := &gnmi.SetBatch{} + p2 := dut.Port(t, "port2") + p3 := dut.Port(t, "port3") + p4 := dut.Port(t, "port4") + p5 := dut.Port(t, "port5") + p6 := dut.Port(t, "port6") + p7 := dut.Port(t, "port7") + portList := []*ondatra.Port{p2, p3, p4, p5, p6, p7} + for idx, p := range portList { + s := &oc.NetworkInstance_Protocol_Static{ + Prefix: ygot.String(magicIP + "/32"), + NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ + strconv.Itoa(idx): { + Index: ygot.String(strconv.Itoa(idx)), + InterfaceRef: &oc.NetworkInstance_Protocol_Static_NextHop_InterfaceRef{ + Interface: ygot.String(p.Name()), + }, + }, + }, + } + sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) + gnmi.BatchUpdate(sb, sp.Static(magicIP+"/32").Config(), s) + gnmi.BatchUpdate(sb, gnmi.OC().Interface(p.Name()).Config(), configStaticArp(p.Name(), magicIP, magicMac)) + } + sb.Set(t, dut) +} + func configureGribiRoute(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice, args *testArgs) { t.Helper() // Programming AFT entries for prefixes in DEFAULT VRF + if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { + args.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(11).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port2").Name()).WithIPAddress(magicIP), + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(12).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port3").Name()).WithIPAddress(magicIP), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(11).AddNextHop(11, 1).AddNextHop(12, 3), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(13).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port4").Name()).WithIPAddress(magicIP), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(12).AddNextHop(13, 2), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(14).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port5").Name()).WithIPAddress(magicIP), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(13).AddNextHop(14, 1), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(15).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port6").Name()).WithIPAddress(magicIP), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(14).AddNextHop(15, 1), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(16).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port7").Name()).WithIPAddress(magicIP), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(15).AddNextHop(16, 1), + ) + } else { + args.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(11).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port2").Name()), + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(12).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port3").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(11).AddNextHop(11, 1).AddNextHop(12, 3), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(13).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port4").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(12).AddNextHop(13, 2), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(14).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port5").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(13).AddNextHop(14, 1), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(15).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port6").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(14).AddNextHop(15, 1), + + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithIndex(16).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port7").Name()), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(15).AddNextHop(16, 1), + ) + } + if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { + t.Logf("Could not program entries via client, got err, check error codes: %v", err) + } + args.client.Modify().AddEntry(t, - fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(11).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port2").Name()), - fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(12).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port3").Name()), - fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithID(11).AddNextHop(11, 1).AddNextHop(12, 3), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF1+"/"+maskLen32).WithNextHopGroup(11), - - fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(13).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port4").Name()), - fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithID(12).AddNextHop(13, 2), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF2+"/"+maskLen32).WithNextHopGroup(12), - - fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(14).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port5").Name()), - fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithID(13).AddNextHop(14, 1), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF3+"/"+maskLen32).WithNextHopGroup(13), - - fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(15).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port6").Name()), - fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithID(14).AddNextHop(15, 1), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF4+"/"+maskLen32).WithNextHopGroup(14), - - fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(16).WithMacAddress(magicMac).WithInterfaceRef(dut.Port(t, "port7").Name()), - fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithID(15).AddNextHop(16, 1), fluent.IPv4Entry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryDefVRF5+"/"+maskLen32).WithNextHopGroup(15), ) @@ -530,14 +608,14 @@ func configureGribiRoute(ctx context.Context, t *testing.T, dut *ondatra.DUTDevi WithIndex(3).WithIPAddress(gribiIPv4EntryDefVRF3), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(2).AddNextHop(3, 1).WithBackupNHG(2000), - fluent.IPv4Entry().WithNetworkInstance(niTeVrf222). + fluent.IPv4Entry().WithNetworkInstance(niTeVrf222).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryVRF2221+"/"+maskLen32).WithNextHopGroup(2), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithIndex(5).WithIPAddress(gribiIPv4EntryDefVRF5), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(4).AddNextHop(5, 1).WithBackupNHG(2000), - fluent.IPv4Entry().WithNetworkInstance(niTeVrf222). + fluent.IPv4Entry().WithNetworkInstance(niTeVrf222).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryVRF2222+"/"+maskLen32).WithNextHopGroup(4), ) if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { @@ -584,14 +662,14 @@ func configureGribiRoute(ctx context.Context, t *testing.T, dut *ondatra.DUTDevi WithIndex(2).WithIPAddress(gribiIPv4EntryDefVRF2), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(1).AddNextHop(1, 1).AddNextHop(2, 3).WithBackupNHG(1000), - fluent.IPv4Entry().WithNetworkInstance(niTeVrf111). + fluent.IPv4Entry().WithNetworkInstance(niTeVrf111).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryVRF1111+"/"+maskLen32).WithNextHopGroup(1), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithIndex(4).WithIPAddress(gribiIPv4EntryDefVRF4), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(3).AddNextHop(4, 1).WithBackupNHG(1001), - fluent.IPv4Entry().WithNetworkInstance(niTeVrf111). + fluent.IPv4Entry().WithNetworkInstance(niTeVrf111).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryVRF1112+"/"+maskLen32).WithNextHopGroup(3), ) if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { @@ -622,7 +700,7 @@ func configureGribiRoute(ctx context.Context, t *testing.T, dut *ondatra.DUTDevi WithNextHopNetworkInstance(niTeVrf111), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(101).AddNextHop(101, 1).AddNextHop(102, 3).WithBackupNHG(18), - fluent.IPv4Entry().WithNetworkInstance(niEncapTeVrfA). + fluent.IPv4Entry().WithNetworkInstance(niEncapTeVrfA).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithPrefix(gribiIPv4EntryEncapVRF+"/"+maskLen24).WithNextHopGroup(101), ) if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { @@ -667,7 +745,12 @@ func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfName, dutAreaAddres isisIntfLevel.Enabled = ygot.Bool(true) isisIntfLevelAfi := isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST) isisIntfLevelAfi.Metric = ygot.Uint32(200) - isisIntfLevelAfi.Enabled = ygot.Bool(true) + if deviations.ISISInterfaceAfiUnsupported(dut) { + isisIntf.Af = nil + } + if deviations.MissingIsisInterfaceAfiSafiEnable(dut) { + isisIntfLevelAfi.Enabled = nil + } gnmi.Replace(t, dut, dutConfIsisPath.Config(), prot) } @@ -1094,11 +1177,29 @@ func TestEncapFrr(t *testing.T) { t.Log("Configure Non-Default Network Instances") configNonDefaultNetworkInstance(t, dut) + if deviations.BackupNHGRequiresVrfWithDecap(dut) { + d := &oc.Root{} + ni := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + pf := ni.GetOrCreatePolicyForwarding() + fp1 := pf.GetOrCreatePolicy("match-ipip") + fp1.SetType(oc.Policy_Type_VRF_SELECTION_POLICY) + fp1.GetOrCreateRule(1).GetOrCreateIpv4().Protocol = oc.UnionUint8(ipOverIPProtocol) + fp1.GetOrCreateRule(1).GetOrCreateAction().NetworkInstance = ygot.String(deviations.DefaultNetworkInstance(dut)) + p1 := dut.Port(t, "port1") + intf := pf.GetOrCreateInterface(p1.Name()) + intf.ApplyVrfSelectionPolicy = ygot.String("match-ipip") + gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Config(), pf) + } + configureDUT(t, dut, dutPorts) t.Log("Apply vrf selection policy to DUT port-1") configureVrfSelectionPolicy(t, dut) + if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { + staticARPWithMagicUniversalIP(t, dut) + } + t.Log("Install BGP route resolved by ISIS.") t.Log("Configure ISIS on DUT") configureISIS(t, dut, dut.Port(t, "port8").Name(), dutAreaAddress, dutSysID) @@ -1242,8 +1343,10 @@ func TestEncapFrr(t *testing.T) { if tc.encapUnviable == "primaryBackupRoutingSingle" { args.client.Modify().AddEntry(t, fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(1000).WithDecapsulateHeader(fluent.IPinIP). + WithIndex(1100).WithDecapsulateHeader(fluent.IPinIP). WithNextHopNetworkInstance(deviations.DefaultNetworkInstance(dut)), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(1000).AddNextHop(1100, 1), ) if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { t.Logf("Could not program entries via client, got err, check error codes: %v", err) @@ -1252,11 +1355,15 @@ func TestEncapFrr(t *testing.T) { if tc.encapUnviable == "primaryBackupRoutingAll" { args.client.Modify().AddEntry(t, fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(1000).WithDecapsulateHeader(fluent.IPinIP). + WithIndex(1100).WithDecapsulateHeader(fluent.IPinIP). WithNextHopNetworkInstance(deviations.DefaultNetworkInstance(dut)), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(1000).AddNextHop(1100, 1), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(1001).WithDecapsulateHeader(fluent.IPinIP). + WithIndex(1101).WithDecapsulateHeader(fluent.IPinIP). WithNextHopNetworkInstance(deviations.DefaultNetworkInstance(dut)), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithID(1001).AddNextHop(1101, 1), ) if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { t.Logf("Could not program entries via client, got err, check error codes: %v", err) @@ -1269,7 +1376,7 @@ func TestEncapFrr(t *testing.T) { fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(1003).AddNextHop(1003, 1), fluent.IPv4Entry().WithNetworkInstance(niEncapTeVrfA). - WithPrefix("0.0.0.0/0").WithNextHopGroup(1003), + WithPrefix("0.0.0.0/0").WithNextHopGroup(1003).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)), ) if err := awaitTimeout(args.ctx, t, args.client, time.Minute); err != nil { t.Logf("Could not program entries via client, got err, check error codes: %v", err) diff --git a/feature/gribi/otg_tests/encap_frr/metadata.textproto b/feature/gribi/otg_tests/encap_frr/metadata.textproto index 1d9a9ef004d..a0b9f7a1b75 100644 --- a/feature/gribi/otg_tests/encap_frr/metadata.textproto +++ b/feature/gribi/otg_tests/encap_frr/metadata.textproto @@ -39,5 +39,13 @@ platform_exceptions: { deviations: { interface_enabled: true default_network_instance: "default" + isis_instance_enabled_required: true + static_protocol_name: "STATIC" + gribi_mac_override_static_arp_static_route: true + ttl_copy_unsupported: true + omit_l2_mtu: true + backup_nhg_requires_vrf_with_decap: true + missing_isis_interface_afi_safi_enable: true + isis_interface_afi_unsupported: true } } From f4fe904c315a599eb1c4761044964d370400d24c Mon Sep 17 00:00:00 2001 From: sunilprgit Date: Wed, 27 Mar 2024 14:58:01 +0530 Subject: [PATCH 50/97] arista deviation and OTG fix (#2852) --- .../prefix_set_test/bgp_prefix_set_test.go | 12 ++++-------- .../otg_tests/prefix_set_test/metadata.textproto | 13 +++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go b/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go index e5e8dbacce7..5034077c35f 100644 --- a/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go +++ b/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go @@ -333,25 +333,21 @@ func configureOTG(t *testing.T, otg *otg.OTG) { iDut1Bgp := iDut1Dev.Bgp().SetRouterId(iDut1Ipv4.Address()) iDut1Bgp4Peer := iDut1Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut1Ipv4.Name()).Peers().Add().SetName(atePort1.Name + ".BGP4.peer") iDut1Bgp4Peer.SetPeerAddress(iDut1Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) - iDut1Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) - iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) // eBGP v6 seesion on Port1. iDut1Bgp6Peer := iDut1Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut1Ipv6.Name()).Peers().Add().SetName(atePort1.Name + ".BGP6.peer") iDut1Bgp6Peer.SetPeerAddress(iDut1Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) - iDut1Bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) - iDut1Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + iDut1Bgp6Peer.LearnedInformationFilter().SetUnicastIpv6Prefix(true) // eBGP v4 seesion on Port2. iDut2Bgp := iDut2Dev.Bgp().SetRouterId(iDut2Ipv4.Address()) iDut2Bgp4Peer := iDut2Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut2Ipv4.Name()).Peers().Add().SetName(atePort2.Name + ".BGP4.peer") iDut2Bgp4Peer.SetPeerAddress(iDut2Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) - iDut2Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) - iDut2Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + iDut2Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) // eBGP v6 seesion on Port2. iDut2Bgp6Peer := iDut2Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut2Ipv6.Name()).Peers().Add().SetName(atePort2.Name + ".BGP6.peer") iDut2Bgp6Peer.SetPeerAddress(iDut2Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) - iDut2Bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) - iDut2Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + iDut2Bgp6Peer.LearnedInformationFilter().SetUnicastIpv6Prefix(true) // eBGP V4 routes from Port1. bgpNeti1Bgp4PeerRoutes := iDut1Bgp4Peer.V4Routes().Add().SetName(atePort1.Name + ".BGP4.Route") diff --git a/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto b/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto index 9bb11b3d562..a4365e30d39 100644 --- a/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto @@ -17,6 +17,19 @@ platform_exceptions: { skip_prefix_set_mode: true } } +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + interface_enabled: true + default_network_instance: "default" + missing_value_for_defaults: true + skip_set_rp_match_set_options: true + + } +} tags: TAGS_AGGREGATION tags: TAGS_TRANSIT tags: TAGS_DATACENTER_EDGE From fc565da0b30cf84f89de4638169919dedc37fb0b Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Wed, 27 Mar 2024 18:10:49 +0530 Subject: [PATCH 51/97] add new import export policy to bgp neighbors (#2854) --- .../management_ha_test/management_ha_test.go | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/feature/system/management/otg_tests/management_ha_test/management_ha_test.go b/feature/system/management/otg_tests/management_ha_test/management_ha_test.go index 1000241b90d..c5087da389b 100644 --- a/feature/system/management/otg_tests/management_ha_test/management_ha_test.go +++ b/feature/system/management/otg_tests/management_ha_test/management_ha_test.go @@ -107,6 +107,7 @@ func TestManagementHA1(t *testing.T) { configureLoopbackOnDUT(t, bs.DUT) advertiseDUTLoopbackToATE(t, bs.DUT) configureStaticRoute(t, bs.DUT, bs.ATEPorts[2].IPv6) + configureImportExportBGPPolicy(t, bs) t.Run("traffic received by port1 or port2", func(t *testing.T) { createFlowV6(t, bs) @@ -308,6 +309,57 @@ func advertiseDUTLoopbackToATE(t *testing.T, dut *ondatra.DUTDevice) { batchSet.Set(t, dut) } +func configureImportExportBGPPolicy(t *testing.T, bs *cfgplugins.BGPSession) { + root := &oc.Root{} + batchSet := &gnmi.SetBatch{} + + rp := root.GetOrCreateRoutingPolicy() + pdef1 := rp.GetOrCreatePolicyDefinition("importRoutePolicy") + stmt1, err := pdef1.AppendNewStatement("routePolicyStatement1") + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", "routePolicyStatement1", err) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + prefixSet1 := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet("ps1") + prefixSet1.SetMode(oc.PrefixSet_Mode_IPV6) + prefixSet1.GetOrCreatePrefix(defaultRoute+"/0", "exact") + + if !deviations.SkipSetRpMatchSetOptions(bs.DUT) { + stmt1.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + stmt1.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet("ps1") + + pdef2 := rp.GetOrCreatePolicyDefinition("exportRoutePolicy") + stmt2, err := pdef2.AppendNewStatement("routePolicyStatement2") + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", "routePolicyStatement2", err) + } + stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + prefixSet2 := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet("ps2") + prefixSet2.SetMode(oc.PrefixSet_Mode_IPV6) + prefixSet2.GetOrCreatePrefix(dutlo0Attrs.IPv6CIDR(), "exact") + + if !deviations.SkipSetRpMatchSetOptions(bs.DUT) { + stmt2.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + stmt2.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet("ps2") + + gnmi.BatchUpdate(batchSet, gnmi.OC().RoutingPolicy().Config(), rp) + + dni := deviations.DefaultNetworkInstance(bs.DUT) + for _, neighbor := range []string{bs.ATEPorts[0].IPv6, bs.ATEPorts[1].IPv6} { + pathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(neighbor).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policyV6 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp().GetOrCreateNeighbor(neighbor).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policyV6.SetImportPolicy([]string{"importRoutePolicy"}) + policyV6.SetExportPolicy([]string{"exportRoutePolicy"}) + gnmi.BatchReplace(batchSet, pathV6.Config(), policyV6) + } + + batchSet.Set(t, bs.DUT) +} + func lossPct(tx, rx float64) float64 { return (math.Abs(tx-rx) * 100) / tx } From 1b16e43c73843951478440bef9aabdb25ad15dc0 Mon Sep 17 00:00:00 2001 From: anksaiki Date: Wed, 27 Mar 2024 10:30:23 -0400 Subject: [PATCH 52/97] zr_tunable_parameters fix telemetry and configuration (#2848) --- .../metadata.textproto | 1 - .../zr_tunable_parameters_test.go | 99 +++++++++---------- internal/deviations/deviations.go | 5 +- internal/samplestream/samplestream.go | 37 +++---- proto/metadata.proto | 5 +- proto/metadata_go_proto/metadata.pb.go | 5 +- 6 files changed, 67 insertions(+), 85 deletions(-) diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto b/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto index c4187439461..5bd64161c63 100644 --- a/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/metadata.textproto @@ -11,7 +11,6 @@ platform_exceptions: { deviations: { interface_enabled: true default_network_instance: "default" - missing_port_to_optical_channel_component_mapping: true missing_zr_optical_channel_tunable_parameters_telemetry: true } } diff --git a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go index 776805fd36a..04c40b069f1 100644 --- a/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go +++ b/feature/platform/transceiver/tests/zr_tunable_parameters_test/zr_tunable_parameters_test.go @@ -63,7 +63,7 @@ func Test400ZRTunableFrequency(t *testing.T) { description: "100GHz grid", startFreq: 191400000, endFreq: 196100000, - freqStep: 100000, + freqStep: 100000 * 4, targetOutputPower: -13, }, { @@ -72,7 +72,7 @@ func Test400ZRTunableFrequency(t *testing.T) { description: "75GHz grid", startFreq: 191375000, endFreq: 196100000, - freqStep: 75000, + freqStep: 75000 * 6, targetOutputPower: -9, }, } @@ -90,6 +90,8 @@ func Test400ZRTunableFrequency(t *testing.T) { Frequency: ygot.Uint64(freq), OperationalMode: ygot.Uint16(dp16QAM), }) + gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, freq, tc.targetOutputPower) }) } @@ -140,6 +142,8 @@ func Test400ZRTunableOutputPower(t *testing.T) { Frequency: ygot.Uint64(tc.frequency), OperationalMode: ygot.Uint16(dp16QAM), }) + gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, tc.frequency, top) }) } @@ -170,6 +174,8 @@ func Test400ZRInterfaceFlap(t *testing.T) { Frequency: ygot.Uint64(frequency), OperationalMode: ygot.Uint16(dp16QAM), }) + gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) t.Run("Telemetry before flap", func(t *testing.T) { validateOpticsTelemetry(t, []*samplestream.SampleStream[*oc.Component]{streamOC1, streamOC2}, frequency, targetPower) }) @@ -186,8 +192,8 @@ func Test400ZRInterfaceFlap(t *testing.T) { // Re-enable the interfaces on the DUT. gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Enabled().Config(), true) gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Enabled().Config(), true) - gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_UP) - gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).AdminStatus().State(), 30*time.Second, oc.Interface_AdminStatus_UP) + gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) // Verify the ZR optics tune back to the correct frequency and TX output // power as per the configuration and related telemetry values are updated // to the value in the normal range again. @@ -209,10 +215,7 @@ func validateOpticsTelemetry(t *testing.T, streams []*samplestream.SampleStream[ } ocs = append(ocs, v.GetOpticalChannel()) } - if deviations.MissingZROpticalChannelTunableParametersTelemetry(dut) { - t.Log("Skipping Tunable Parameters Telemetry validation. Deviation MissingZROpticalChannelTunableParametersTelemetry enabled.") - return - } + for _, oc := range ocs { opm := oc.GetOperationalMode() inst := oc.GetCarrierFrequencyOffset().GetInstant() @@ -227,18 +230,22 @@ func validateOpticsTelemetry(t *testing.T, streams []*samplestream.SampleStream[ if inst < -1*frequencyTolerance || inst > frequencyTolerance { t.Errorf("Optical-Channel: carrier-frequency-offset not in tolerable range, got: %v, want: (+/-)%v", inst, frequencyTolerance) } - // For reported data check for validity: min <= avg/instant <= max - if min > inst { - t.Errorf("Optical-Channel: carrier-frequency-offset min: %v greater than carrier-frequency-offset instant: %v", min, inst) - } - if max < inst { - t.Errorf("Optical-Channel: carrier-frequency-offset max: %v less than carrier-frequency-offset instant: %v", max, inst) - } - if min > avg { - t.Errorf("Optical-Channel: carrier-frequency-offset min: %v greater than carrier-frequency-offset avg: %v", min, avg) - } - if max < avg { - t.Errorf("Optical-Channel: carrier-frequency-offset max: %v less than carrier-frequency-offset avg: %v", max, avg) + if deviations.MissingZROpticalChannelTunableParametersTelemetry(dut) { + t.Log("Skipping Min/Max/Avg Tunable Parameters Telemetry validation. Deviation MissingZROpticalChannelTunableParametersTelemetry enabled.") + } else { + // For reported data check for validity: min <= avg/instant <= max + if min > inst { + t.Errorf("Optical-Channel: carrier-frequency-offset min: %v greater than carrier-frequency-offset instant: %v", min, inst) + } + if max < inst { + t.Errorf("Optical-Channel: carrier-frequency-offset max: %v less than carrier-frequency-offset instant: %v", max, inst) + } + if min > avg { + t.Errorf("Optical-Channel: carrier-frequency-offset min: %v greater than carrier-frequency-offset avg: %v", min, avg) + } + if max < avg { + t.Errorf("Optical-Channel: carrier-frequency-offset max: %v less than carrier-frequency-offset avg: %v", max, avg) + } } inst = oc.GetOutputPower().GetInstant() avg = oc.GetOutputPower().GetAvg() @@ -250,18 +257,22 @@ func validateOpticsTelemetry(t *testing.T, streams []*samplestream.SampleStream[ if inst < outputPower-1 || inst > outputPower+1 { t.Errorf("Optical-Channel: output-power not in tolerable range, got: %v, want: %v", inst, outputPower) } - // For reported data check for validity: min <= avg/instant <= max - if min > inst { - t.Errorf("Optical-Channel: output-power min: %v greater than output-power instant: %v", min, inst) - } - if max < inst { - t.Errorf("Optical-Channel: output-power max: %v less than output-power instant: %v", max, inst) - } - if min > avg { - t.Errorf("Optical-Channel: output-power min: %v greater than output-power avg: %v", min, avg) - } - if max < avg { - t.Errorf("Optical-Channel: output-power max: %v less than output-power avg: %v", max, avg) + if deviations.MissingZROpticalChannelTunableParametersTelemetry(dut) { + t.Log("Skipping Min/Max/Avg Tunable Parameters Telemetry validation. Deviation MissingZROpticalChannelTunableParametersTelemetry enabled.") + } else { + // For reported data check for validity: min <= avg/instant <= max + if min > inst { + t.Errorf("Optical-Channel: output-power min: %v greater than output-power instant: %v", min, inst) + } + if max < inst { + t.Errorf("Optical-Channel: output-power max: %v less than output-power instant: %v", max, inst) + } + if min > avg { + t.Errorf("Optical-Channel: output-power min: %v greater than output-power avg: %v", min, avg) + } + if max < avg { + t.Errorf("Optical-Channel: output-power max: %v less than output-power avg: %v", max, avg) + } } if got, want := oc.GetFrequency(), frequency; got != want { t.Errorf("Optical-Channel: frequency: %v, want: %v", got, want) @@ -272,26 +283,6 @@ func validateOpticsTelemetry(t *testing.T, streams []*samplestream.SampleStream[ // opticalChannelFromPort returns the connected optical channel component name for a given ondatra port. func opticalChannelFromPort(t *testing.T, dut *ondatra.DUTDevice, p *ondatra.Port) string { t.Helper() - if deviations.MissingPortToOpticalChannelMapping(dut) { - switch dut.Vendor() { - case ondatra.ARISTA: - return fmt.Sprintf("%s-Optical0", p.Name()) - default: - t.Fatal("Manual Optical channel name required when deviation missing_port_to_optical_channel_component_mapping applied.") - } - } - compName := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).HardwarePort().State()) - for { - comp, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(compName).State()).Val() - if !ok { - t.Fatalf("Recursive optical channel lookup failed for port: %s, component %s not found.", p.Name(), compName) - } - if comp.GetType() == oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_OPTICAL_CHANNEL { - return compName - } - if comp.GetParent() == "" { - t.Fatalf("Recursive optical channel lookup failed for port: %s, parent of component %s not found.", p.Name(), compName) - } - compName = comp.GetParent() - } + tr := gnmi.Get(t, dut, gnmi.OC().Interface(p.Name()).Transceiver().State()) + return gnmi.Get(t, dut, gnmi.OC().Component(tr).Transceiver().Channel(0).AssociatedOpticalChannel().State()) } diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index f4f5a8eca77..64ac4aa7da5 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -875,8 +875,9 @@ func MissingStaticRouteDropNextHopTelemetry(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetMissingStaticRouteDropNextHopTelemetry() } -// Device missing 400ZR optical-channel tunable parameters telemetry. -// Arista: https://partnerissuetracker.corp.google.com/issues/330777809 +// MissingZROpticalChannelTunableParametersTelemetry returns true for devices missing 400ZR +// optical-channel tunable parameters telemetry: min/max/avg. +// Arista: https://partnerissuetracker.corp.google.com/issues/319314781 func MissingZROpticalChannelTunableParametersTelemetry(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetMissingZrOpticalChannelTunableParametersTelemetry() } diff --git a/internal/samplestream/samplestream.go b/internal/samplestream/samplestream.go index b65c02ca5d8..ed8160c6286 100644 --- a/internal/samplestream/samplestream.go +++ b/internal/samplestream/samplestream.go @@ -19,11 +19,11 @@ const ( // SampleStream represents a gNMI Subscription with SAMPLE mode. type SampleStream[T any] struct { - dataMu sync.Mutex // Lock that protects the received data and the next channel. - nextCh chan *ygnmi.Value[T] // Channel that holds the next sample. - data []*ygnmi.Value[T] // Data received from gNMI call. - cancel context.CancelFunc // Cancels the subscription. - interval time.Duration // Configured interval for the SAMPLE mode stream. + dataMu sync.Mutex // Lock that protects the received data and the next channel. + lastVal *ygnmi.Value[T] // Holds the last received sample. + data []*ygnmi.Value[T] // Data received from gNMI call. + cancel context.CancelFunc // Cancels the subscription. + interval time.Duration // Configured interval for the SAMPLE mode stream. } // New creates a new SampleStream. @@ -42,10 +42,11 @@ func New[T any](t *testing.T, dut *ondatra.DUTDevice, q ygnmi.SingletonQuery[T], ygnmi.Watch(ctx, c, q, func(v *ygnmi.Value[T]) error { s.dataMu.Lock() defer s.dataMu.Unlock() - s.data = append(s.data, v) - if s.nextCh != nil { - s.nextCh <- v + if !v.IsPresent() { + return ygnmi.Continue } + s.data = append(s.data, v) + s.lastVal = v return ygnmi.Continue }, ygnmi.WithSubscriptionMode(gpb.SubscriptionMode_SAMPLE), ygnmi.WithSampleInterval(interval)) return s @@ -54,22 +55,10 @@ func New[T any](t *testing.T, dut *ondatra.DUTDevice, q ygnmi.SingletonQuery[T], // Next returns the next sample received within the sample interval. // If no sample is received within the interval, nil is returned. func (s *SampleStream[T]) Next() *ygnmi.Value[T] { - func() { - s.dataMu.Lock() - defer s.dataMu.Unlock() - s.nextCh = make(chan *ygnmi.Value[T], 1) - }() - defer func() { - s.dataMu.Lock() - defer s.dataMu.Unlock() - s.nextCh = nil - }() - select { - case v := <-s.nextCh: - return v - case <-time.After(s.interval + intervalTolerance): - return nil - } + time.Sleep(s.interval + intervalTolerance) + s.dataMu.Lock() + defer s.dataMu.Unlock() + return s.lastVal } // Nexts calls Next() count times and returns the slice of returned samples. diff --git a/proto/metadata.proto b/proto/metadata.proto index b9d115f45ac..2bdeb5c6969 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -461,8 +461,9 @@ message Metadata { // Device missing telemetry for static route that has DROP next hop. // Arista: https://partnerissuetracker.corp.google.com/issues/330619816 bool missing_static_route_drop_next_hop_telemetry = 162; - // Device missing 400ZR optical-channel tunable parameters telemetry. - // Arista: https://partnerissuetracker.corp.google.com/issues/330777809 + // Device missing 400ZR optical-channel tunable parameters telemetry: + // min/max/avg. + // Arista: https://partnerissuetracker.corp.google.com/issues/319314781 bool missing_zr_optical_channel_tunable_parameters_telemetry = 163; // Reserved field numbers and identifiers. diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index d8f63266324..4e6f643f6b0 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -732,8 +732,9 @@ type Metadata_Deviations struct { // Device missing telemetry for static route that has DROP next hop. // Arista: https://partnerissuetracker.corp.google.com/issues/330619816 MissingStaticRouteDropNextHopTelemetry bool `protobuf:"varint,162,opt,name=missing_static_route_drop_next_hop_telemetry,json=missingStaticRouteDropNextHopTelemetry,proto3" json:"missing_static_route_drop_next_hop_telemetry,omitempty"` - // Device missing 400ZR optical-channel tunable parameters telemetry. - // Arista: https://partnerissuetracker.corp.google.com/issues/330777809 + // Device missing 400ZR optical-channel tunable parameters telemetry: + // min/max/avg. + // Arista: https://partnerissuetracker.corp.google.com/issues/319314781 MissingZrOpticalChannelTunableParametersTelemetry bool `protobuf:"varint,163,opt,name=missing_zr_optical_channel_tunable_parameters_telemetry,json=missingZrOpticalChannelTunableParametersTelemetry,proto3" json:"missing_zr_optical_channel_tunable_parameters_telemetry,omitempty"` } From ee948a7001884148d19f1133021ec5f1e39356a7 Mon Sep 17 00:00:00 2001 From: Matthew Starkey <157065700+mastarkey@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:43:08 -0700 Subject: [PATCH 53/97] RT-5.5: Interface hold-time (#2658) * Hold down timers test * Test requires that DUT and ATE have clocks synced within 10's of msec of each other --------- Co-authored-by: Darren Loher --- .../holdtime_test/holddown_timers_test.go | 616 ++++++++++++++++++ .../holdtime_test/metadata.textproto | 11 +- 2 files changed, 626 insertions(+), 1 deletion(-) create mode 100644 feature/interface/holdtime/otg_tests/holdtime_test/holddown_timers_test.go diff --git a/feature/interface/holdtime/otg_tests/holdtime_test/holddown_timers_test.go b/feature/interface/holdtime/otg_tests/holdtime_test/holddown_timers_test.go new file mode 100644 index 00000000000..913505b0063 --- /dev/null +++ b/feature/interface/holdtime/otg_tests/holdtime_test/holddown_timers_test.go @@ -0,0 +1,616 @@ +package holddown_times_test + +import ( + "fmt" + "strconv" + "testing" + "time" + + "github.com/openconfig/ondatra/netutil" + + "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/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +const ( + ipv4PrefixLen = 30 + ipv6PrefixLen = 126 + lagName = "LAGRx" // OTG LAG NAME + upTimer = 5000 + downTimer = 300 + toleranceMS = 200 // Define the tolerance in milliseconds + +) + +var ( + aggID string + dutPort1Intf *ondatra.Port + ateSrc = attrs.Attributes{ + Name: "ateSrc", + MAC: "02:11:01:00:00:01", + IPv4: "192.0.2.1", + IPv6: "2001:db8::1", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + } + + dutDst = attrs.Attributes{ + Desc: "DUT to ATE destination", + IPv4: "192.0.2.5", + IPv6: "2001:db8::5", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + } + + ateDst = attrs.Attributes{ + Name: "ateDst", + MAC: "02:12:01:00:00:01", + IPv4: "192.0.2.6", + IPv6: "2001:db8::6", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + } +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func configureDUTBundle(t *testing.T, dut *ondatra.DUTDevice, aggPorts []*ondatra.Port, aggID string) { + t.Helper() + + agg := dutDst.NewOCInterface(aggID, dut) + agg.Type = oc.IETFInterfaces_InterfaceType_ieee8023adLag + agg.GetOrCreateAggregation().LagType = oc.IfAggregate_AggregationType_STATIC + gnmi.Replace(t, dut, gnmi.OC().Interface(aggID).Config(), agg) + + for _, port := range aggPorts { + d := &oc.Root{} + + i := d.GetOrCreateInterface(port.Name()) + i.GetOrCreateEthernet().AggregateId = ygot.String(aggID) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + + if deviations.InterfaceEnabled(dut) { + i.Enabled = ygot.Bool(true) + } + gnmi.Replace(t, dut, gnmi.OC().Interface(port.Name()).Config(), i) + } +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice, aggID string) { + t.Helper() + fptest.ConfigureDefaultNetworkInstance(t, dut) + dutAggPorts := []*ondatra.Port{ + dut.Port(t, "port1"), + } + configureDUTBundle(t, dut, dutAggPorts, aggID) + +} + +func configureOTG(t *testing.T, + ate *ondatra.ATEDevice, + aggID string) { + t.Helper() + + top := gosnappi.NewConfig() + + ateAggPorts := []*ondatra.Port{ + ate.Port(t, "port1"), + } + configureOTGBundle(t, top, ateAggPorts, aggID) + + t.Log(top.String()) + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + + OTGInterfaceUP(t, ate) +} + +func OTGInterfaceUP(t *testing.T, + ate *ondatra.ATEDevice) { + + p1 := ondatra.ATE(t, "ate").Port(t, "port1") + portStateAction := gosnappi.NewControlState() + + // make sure interface is not down + portStateAction.Port().Link().SetPortNames([]string{p1.ID()}).SetState(gosnappi.StatePortLinkState.UP) + ate.OTG().SetControlState(t, portStateAction) +} + +func OTGInterfaceDOWN(t *testing.T, + ate *ondatra.ATEDevice, + dut *ondatra.DUTDevice) time.Time { + + p1 := ondatra.ATE(t, "ate").Port(t, "port1") + portStateAction := gosnappi.NewControlState() + timestamp := gnmi.Get(t, dut, gnmi.OC().System().CurrentDatetime().State()) + + timeObj, err := time.Parse(time.RFC3339Nano, timestamp) + if err != nil { + t.Errorf("Failed to parse time string: %v", timestamp) + return timeObj + } + + // make sure interface is not down + portStateAction.Port().Link().SetPortNames([]string{p1.ID()}).SetState(gosnappi.StatePortLinkState.DOWN) + ate.OTG().SetControlState(t, portStateAction) + + return timeObj +} + +func configureOTGBundle(t *testing.T, + + top gosnappi.Config, + aggPorts []*ondatra.Port, + aggID string) { + t.Helper() + agg := top.Lags().Add().SetName(lagName) + lagID, _ := strconv.Atoi(aggID) + agg.Protocol().Static().SetLagId(uint32(lagID)) + + for i, p := range aggPorts { + port := top.Ports().Add().SetName(p.ID()) + agg.Ports().Add().SetPortName(port.Name()).Ethernet().SetMac(ateSrc.MAC).SetName("LAGRx-" + strconv.Itoa(i)) + } + + dstDev := top.Devices().Add().SetName(agg.Name() + ".dev") + dstEth := dstDev.Ethernets().Add().SetName(lagName + ".Eth").SetMac(ateDst.MAC) + dstEth.Connection().SetLagName(agg.Name()) + dstEth.Ipv4Addresses().Add().SetName(lagName + ".IPv4").SetAddress(ateDst.IPv4).SetGateway(dutDst.IPv4).SetPrefix(uint32(ateDst.IPv4Len)) +} + +func displaySummaryTable(t *testing.T, + preActionTS, + postActionTS string, + actualDurationInMS, + minToleranceInMS, + maxToleranceInMS int64, + expectedOperStatus, + actualOperStatus string, + pass bool) { + + result := "FAIL" + if pass { + result = "PASS" + } + + // Prepare the strings for output. + expectedDurationStr := "300ms" // Assuming this is a constant value + + minToleranceStr := strconv.Itoa(int(minToleranceInMS)) + "ms" + maxToleranceStr := strconv.Itoa(int(maxToleranceInMS)) + "ms" + actualDurationStr := strconv.Itoa(int(actualDurationInMS)) + "ms" + + // Create a slice of metrics and corresponding values. + metrics := []string{"Pre-action TS", + "Post-action TS", + "Expected Duration", + "Actual Duration", + "Min Tolerance", + "Max Tolerance", + "Expected Oper Status", + "Actual Oper Status", + "Result"} + values := []string{preActionTS, + postActionTS, + expectedDurationStr, + actualDurationStr, + minToleranceStr, + maxToleranceStr, + expectedOperStatus, + actualOperStatus, + result} + + // Find the maximum width for the metrics to align the values. + maxMetricWidth := 0 + for _, metric := range metrics { + if len(metric) > maxMetricWidth { + maxMetricWidth = len(metric) + } + } + + // Create the vertical table. + table := "" + for i, metric := range metrics { + table += fmt.Sprintf("%-*s: %s\n", maxMetricWidth, metric, values[i]) + } + + t.Logf("\n%s", table) +} + +func flapOTGInterface(t *testing.T, + ate *ondatra.ATEDevice, + dut *ondatra.DUTDevice, + actionState string) (time.Time, time.Time, string, string) { + + // Shut down OTG Interface + p1 := ondatra.ATE(t, "ate").Port(t, "port1") + portStateAction := gosnappi.NewControlState() + + var otgStateChangeTsStr string + + // TC2 Step 1 Read timestamp of last oper-status change form DUT port-1 + preStateTSSTR := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).LastChange().State()) + DutLastChangeTS1 := time.Unix(0, int64(preStateTSSTR)).UTC().Format(time.RFC3339Nano) + t.Logf("Step1. DutLastChangeTS1 is: %v", DutLastChangeTS1) + if actionState == "UP" { + portStateAction.Port().Link().SetPortNames([]string{p1.ID()}).SetState(gosnappi.StatePortLinkState.UP) + otgStateChangeTsStr = gnmi.Get(t, dut, gnmi.OC().System().CurrentDatetime().State()) + ate.OTG().SetControlState(t, portStateAction) + } else if actionState == "DOWN" { + // TC2 Step 2 Bring Down OTG Interface + t.Log("RT-5.5.2: Bring Down OTG Interface") + portStateAction.Port().Link().SetPortNames([]string{p1.ID()}).SetState(gosnappi.StatePortLinkState.DOWN) + otgStateChangeTsStr = gnmi.Get(t, dut, gnmi.OC().System().CurrentDatetime().State()) + ate.OTG().SetControlState(t, portStateAction) + + // TC2 Step 3 + t.Log("Step 3 sleeping 500ms") + time.Sleep(500 * time.Millisecond) + } + + // Step 4. Read timestamp of last oper-status change form DUT port-1 (DUT_LAST_CHANGE_TS) + postStateTSSTR := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).LastChange().State()) + DutLastChangeTS2STR := time.Unix(0, int64(postStateTSSTR)).UTC().Format(time.RFC3339Nano) + DutLastChangeOper2 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).OperStatus().State()) + + var expectedStatus oc.E_Interface_OperStatus + if actionState == "UP" { + expectedStatus = oc.Interface_OperStatus_UP + } else if actionState == "DOWN" { + expectedStatus = oc.Interface_OperStatus_DOWN + } + + // Step 5. verify oper-status is DOWN + if DutLastChangeOper2 != expectedStatus { + t.Errorf("Interface %s status got %v, want %v", aggID, DutLastChangeTS2STR, expectedStatus.String()) + } else { + t.Logf("Interface %s status got %v, want %v", aggID, DutLastChangeTS2STR, expectedStatus.String()) + } + + // convert string type change to time.time + otgStateChangeTs, err := time.Parse(time.RFC3339Nano, otgStateChangeTsStr) + if err != nil { + t.Fatalf("failed to parse event timestamp: %v %v", err, otgStateChangeTs) + } + + DutLastChangeTS2, err := time.Parse(time.RFC3339Nano, DutLastChangeTS2STR) + if err != nil { + t.Fatalf("failed to parse event timestamp: %v %v", err, DutLastChangeTS2) + } + + // Step 6. verify oper-status last change time has changed + t.Log("Compare if pre and post timestamps are the same for the last change before and after shut event") + if DutLastChangeTS1 == DutLastChangeTS2STR { + t.Fatalf("Before Trigger Last Change was %v after trigger Last Change was %v", DutLastChangeTS1, DutLastChangeTS2STR) + } else { + t.Logf("Before Trigger Last Change was %v after trigger Last Change was %v", DutLastChangeTS1, DutLastChangeTS2STR) + } + + // convert to time objects + otgStateChangeTs = otgStateChangeTs.UTC() + DutLastChangeTS2 = DutLastChangeTS2.UTC() + + return otgStateChangeTs, DutLastChangeTS2, expectedStatus.String(), DutLastChangeOper2.String() + +} + +// verifyPortsUp asserts that each port on the device is operating. +func verifyPortsStatus(t *testing.T, dut *ondatra.DUTDevice, portState string, waitTime time.Duration) { + t.Helper() + + t.Logf("Checking Oper Status on %s", aggID) + + // Determine the expected status based on the portState argument. + var want oc.E_Interface_OperStatus + if portState == "UP" { + want = oc.Interface_OperStatus_UP + gnmi.Await(t, dut, + gnmi.OC().Interface(aggID).OperStatus().State(), + time.Second*waitTime, + oc.Interface_OperStatus_UP) + } else { + want = oc.Interface_OperStatus_DOWN + gnmi.Await(t, dut, + gnmi.OC().Interface(aggID).OperStatus().State(), + time.Second*waitTime, + oc.Interface_OperStatus_DOWN) + } + + status := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).OperStatus().State()) + + // check the status and log the result. + if status != want { + t.Fatalf("Failed: %s Status: got %v, want %v", aggID, status, want) + } else { + t.Logf("Pass: %s Status: got %v, want %v", aggID, status, want) + } +} + +func TestHoldTimeConfig(t *testing.T) { + + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + dutPort1Intf = dut.Port(t, "port1") + t.Run("ConfigureDUT Interfaces", func(t *testing.T) { + // Configure the DUT + aggID = netutil.NextAggregateInterface(t, dut) + t.Log(dutPort1Intf) + configureDUT(t, dut, aggID) + + }) + + t.Run("Configure Hold Timers on DUT", func(t *testing.T) { + // Construct the hold-time config object + holdTimeConfig := &oc.Interface_HoldTime{ + Up: ygot.Uint32(upTimer), + Down: ygot.Uint32(downTimer), + } + + intfPath := gnmi.OC().Interface(dutPort1Intf.Name()) + gnmi.Update(t, dut, intfPath.HoldTime().Config(), holdTimeConfig) + + }) + + t.Run("ConfigureOTG", func(t *testing.T) { + t.Logf("Configure ATE") + configureOTG(t, ate, aggID) + + }) + + t.Run(fmt.Sprintf("Verify Interface State for %s", aggID), func(t *testing.T) { + // Verify Port Status + t.Logf("Verifying port status for %s", aggID) + verifyPortsStatus(t, dut, "UP", 45) + }) + +} + +func TestTC1ValidateTimersConfig(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + holdTimePath := gnmi.OC().Interface(dutPort1Intf.Name()).HoldTime().State() + + holdTimeState := gnmi.Get(t, dut, holdTimePath) + t.Log(holdTimeState) + if *holdTimeState.Up == upTimer && *holdTimeState.Down == downTimer { + t.Logf("Successfully configured times as up timer is %d and down timer"+ + " is %d", *holdTimeState.Up, *holdTimeState.Down) + } else { + t.Errorf("TC Failed: Configured up and down timers dont match what was configured "+ + "expected up %d got %d expected down %d got %d", upTimer, *holdTimeState.Up, + downTimer, *holdTimeState.Down) + } +} + +func TestTC2LongDown(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + var otgStateChangeTs, DutLastChangeTS2 time.Time + var expectedOper, actualOper string + + t.Run(fmt.Sprintf("Shut down OTG interface to cause remote fault on %s", aggID), func(t *testing.T) { + otgStateChangeTs, DutLastChangeTS2, expectedOper, actualOper = flapOTGInterface(t, ate, dut, "DOWN") + if expectedOper != actualOper { + t.Errorf("expectedOper and actualOper do not match: expected %s, got %s", expectedOper, actualOper) + } + }) + + duration := DutLastChangeTS2.Sub(otgStateChangeTs) + durationInMS := duration.Milliseconds() + + // Define the expected delay and tolerance + expectedDelayMS := 300 // Expected delay in milliseconds + minDuration := int64(expectedDelayMS - toleranceMS) + maxDuration := int64(expectedDelayMS + toleranceMS) + + // Check if the actual duration falls within the expected range + pass := durationInMS <= maxDuration + + t.Run(fmt.Sprintf("Calculate fault duration on %s", aggID), func(t *testing.T) { + t.Logf("Shutdown triggered at: %v", otgStateChangeTs) + t.Logf("Last change reported at: %v", DutLastChangeTS2) + t.Logf("Duration between shutdown triggered and last change reported: %v ms", durationInMS) + + if pass { + t.Logf("PASS: Duration is within the expected range; got %d ms", durationInMS) + } else { + t.Errorf("FAIL: Expected duration to be within %d ms to %d ms; got %d ms", minDuration, maxDuration, durationInMS) + } + }) + + t.Run("Bring back UP OTG Interface", func(t *testing.T) { + OTGInterfaceUP(t, ate) + t.Logf("Verifying port status for %s", aggID) + verifyPortsStatus(t, dut, "UP", 45) + }) + + t.Run("Verify test results", func(t *testing.T) { + displaySummaryTable(t, otgStateChangeTs.Format(time.RFC3339Nano), DutLastChangeTS2.Format(time.RFC3339Nano), + durationInMS, minDuration, maxDuration, expectedOper, actualOper, pass) + + }) + +} + +func TestTC3ShortUP(t *testing.T) { + + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + t.Run("Start sending Ethernet Remote Fault on OTG", func(t *testing.T) { + + // shutting down OTG interface to emulate the RF + OTGInterfaceDOWN(t, ate, dut) + oper1 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).OperStatus().State()) + change1 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).LastChange().State()) + t.Log(oper1) + t.Log(change1) + + // bring port back up for 4 seconds below the 5000 ms hold up timer + OTGInterfaceUP(t, ate) + // shut the OTG interface back to down state + OTGInterfaceDOWN(t, ate, dut) + oper2 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).OperStatus().State()) + change2 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).LastChange().State()) + + // ensure the LAG interface is still down + verifyPortsStatus(t, dut, "DOWN", 4) + t.Log(oper2) + + change1Time := time.Unix(0, int64(change1)).UTC() + change2Time := time.Unix(0, int64(change2)).UTC() + + // Compare the times and ensure there is no change in the last change + if change1Time.Before(change2Time) || change1Time.After(change2Time) { + t.Errorf("Time 1 %v and Time 2 dont match %v", change1Time, change2Time) + } else if change1Time.Equal(change2Time) { + t.Logf("Time 1 %v and Time 2 the the same which is expected %v", change1Time, change2Time) + } + + // bring OTG port back up + OTGInterfaceUP(t, ate) + // verify interface is up for next test case + verifyPortsStatus(t, dut, "UP", 45) + + }) + +} + +func TestTC4SLongUP(t *testing.T) { + + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + t.Run("Start sending Ethernet Remote Fault on OTG", func(t *testing.T) { + + // shutting down OTG interface to emulate the RF + OTGInterfaceDOWN(t, ate, dut) + time.Sleep(1 * time.Second) + change1 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).LastChange().State()) + t.Log(change1) + + // bring port back up for 4 seconds below the 5000 ms hold up timer + OTGInterfaceUP(t, ate) + // ensure the LAG interface is still down + verifyPortsStatus(t, dut, "UP", 30) + + // Collecting time stamp of interface up + change2 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).LastChange().State()) + + change1Time := time.Unix(0, int64(change1)).UTC() + change2Time := time.Unix(0, int64(change2)).UTC() + + // Calculate the difference in time + duration := change2Time.Sub(change1Time) + + // Convert the duration to milliseconds + durationInMS := duration.Milliseconds() + t.Logf("Duration interface %v ms", durationInMS) + + if durationInMS >= upTimer { + t.Logf("PASS: Expected interface up time delay of at least %v and got %v", upTimer, durationInMS) + } else { + t.Fatalf("FAIL: Expected interface up time delay of at least %v and got %v", upTimer, durationInMS) + } + + }) + +} + +func TestTC5ShortDOWN(t *testing.T) { + + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + var time1 time.Time + var change1 *oc.Interface + + // Construct the hold-time config object + holdTimeConfig := &oc.Interface_HoldTime{ + Up: ygot.Uint32(upTimer), + Down: ygot.Uint32(2000), + } + + t.Run("Update hold timer configs down", func(t *testing.T) { + intfPath := gnmi.OC().Interface(dutPort1Intf.Name()) + gnmi.Update(t, dut, intfPath.HoldTime().Config(), holdTimeConfig) + + }) + + t.Run("Flap OTG Interfaces", func(t *testing.T) { + + t.Log("Verify Interface State before TC Start") + verifyPortsStatus(t, dut, "UP", 10) + // shutting down OTG interface to emulate the RF + t.Log("Shutdown OTG Interface") + change1 = gnmi.Get(t, dut, gnmi.OC().Interface(aggID).State()) + t.Logf("change1 last change is %v and status is %v", change1.LastChange, change1.AdminStatus) + + time1 = OTGInterfaceDOWN(t, ate, dut) + time.Sleep(200 * time.Millisecond) + t.Log("Bring OTG Interface Back UP") + OTGInterfaceUP(t, ate) + + }) + + t.Run("Verify Short Down Results", func(t *testing.T) { + + // Start building the log message + logMessage := "Interface Status Timeline\n" + + "----------------------------------------------------\n" + + "Event | Time | Oper Status\n" + + "----------------------------------------------------\n" + + "Last-change time 1 | %v | %v\n" + + "Trigger Start Time | %v | -\n" + + "Last-change Re-check | %v | %v\n" + + change2 := gnmi.Get(t, dut, gnmi.OC().Interface(aggID).State()) + + if *change2.LastChange == *change1.LastChange && change2.OperStatus == change1.OperStatus { + time2 := gnmi.Get(t, dut, gnmi.OC().System().CurrentDatetime().State()) + + // Dereference the value and convert to int64 before passing to time.Unix function + change2LastChangeTime := time.Unix(0, int64(*change2.LastChange)).UTC().Format(time.RFC3339Nano) + change1LastChangeTime := time.Unix(0, int64(*change1.LastChange)).UTC().Format(time.RFC3339Nano) + t1 := time1.UTC().Format(time.RFC3339Nano) + t2, err := time.Parse(time.RFC3339Nano, time2) + if err != nil { + t.Errorf("Failed to parse time string: %v", err) + return + } + + timeDiff := t2.Sub(time1).Milliseconds() + + logMessage += fmt.Sprintf("End Time | %v | -\n"+ + "-----------------------------------------------------\n"+ + "Total Elapsed Time: %vms\n", t2, timeDiff) + t.Logf(logMessage, change1LastChangeTime, change1.OperStatus, t1, change2LastChangeTime, change2.OperStatus) + + } else { + // Dereference the value and convert to int64 before passing to time.Unix function + change2LastChangeTime := time.Unix(0, int64(*change2.LastChange)).UTC().Format(time.RFC3339Nano) + change1LastChangeTime := time.Unix(0, int64(*change1.LastChange)).UTC().Format(time.RFC3339Nano) + t1 := time1.UTC().Format(time.RFC3339Nano) + + // Log failure message and the partially built log message without end time + t.Log("Failed due to an unexpected match such as last-change time or interface oper-status") + t.Fatalf(logMessage, change1LastChangeTime, change1.OperStatus, t1, change2LastChangeTime, change2.OperStatus) + } + }) + + t.Run("Verify port status UP", func(t *testing.T) { + t.Log("re-verify that the interface state is still up") + verifyPortsStatus(t, dut, "UP", 10) + + }) +} diff --git a/feature/interface/holdtime/otg_tests/holdtime_test/metadata.textproto b/feature/interface/holdtime/otg_tests/holdtime_test/metadata.textproto index 420c75186b1..6d2e250ac73 100644 --- a/feature/interface/holdtime/otg_tests/holdtime_test/metadata.textproto +++ b/feature/interface/holdtime/otg_tests/holdtime_test/metadata.textproto @@ -1,6 +1,15 @@ # proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata +uuid: "4ed6ff3f-b27e-4f46-93b2-8bcbc521d883" plan_id: "RT-5.5" -description: "Interface hold-times" +description: "Interface hold-time" testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + ipv4_missing_enabled: true + } +} From 89c3de7a2931c3ce65eebbd51655b36df2f2a912 Mon Sep 17 00:00:00 2001 From: arvbaska1 <123760606+arvbaska1@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:12:16 -0400 Subject: [PATCH 54/97] gNOI-2.1 packet link qualification deviations (#2617) * gNOI-2.1 PLQ deviations for Cisco --------- Co-authored-by: Darren Loher --- .../metadata.textproto | 11 ++ .../packet_link_qualification_test.go | 40 ++++-- internal/deviations/deviations.go | 15 +++ internal/vrfpolicy/vrfpolicy.go | 2 +- proto/metadata.proto | 8 +- proto/metadata_go_proto/metadata.pb.go | 125 ++++++++++++------ 6 files changed, 148 insertions(+), 53 deletions(-) diff --git a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/metadata.textproto b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/metadata.textproto index e0bbb248c81..550fef5802e 100644 --- a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/metadata.textproto +++ b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/metadata.textproto @@ -33,3 +33,14 @@ platform_exceptions: { explicit_port_speed: true } } +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + skip_plq_interface_oper_status_check: true + plq_reflector_stats_unsupported: true + plq_generator_capabilities_max_mtu: 512 + plq_generator_capabilities_max_pps: 40000000 + } +} diff --git a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go index e3c600508a1..3da68cc1db0 100644 --- a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go +++ b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go @@ -44,6 +44,11 @@ func TestMain(m *testing.M) { // https://github.com/fullstorydev/grpcurl // +var ( + minRequiredGeneratorMTU = uint64(8184) + minRequiredGeneratorPPS = uint64(1e8) +) + func TestCapabilitiesResponse(t *testing.T) { dut1 := ondatra.DUT(t, "dut1") dut2 := ondatra.DUT(t, "dut2") @@ -60,6 +65,14 @@ func TestCapabilitiesResponse(t *testing.T) { t.Fatalf("Failed to handle gnoi LinkQualification().Capabilities(): %v", err) } + if deviations.PLQGeneratorCapabilitiesMaxMTU(dut1) != 0 { + minRequiredGeneratorMTU = uint64(deviations.PLQGeneratorCapabilitiesMaxMTU(dut1)) + } + + if deviations.PLQGeneratorCapabilitiesMaxPPS(dut1) != 0 { + minRequiredGeneratorPPS = deviations.PLQGeneratorCapabilitiesMaxPPS(dut1) + } + cases := []struct { desc string got uint64 @@ -91,7 +104,7 @@ func TestCapabilitiesResponse(t *testing.T) { }, { desc: "Generator MaxMtu", got: uint64(plqResp.GetGenerator().GetPacketGenerator().GetMaxMtu()), - min: uint64(8184), + min: minRequiredGeneratorMTU, }, { desc: "Generator MaxBps", got: uint64(plqResp.GetGenerator().GetPacketGenerator().GetMaxBps()), @@ -99,7 +112,7 @@ func TestCapabilitiesResponse(t *testing.T) { }, { desc: "Generator MaxPps", got: uint64(plqResp.GetGenerator().GetPacketGenerator().GetMaxPps()), - min: uint64(1e8), + min: minRequiredGeneratorPPS, }} for _, tc := range cases { @@ -231,6 +244,10 @@ func TestLinkQualification(t *testing.T) { } plqID := dut1.Name() + ":" + dp1.Name() + "<->" + dut2.Name() + ":" + dp2.Name() + + if deviations.PLQGeneratorCapabilitiesMaxMTU(dut1) != 0 { + minRequiredGeneratorMTU = uint64(deviations.PLQGeneratorCapabilitiesMaxMTU(dut1)) + } type LinkQualificationDuration struct { // time needed to complete preparation generatorsetupDuration time.Duration @@ -265,7 +282,7 @@ func TestLinkQualification(t *testing.T) { EndpointType: &plqpb.QualificationConfiguration_PacketGenerator{ PacketGenerator: &plqpb.PacketGeneratorConfiguration{ PacketRate: uint64(138888), - PacketSize: uint32(8184), + PacketSize: uint32(minRequiredGeneratorMTU), }, }, Timing: &plqpb.QualificationConfiguration_Rpc{ @@ -422,11 +439,16 @@ func TestLinkQualification(t *testing.T) { // The packet counters between Generator and Reflector mismatch tolerance level in percentage var tolerance float64 = 0.0001 - if ((math.Abs(float64(generatorPktsSent)-float64(reflectorPktsRxed)))/(float64(generatorPktsSent)+float64(reflectorPktsRxed)+tolerance))*200.00 > tolerance { - t.Errorf("The difference between packets received count at Reflector and packets sent count at Generator is greater than %0.4f percent: generatorPktsSent %v, reflectorPktsRxed %v", tolerance, generatorPktsSent, reflectorPktsRxed) - } - if ((math.Abs(float64(reflectorPktsSent)-float64(generatorPktsRxed)))/(float64(reflectorPktsSent)+float64(generatorPktsRxed)+tolerance))*200.00 > tolerance { - t.Errorf("The difference between packets received count at Generator and packets sent count at Reflector is greater than %0.4f percent: reflectorPktsSent %v, generatorPktsRxed %v", tolerance, reflectorPktsSent, generatorPktsRxed) + if deviations.PLQReflectorStatsUnsupported(dut1) { + if (math.Abs(float64(generatorPktsSent)-float64(generatorPktsRxed))/float64(generatorPktsSent))*100.00 > tolerance { + t.Errorf("The difference between packets sent count and packets received count at Generator is greater than %0.4f percent: generatorPktsSent %v, generatorPktsRxed %v", tolerance, generatorPktsSent, generatorPktsRxed) + } + } else { + if ((math.Abs(float64(generatorPktsSent)-float64(reflectorPktsRxed)))/(float64(generatorPktsSent)+float64(reflectorPktsRxed)+tolerance))*200.00 > tolerance { + t.Errorf("The difference between packets received count at Reflector and packets sent count at Generator is greater than %0.4f percent: generatorPktsSent %v, reflectorPktsRxed %v", tolerance, generatorPktsSent, reflectorPktsRxed) + } + if ((math.Abs(float64(reflectorPktsSent)-float64(generatorPktsRxed)))/(float64(reflectorPktsSent)+float64(generatorPktsRxed)+tolerance))*200.00 > tolerance { + t.Errorf("The difference between packets received count at Generator and packets sent count at Reflector is greater than %0.4f percent: reflectorPktsSent %v, generatorPktsRxed %v", tolerance, reflectorPktsSent, generatorPktsRxed) + } } - } diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 64ac4aa7da5..6c2bedde4fd 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -881,3 +881,18 @@ func MissingStaticRouteDropNextHopTelemetry(dut *ondatra.DUTDevice) bool { func MissingZROpticalChannelTunableParametersTelemetry(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetMissingZrOpticalChannelTunableParametersTelemetry() } + +// PLQReflectorStatsUnsupported returns true for devices that does not support packet link qualification(PLQ) reflector packet sent/received stats. +func PLQReflectorStatsUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetPlqReflectorStatsUnsupported() +} + +// PLQGeneratorCapabilitiesMaxMTU returns supported max_mtu for devices that does not support packet link qualification(PLQ) Generator max_mtu to be atleast >= 8184. +func PLQGeneratorCapabilitiesMaxMTU(dut *ondatra.DUTDevice) uint32 { + return lookupDUTDeviations(dut).GetPlqGeneratorCapabilitiesMaxMtu() +} + +// PLQGeneratorCapabilitiesMaxPPS returns supported max_pps for devices that does not support packet link qualification(PLQ) Generator max_pps to be atleast >= 100000000. +func PLQGeneratorCapabilitiesMaxPPS(dut *ondatra.DUTDevice) uint64 { + return lookupDUTDeviations(dut).GetPlqGeneratorCapabilitiesMaxPps() +} diff --git a/internal/vrfpolicy/vrfpolicy.go b/internal/vrfpolicy/vrfpolicy.go index 5d914ef0dcb..33f65574c24 100644 --- a/internal/vrfpolicy/vrfpolicy.go +++ b/internal/vrfpolicy/vrfpolicy.go @@ -220,7 +220,7 @@ func ConfigureVRFSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice) { gnmi.Replace(t, dut, dutForwardingPath.Interface(interfaceID).Config(), interface1) } -// deletePolicyForwarding deletes policy configured under given interface +// DeletePolicyForwarding deletes policy configured under given interface. func DeletePolicyForwarding(t *testing.T, dut *ondatra.DUTDevice, portID string) { t.Helper() p1 := dut.Port(t, portID) diff --git a/proto/metadata.proto b/proto/metadata.proto index 2bdeb5c6969..51bf2118ac1 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -465,7 +465,13 @@ message Metadata { // min/max/avg. // Arista: https://partnerissuetracker.corp.google.com/issues/319314781 bool missing_zr_optical_channel_tunable_parameters_telemetry = 163; - + // Device that does not support packet link qualification reflector packet sent/received stats. + bool plq_reflector_stats_unsupported = 164; + // Device that does not support PLQ Generator max_mtu to be atleast >= 8184. + uint32 plq_generator_capabilities_max_mtu = 165; + // Device that does not support PLQ Generator max_pps to be atleast >= 100000000. + uint64 plq_generator_capabilities_max_pps = 166; + // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 4e6f643f6b0..81689727efc 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 -// protoc v3.21.12 +// protoc-gen-go v1.31.0 +// protoc v4.23.4 // source: metadata.proto package metadata_go_proto @@ -674,7 +674,7 @@ type Metadata_Deviations struct { // Skip setting allow-multiple-as while configuring eBGP // Arista: partnerissuetracker.corp.google.com/issues/317422300 SkipSettingAllowMultipleAs bool `protobuf:"varint,140,opt,name=skip_setting_allow_multiple_as,json=skipSettingAllowMultipleAs,proto3" json:"skip_setting_allow_multiple_as,omitempty"` - //Skip tests with decap encap vrf as PBF action + // Skip tests with decap encap vrf as PBF action // Nokia: partnerissuetracker.corp.google.com/issues/323251581 SkipPbfWithDecapEncapVrf bool `protobuf:"varint,141,opt,name=skip_pbf_with_decap_encap_vrf,json=skipPbfWithDecapEncapVrf,proto3" json:"skip_pbf_with_decap_encap_vrf,omitempty"` // Devices which does not support copying TTL. @@ -736,6 +736,12 @@ type Metadata_Deviations struct { // min/max/avg. // Arista: https://partnerissuetracker.corp.google.com/issues/319314781 MissingZrOpticalChannelTunableParametersTelemetry bool `protobuf:"varint,163,opt,name=missing_zr_optical_channel_tunable_parameters_telemetry,json=missingZrOpticalChannelTunableParametersTelemetry,proto3" json:"missing_zr_optical_channel_tunable_parameters_telemetry,omitempty"` + // Device that does not support packet link qualification reflector packet sent/received stats. + PlqReflectorStatsUnsupported bool `protobuf:"varint,164,opt,name=plq_reflector_stats_unsupported,json=plqReflectorStatsUnsupported,proto3" json:"plq_reflector_stats_unsupported,omitempty"` + // Device that does not support PLQ Generator max_mtu to be atleast >= 8184. + PlqGeneratorCapabilitiesMaxMtu uint32 `protobuf:"varint,165,opt,name=plq_generator_capabilities_max_mtu,json=plqGeneratorCapabilitiesMaxMtu,proto3" json:"plq_generator_capabilities_max_mtu,omitempty"` + // Device that does not support PLQ Generator max_pps to be atleast >= 100000000. + PlqGeneratorCapabilitiesMaxPps uint64 `protobuf:"varint,166,opt,name=plq_generator_capabilities_max_pps,json=plqGeneratorCapabilitiesMaxPps,proto3" json:"plq_generator_capabilities_max_pps,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1799,6 +1805,27 @@ func (x *Metadata_Deviations) GetMissingZrOpticalChannelTunableParametersTelemet return false } +func (x *Metadata_Deviations) GetPlqReflectorStatsUnsupported() bool { + if x != nil { + return x.PlqReflectorStatsUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetPlqGeneratorCapabilitiesMaxMtu() uint32 { + if x != nil { + return x.PlqGeneratorCapabilitiesMaxMtu + } + return 0 +} + +func (x *Metadata_Deviations) GetPlqGeneratorCapabilitiesMaxPps() uint64 { + if x != nil { + return x.PlqGeneratorCapabilitiesMaxPps + } + return 0 +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1862,7 +1889,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfb, 0x5b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdd, 0x5d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1893,7 +1920,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xfc, 0x53, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xde, 0x55, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2562,43 +2589,57 @@ var file_metadata_proto_rawDesc = []byte{ 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5a, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, - 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, - 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, - 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, - 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, - 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, - 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, - 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, - 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, - 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, - 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, - 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, - 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, - 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, - 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, - 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, - 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, - 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, - 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, - 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, - 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x46, 0x0a, 0x1f, 0x70, 0x6c, 0x71, 0x5f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x18, 0xa4, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x70, 0x6c, 0x71, 0x52, + 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0xa5, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, + 0x61, 0x78, 0x4d, 0x74, 0x75, 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x70, 0x73, 0x18, 0xa6, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x50, + 0x70, 0x73, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, + 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, + 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, + 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, + 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, + 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, + 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, + 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, + 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, + 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, + 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, + 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, + 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, + 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, + 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, + 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 13616be11a107d51f55afddf919cc44be4f0c04c Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Thu, 28 Mar 2024 15:24:07 +0530 Subject: [PATCH 55/97] change default vrf to mgmt vrf (#2860) --- .../otg_tests/management_ha_test/management_ha_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/feature/system/management/otg_tests/management_ha_test/management_ha_test.go b/feature/system/management/otg_tests/management_ha_test/management_ha_test.go index c5087da389b..d49da2d55ea 100644 --- a/feature/system/management/otg_tests/management_ha_test/management_ha_test.go +++ b/feature/system/management/otg_tests/management_ha_test/management_ha_test.go @@ -348,10 +348,9 @@ func configureImportExportBGPPolicy(t *testing.T, bs *cfgplugins.BGPSession) { gnmi.BatchUpdate(batchSet, gnmi.OC().RoutingPolicy().Config(), rp) - dni := deviations.DefaultNetworkInstance(bs.DUT) for _, neighbor := range []string{bs.ATEPorts[0].IPv6, bs.ATEPorts[1].IPv6} { - pathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(neighbor).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() - policyV6 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp().GetOrCreateNeighbor(neighbor).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + pathV6 := gnmi.OC().NetworkInstance(mgmtVRF).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(neighbor).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policyV6 := root.GetOrCreateNetworkInstance(mgmtVRF).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp().GetOrCreateNeighbor(neighbor).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() policyV6.SetImportPolicy([]string{"importRoutePolicy"}) policyV6.SetExportPolicy([]string{"exportRoutePolicy"}) gnmi.BatchReplace(batchSet, pathV6.Config(), policyV6) From c3b74d1bb98efe98a35fb32f5e54e3a408041ab8 Mon Sep 17 00:00:00 2001 From: sunilprgit Date: Thu, 28 Mar 2024 19:52:06 +0530 Subject: [PATCH 56/97] Add automation for testcase RT-7.5 (#2859) --- .../otg_tests/link_bandwidth_test/README.md | 0 .../link_bandwidth_test.go | 829 ++++++++++++++++++ .../link_bandwidth_test/metadata.textproto | 25 + internal/deviations/deviations.go | 5 + proto/metadata.proto | 3 +- proto/metadata_go_proto/metadata.pb.go | 97 +- testregistry.textproto | 2 +- 7 files changed, 918 insertions(+), 43 deletions(-) rename feature/{bgp/policybase => experimental/bgp}/otg_tests/link_bandwidth_test/README.md (100%) create mode 100644 feature/experimental/bgp/otg_tests/link_bandwidth_test/link_bandwidth_test.go create mode 100644 feature/experimental/bgp/otg_tests/link_bandwidth_test/metadata.textproto diff --git a/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md b/feature/experimental/bgp/otg_tests/link_bandwidth_test/README.md similarity index 100% rename from feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md rename to feature/experimental/bgp/otg_tests/link_bandwidth_test/README.md diff --git a/feature/experimental/bgp/otg_tests/link_bandwidth_test/link_bandwidth_test.go b/feature/experimental/bgp/otg_tests/link_bandwidth_test/link_bandwidth_test.go new file mode 100644 index 00000000000..a45aaefada9 --- /dev/null +++ b/feature/experimental/bgp/otg_tests/link_bandwidth_test/link_bandwidth_test.go @@ -0,0 +1,829 @@ +// 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 link_bandwidth_test + +import ( + "testing" + "time" + + "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" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +const ( + ipv4PrefixLen = 30 + ipv6PrefixLen = 126 + v41Route = "203.0.113.0" + v41TrafficStart = "203.0.113.1" + v42Route = "203.0.114.0" + v42TrafficStart = "203.0.114.1" + v43Route = "203.0.115.0" + v43TrafficStart = "203.0.115.1" + v4RoutePrefix = uint32(24) + v61Route = "2001:db8:128:128::0" + v61TrafficStart = "2001:db8:128:128::1" + v62Route = "2001:db8:128:129::0" + v62TrafficStart = "2001:db8:128:129::1" + v63Route = "2001:db8:128:130::0" + v63TrafficStart = "2001:db8:128:130::1" + v6RoutePrefix = uint32(64) + dutAS = uint32(65656) + ateAS = uint32(65657) + bgpName = "BGP" + maskLenExact = "exact" + localPref = 200 + v4Flow = "flow-v4" + v6Flow = "flow-v6" +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "dutPort1", + IPv4: "192.0.2.1", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:1", + IPv6Len: ipv6PrefixLen, + } + + atePort1 = attrs.Attributes{ + Name: "atePort1", + MAC: "02:00:01:01:01:01", + IPv4: "192.0.2.2", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:2", + IPv6Len: ipv6PrefixLen, + } + + dutPort2 = attrs.Attributes{ + Desc: "dutPort2", + IPv4: "192.0.2.5", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:5", + IPv6Len: ipv6PrefixLen, + } + + atePort2 = attrs.Attributes{ + Name: "atePort2", + MAC: "02:00:01:01:01:02", + IPv4: "192.0.2.6", + IPv4Len: ipv4PrefixLen, + IPv6: "2001:db8::192:0:2:6", + IPv6Len: ipv6PrefixLen, + } + + advertisedIPv41 = ipAddr{address: v41Route, prefix: v4RoutePrefix} + advertisedIPv42 = ipAddr{address: v42Route, prefix: v4RoutePrefix} + advertisedIPv43 = ipAddr{address: v43Route, prefix: v4RoutePrefix} + advertisedIPv61 = ipAddr{address: v61Route, prefix: v6RoutePrefix} + advertisedIPv62 = ipAddr{address: v62Route, prefix: v6RoutePrefix} + advertisedIPv63 = ipAddr{address: v63Route, prefix: v6RoutePrefix} + extCommunitySet = map[string]string{ + "linkbw_0": "link-bandwidth:100:0", + "linkbw_1M": "link-bandwidth:100:1M", + "inkbw_2G": "link-bandwidth:100:2G", + "regex_match_comm100": "^100:.*$", + "linkbw_any": "^link-bandwidth:.*:.$", + "linkbw_any_0": "^link-bandwidth:.*:0$", + } +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +type ipAddr struct { + address string + prefix uint32 +} + +type testData struct { + dut *ondatra.DUTDevice + ate *ondatra.ATEDevice + top gosnappi.Config + otgP1 gosnappi.Device + otgP2 gosnappi.Device +} + +type extCommunity struct { + prefixSet1Comm string + prefixSet2Comm string + prefixSet3Comm string +} + +type flowConfig struct { + src attrs.Attributes + dstNw string + dstIP string +} + +func TestBGPLinkBandwidth(t *testing.T) { + dut := ondatra.DUT(t, "dut") + configureDUT(t, dut) + ate := ondatra.ATE(t, "ate") + top := gosnappi.NewConfig() + devs := configureOTG(t, ate, top) + td := testData{ + dut: dut, + ate: ate, + top: top, + otgP1: devs[0], + otgP2: devs[1], + } + type testCase struct { + name string + policyName string + applyPolicy func(t *testing.T, dut *ondatra.DUTDevice, policyName string) + validate func(t *testing.T, dut *ondatra.DUTDevice, policyName string) + routeCommunity extCommunity + localPerf bool + validateRouteCommunityV4 func(t *testing.T, td testData, ec extCommunity, localPerf bool) + validateRouteCommunityV6 func(t *testing.T, td testData, ec extCommunity, localPerf bool) + } + baseSetupConfigAndVerification(t, td) + configureExtCommunityRoutingPolicy(t, dut) + testCases := []testCase{ + { + name: "Policy set link bandwidth 0", + policyName: "set_linkbw_0", + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "link-bandwidth:100:0", prefixSet2Comm: "link-bandwidth:100:0", prefixSet3Comm: "link-bandwidth:100:0"}, + localPerf: false, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + { + name: "Policy set not_match_100_set_linkbw_1M", + policyName: "not_match_100_set_linkbw_1M", + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "link-bandwidth:100:0"}, + localPerf: false, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + { + name: "Policy set match_100_set_linkbw_2G", + policyName: "match_100_set_linkbw_2G", + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "link-bandwidth:100:2000000000", prefixSet3Comm: "link-bandwidth:100:0"}, + localPerf: false, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + { + name: "Policy set del_linkbw", + policyName: "del_linkbw", + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "none"}, + localPerf: false, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + { + name: "Policy set rm_any_zero_bw_set_LocPref_5", + policyName: "match_linkbw_0_remove_and_set_localpref_5", + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "none"}, + localPerf: true, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Logf("Description: %s", tc.name) + tc.applyPolicy(t, dut, tc.policyName) + tc.validate(t, dut, tc.policyName) + tc.validateRouteCommunityV4(t, td, tc.routeCommunity, tc.localPerf) + tc.validateRouteCommunityV6(t, td, tc.routeCommunity, tc.localPerf) + }) + } +} + +func applyPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { + // Apply ipv4 policy to bgp neighbour. + root := &oc.Root{} + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName). + Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + + policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName). + GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() + policy.SetImportPolicy([]string{policyName}) + gnmi.Replace(t, dut, path.Config(), policy) + + // Apply ipv6 policy to bgp neighbour. + path = gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policy = root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policy.SetImportPolicy([]string{policyName}) + gnmi.Replace(t, dut, path.Config(), policy) +} + +func validatPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) + importPolicies := policy.GetImportPolicy() + if len(importPolicies) != 1 { + t.Fatalf("ImportPolicy Ipv4 got= %v, want %v", importPolicies, []string{policyName}) + } +} + +func validateRouteCommunityV4(t *testing.T, td testData, ec extCommunity, localPerf bool) { + prefixes := map[string]string{ + v41Route: ec.prefixSet1Comm, + v42Route: ec.prefixSet2Comm, + v43Route: ec.prefixSet3Comm, + } + for prefix, community := range prefixes { + validateRouteCommunityV4Prefix(t, td, community, prefix, localPerf) + } +} + +func validateRouteCommunityV4Prefix(t *testing.T, td testData, community, v4Prefix string, localPerf bool) { + _, ok := gnmi.WatchAll(t, + td.ate.OTG(), + gnmi.OTG().BgpPeer(td.otgP2.Name()+".BGP4.peer").UnicastIpv4PrefixAny().State(), + time.Minute, + func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { + _, present := v.Val() + return present + }).Await(t) + if ok { + bgpPrefixes := gnmi.GetAll(t, td.ate.OTG(), gnmi.OTG().BgpPeer(td.otgP2.Name()+".BGP4.peer").UnicastIpv4PrefixAny().State()) + t.Logf("bgp prefix:%v", bgpPrefixes) + for _, bgpPrefix := range bgpPrefixes { + if bgpPrefix.GetAddress() == v4Prefix { + t.Logf("Prefix recevied on OTG is correct, got Address %s, want prefix %v", bgpPrefix.GetAddress(), v4Prefix) + switch community { + case "none": + if len(bgpPrefix.Community) != 0 { + t.Fatalf("community is not empty it should be none") + } + case "100:100": + for _, gotCommunity := range bgpPrefix.Community { + t.Logf("community AS:%d val: %d", gotCommunity.GetCustomAsNumber(), gotCommunity.GetCustomAsValue()) + if gotCommunity.GetCustomAsNumber() != 100 && gotCommunity.GetCustomAsValue() != 100 { + t.Fatalf("community is not 100:100 got AS number:%d AS value:%d", gotCommunity.GetCustomAsNumber(), gotCommunity.GetCustomAsValue()) + } + } + default: + // TODO Verification as OTG not supported for Extended community/ + t.Logf("TODO: https://github.com/open-traffic-generator/snappi/issues/220 Verification as OTG not supported for Extended community") + if deviations.BgpExtendedCommunityIndexUnsupported(td.dut) { + verifyExtCommunityIndexV4(t, td, v4Prefix) + } + } + } + } + } +} + +func validateRouteCommunityV6(t *testing.T, td testData, ec extCommunity, localPerf bool) { + prefixes := map[string]string{ + v61Route: ec.prefixSet1Comm, + v62Route: ec.prefixSet2Comm, + v63Route: ec.prefixSet3Comm, + } + for prefix, community := range prefixes { + validateRouteCommunityV6Prefix(t, td, community, prefix, localPerf) + } +} + +func validateRouteCommunityV6Prefix(t *testing.T, td testData, community, v6Prefix string, localPerf bool) { + + // This function to verify received route communities on ATE ports. + _, ok := gnmi.WatchAll(t, + td.ate.OTG(), + gnmi.OTG().BgpPeer(td.otgP2.Name()+".BGP6.peer").UnicastIpv6PrefixAny().State(), + time.Minute, + func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv6Prefix]) bool { + _, present := v.Val() + return present + }).Await(t) + if ok { + bgpPrefixes := gnmi.GetAll(t, td.ate.OTG(), gnmi.OTG().BgpPeer(td.otgP2.Name()+".BGP6.peer").UnicastIpv6PrefixAny().State()) + for _, bgpPrefix := range bgpPrefixes { + if bgpPrefix.GetAddress() == v6Prefix { + t.Logf("Prefix recevied on OTG is correct, got prefix:%v , want prefix %v", bgpPrefix, v6Prefix) + switch community { + case "none": + if len(bgpPrefix.Community) != 0 { + t.Fatalf("community is not empty it should be none") + } + case "100:100": + for _, gotCommunity := range bgpPrefix.Community { + t.Logf("community AS:%d val: %d", gotCommunity.GetCustomAsNumber(), gotCommunity.GetCustomAsValue()) + if gotCommunity.GetCustomAsNumber() != 100 && gotCommunity.GetCustomAsValue() != 100 { + t.Fatalf("community is not 100:100 got AS number:%d AS value:%d", gotCommunity.GetCustomAsNumber(), gotCommunity.GetCustomAsValue()) + } + } + default: + + // TODO Verification as OTG not supported for Extended community. + t.Logf("TODO: https://github.com/open-traffic-generator/snappi/issues/220 Verification as OTG not supported for Extended community") + if deviations.BgpExtendedCommunityIndexUnsupported(td.dut) { + verifyExtCommunityIndexV6(t, td, v6Prefix) + } + } + } + } + } +} + +func configureImportRoutingPolicyAllowAll(t *testing.T, dut *ondatra.DUTDevice) { + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + pdef1 := rp.GetOrCreatePolicyDefinition("allow-all") + stmt1, err := pdef1.AppendNewStatement("allow-all") + if err != nil { + t.Fatalf("AppendNewStatement failed: %v", err) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + // Apply ipv4 policy to bgp neighbour. + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4). + AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + + policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName). + GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() + policy.SetImportPolicy([]string{"allow-all"}) + gnmi.Replace(t, dut, path.Config(), policy) + + // Apply ipv6 policy to bgp neighbour. + path = gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp(). + Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + + policy = root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName). + GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policy.SetImportPolicy([]string{"allow-all"}) + gnmi.Replace(t, dut, path.Config(), policy) +} + +func validateImportRoutingPolicyAllowAll(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + dni := deviations.DefaultNetworkInstance(dut) + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp(). + Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + + policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) + importPolicies := policy.GetImportPolicy() + if len(importPolicies) != 1 { + t.Fatalf("ImportPolicy Ipv4 = %v, want %v", importPolicies, []string{"allow-all"}) + } + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv4Unicast_LocRib](t, dut, bgpRIBPath. + AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast().LocRib().State()) + + found := 0 + expected := map[string]bool{ + advertisedIPv41.address: true, + advertisedIPv42.address: true, + advertisedIPv43.address: true, + } + for route, prefix := range locRib.Route { + if expected[prefix.GetPrefix()] { + found++ + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", route.Prefix, route.Origin, route.PathId, prefix.GetPrefix()) + } + } + if found != len(expected) { + t.Errorf("Not all V4 routes found. expected:%d got:%d", len(expected), found) + } + + // Verify ipv6 policy. + pathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policyV6 := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, pathV6.State()) + importPolicies = policyV6.GetImportPolicy() + if len(importPolicies) != 1 { + t.Errorf("ImportPolicy Ipv6 got= %v, want= %v", importPolicies, []string{"allow-all"}) + } + bgpRIBPathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRibv6 := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv6Unicast_LocRib](t, dut, bgpRIBPathV6.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast().LocRib().State()) + found = 0 + expectedV6 := map[string]bool{ + advertisedIPv61.address: true, + advertisedIPv62.address: true, + advertisedIPv63.address: true, + } + for route, prefix := range locRibv6.Route { + if expectedV6[prefix.GetPrefix()] { + found++ + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", route.Prefix, route.Origin, route.PathId, prefix.GetPrefix()) + } + } + if found != len(expectedV6) { + t.Errorf("Not all v6 Routes found expected:%d got:%d", len(expectedV6), found) + } +} + +func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { + root := &oc.Root{} + for name, community := range extCommunitySet { + rp := root.GetOrCreateRoutingPolicy() + pdef := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets() + stmt, err := pdef.NewExtCommunitySet(name) + if err != nil { + t.Fatalf("NewExtCommunitySet failed: %v", err) + } + stmt.SetExtCommunityMember([]string{community}) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + } + + // Configure routing policy link bandwidth zero. + rpSetLinkBwZero := root.GetOrCreateRoutingPolicy() + pdef1 := rpSetLinkBwZero.GetOrCreatePolicyDefinition("set_linkbw_0") + pdef1Stmt1, err := pdef1.AppendNewStatement("zero_linkbw") + if err != nil { + t.Fatalf("AppendNewStatement zero_linkbw failed: %v", err) + } + ref := pdef1Stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() + ref.GetOrCreateReference().SetExtCommunitySetRef("linkbw_0") + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + ref.SetMethod(oc.SetCommunity_Method_REFERENCE) + pdef1Stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + pdef1Stmt2, err := pdef1.AppendNewStatement("accept_all_routes") + if err != nil { + t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) + } + pdef1Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpSetLinkBwZero) + + // Configure routing Policy not_match_100_set_linkbw_1M. + rpNotMatch := root.GetOrCreateRoutingPolicy() + pdef2 := rpNotMatch.GetOrCreatePolicyDefinition("not_match_100_set_linkbw_1M") + pdef2Stmt1, err := pdef2.AppendNewStatement("1-megabit-match") + if err != nil { + t.Fatalf("AppendNewStatement 1-megabit-match failed: %v", err) + } + ref = pdef2Stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() + ref.GetOrCreateReference().SetExtCommunitySetRef("linkbw_1M") + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + ref1 := pdef2Stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetMatchExtCommunitySet() + ref1.SetExtCommunitySet("regex_match_comm100") + ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_INVERT) + pdef2Stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + pdef2Stmt2, err := pdef2.AppendNewStatement("accept_all_routes") + if err != nil { + t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) + } + pdef2Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpNotMatch) + + // Configure routing policy match_100_set_linkbw_2G. + rpMatch := root.GetOrCreateRoutingPolicy() + pdef3 := rpMatch.GetOrCreatePolicyDefinition("match_100_set_linkbw_2G") + pdef3Stmt1, err := pdef3.AppendNewStatement("2-gigabit-match") + if err != nil { + t.Fatalf("AppendNewStatement match_100_set_linkbw_2G failed: %v", err) + } + ref = pdef3Stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() + ref.GetOrCreateReference().SetExtCommunitySetRef("linkbw_2G") + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + ref1 = pdef3Stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetMatchExtCommunitySet() + ref1.SetExtCommunitySet("regex_match_comm100") + ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_ANY) + pdef3Stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + pdef3Stmt2, err := pdef3.AppendNewStatement("accept_all_routes") + if err != nil { + t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) + } + pdef3Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpMatch) + + // Configure routing policy del_linkbw. + rpDelLinkbw := root.GetOrCreateRoutingPolicy() + pdef4 := rpDelLinkbw.GetOrCreatePolicyDefinition("del_linkbw") + pdef4Stmt1, err := pdef4.AppendNewStatement("del_linkbw") + if err != nil { + t.Fatalf("AppendNewStatement del_linkbw failed: %v", err) + } + ref = pdef4Stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() + ref.GetOrCreateReference().SetExtCommunitySetRef("linkbw_any") + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_REMOVE) + ref.SetMethod(oc.SetCommunity_Method_REFERENCE) + pdef4Stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + pdef4Stmt2, err := pdef4.AppendNewStatement("accept_all_routes") + if err != nil { + t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) + } + pdef4Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpDelLinkbw) + + // Configure routing policy match_linkbw_0_remove_and_set_localpref_5. + rpMatchLB0Perf5 := root.GetOrCreateRoutingPolicy() + pdef5 := rpMatchLB0Perf5.GetOrCreatePolicyDefinition("match_linkbw_0_remove_and_set_localpref_5") + pdef5Stmt1, err := pdef5.AppendNewStatement("match_and_remove_linkbw_any_0") + if err != nil { + t.Fatalf("AppendNewStatement match_and_remove_linkbw_any_0 failed: %v", err) + } + ref = pdef5Stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() + ref.GetOrCreateReference().SetExtCommunitySetRef("linkbw_any_0") + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_REMOVE) + ref.SetMethod(oc.SetCommunity_Method_REFERENCE) + ref1 = pdef5Stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetMatchExtCommunitySet() + ref1.SetExtCommunitySet("linkbw_any_0") + pdef5Stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + pdef5Stmt1.GetOrCreateActions().GetOrCreateBgpActions().SetLocalPref = ygot.Uint32(5) + pdef5Stmt2, err := pdef5.AppendNewStatement("accept_all_routes") + if err != nil { + t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) + } + pdef5Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpMatchLB0Perf5) +} + +func createFlow(t *testing.T, td testData, fc flowConfig) { + td.top.Flows().Clear() + v4Flow := td.top.Flows().Add().SetName(v4Flow) + v4Flow.Metrics().SetEnable(true) + v4Flow.TxRx().Device(). + SetTxNames([]string{fc.src.Name + ".IPv4"}). + SetRxNames([]string{fc.dstNw}) + v4Flow.Size().SetFixed(512) + v4Flow.Rate().SetPps(100) + v4Flow.Duration().Continuous() + e1 := v4Flow.Packet().Add().Ethernet() + e1.Src().SetValue(fc.src.MAC) + v4 := v4Flow.Packet().Add().Ipv4() + v4.Src().SetValue(fc.src.IPv4) + v4.Dst().Increment().SetStart(fc.dstIP).SetCount(1) + + td.ate.OTG().PushConfig(t, td.top) + td.ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, td.ate.OTG(), td.top, "IPv4") +} + +func createFlowV6(t *testing.T, td testData, fc flowConfig) { + td.top.Flows().Clear() + v6Flow := td.top.Flows().Add().SetName(v6Flow) + v6Flow.Metrics().SetEnable(true) + v6Flow.TxRx().Device(). + SetTxNames([]string{fc.src.Name + ".IPv6"}). + SetRxNames([]string{fc.dstNw}) + v6Flow.Size().SetFixed(512) + v6Flow.Rate().SetPps(100) + v6Flow.Duration().Continuous() + e1 := v6Flow.Packet().Add().Ethernet() + e1.Src().SetValue(fc.src.MAC) + v6 := v6Flow.Packet().Add().Ipv6() + v6.Src().SetValue(fc.src.IPv6) + v6.Dst().Increment().SetStart(fc.dstIP).SetCount(1) + td.ate.OTG().PushConfig(t, td.top) + td.ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, td.ate.OTG(), td.top, "IPv6") +} + +func checkTraffic(t *testing.T, td testData, flowName string) { + td.ate.OTG().StartTraffic(t) + time.Sleep(time.Second * 30) + td.ate.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, td.ate.OTG(), td.top) + otgutils.LogPortMetrics(t, td.ate.OTG(), td.top) + recvMetric := gnmi.Get(t, td.ate.OTG(), gnmi.OTG().Flow(flowName).State()) + txPackets := recvMetric.GetCounters().GetOutPkts() + rxPackets := recvMetric.GetCounters().GetInPkts() + lostPackets := txPackets - rxPackets + lossPct := lostPackets * 100 / txPackets + + if lossPct > 1 { + t.Errorf("FAIL in checkTraffic - Got %v%% packet loss for %s ; expected < 1%%", lossPct, flowName) + } +} + +func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { + t.Helper() + + root := &oc.Root{} + ni := root.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(td.dut)) + bgpP := ni.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName) + bgpP.SetEnabled(true) + bgp := bgpP.GetOrCreateBgp() + + g := bgp.GetOrCreateGlobal() + g.SetAs(dutAS) + g.SetRouterId(dutPort1.IPv4) + g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + + nV41 := bgp.GetOrCreateNeighbor(atePort1.IPv4) + nV41.SetPeerAs(ateAS) + nV41.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV42 := bgp.GetOrCreateNeighbor(atePort2.IPv4) + nV42.SetPeerAs(dutAS) + nV42.SetSendCommunity(oc.Bgp_CommunityType_BOTH) + nV42.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV61 := bgp.GetOrCreateNeighbor(atePort1.IPv6) + nV61.SetPeerAs(ateAS) + nV61.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nV62 := bgp.GetOrCreateNeighbor(atePort2.IPv6) + nV62.SetPeerAs(dutAS) + nV62.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + gnmi.Update(t, td.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Config(), ni) + + // Configure eBGP on OTG port1. + ipv41 := td.otgP1.Ethernets().Items()[0].Ipv4Addresses().Items()[0] + dev1BGP := td.otgP1.Bgp().SetRouterId(atePort1.IPv4) + bgp4Peer1 := dev1BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv41.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP4.peer") + bgp4Peer1.SetPeerAddress(dutPort1.IPv4).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + ipv61 := td.otgP1.Ethernets().Items()[0].Ipv6Addresses().Items()[0] + bgp6Peer1 := dev1BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv61.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP6.peer") + bgp6Peer1.SetPeerAddress(dutPort1.IPv6).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + + // Configure emulated network on ATE port1. + netv41 := bgp4Peer1.V4Routes().Add().SetName("v4-bgpNet-dev1") + netv41.Addresses().Add().SetAddress(advertisedIPv41.address).SetPrefix(advertisedIPv41.prefix) + netv61 := bgp6Peer1.V6Routes().Add().SetName("v6-bgpNet-dev1") + netv61.Addresses().Add().SetAddress(advertisedIPv61.address).SetPrefix(advertisedIPv61.prefix) + + // Configure routes with BGP community. + netv42 := bgp4Peer1.V4Routes().Add().SetName("v4-bgpNet-dev2") + netv42.Addresses().Add().SetAddress(advertisedIPv42.address).SetPrefix(advertisedIPv42.prefix) + commv4 := netv42.Communities().Add() + commv4.SetType(gosnappi.BgpCommunityType.MANUAL_AS_NUMBER) + commv4.SetAsNumber(100) + commv4.SetAsCustom(100) + netv62 := bgp6Peer1.V6Routes().Add().SetName("v6-bgpNet-dev2") + netv62.Addresses().Add().SetAddress(advertisedIPv62.address).SetPrefix(advertisedIPv62.prefix) + commv6 := netv62.Communities().Add() + commv6.SetType(gosnappi.BgpCommunityType.MANUAL_AS_NUMBER) + commv6.SetAsNumber(100) + commv6.SetAsCustom(100) + + // Configure routes with Link bandwidth community. + netv43 := bgp4Peer1.V4Routes().Add().SetName("v4-bgpNet-dev3") + netv43.Addresses().Add().SetAddress(advertisedIPv43.address).SetPrefix(advertisedIPv43.prefix) + extcommv4 := netv43.ExtendedCommunities().Add().NonTransitive2OctetAsType().LinkBandwidthSubtype() + extcommv4.SetGlobal2ByteAs(100) + extcommv4.SetBandwidth(0) + netv63 := bgp6Peer1.V6Routes().Add().SetName("v6-bgpNet-dev3") + netv63.Addresses().Add().SetAddress(advertisedIPv63.address).SetPrefix(advertisedIPv63.prefix) + extcommv6 := netv63.ExtendedCommunities().Add().NonTransitive2OctetAsType().LinkBandwidthSubtype() + extcommv6.SetGlobal2ByteAs(100) + extcommv6.SetBandwidth(0) + + // Configure iBGP on OTG port2. + ipv42 := td.otgP2.Ethernets().Items()[0].Ipv4Addresses().Items()[0] + dev2BGP := td.otgP2.Bgp().SetRouterId(atePort2.IPv4) + bgp4Peer2 := dev2BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv42.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP4.peer") + bgp4Peer2.SetPeerAddress(dutPort2.IPv4).SetAsNumber(dutAS).SetAsType(gosnappi.BgpV4PeerAsType.IBGP) + bgp4Peer2.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + bgp4Peer2.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + ipv62 := td.otgP2.Ethernets().Items()[0].Ipv6Addresses().Items()[0] + bgp6Peer2 := dev2BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv62.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP6.peer") + bgp6Peer2.SetPeerAddress(dutPort2.IPv6).SetAsNumber(dutAS).SetAsType(gosnappi.BgpV6PeerAsType.IBGP) + bgp6Peer2.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true).SetExtendedNextHopEncoding(true) + bgp6Peer2.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) +} + +func (td *testData) verifyDUTBGPEstablished(t *testing.T) { + sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().NeighborAny().SessionState().State() + watch := gnmi.WatchAll(t, td.dut, sp, 2*time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + if !ok || state != oc.Bgp_Neighbor_SessionState_ESTABLISHED { + return false + } + return true + }) + if val, ok := watch.Await(t); !ok { + t.Fatalf("BGP sessions not established in verifyDUTBGPEstablished : got %v", val) + } +} + +// verifyOTGBGPEstablished verifies on OTG BGP peer establishment. +func (td *testData) verifyOTGBGPEstablished(t *testing.T) { + sp := gnmi.OTG().BgpPeerAny().SessionState().State() + watch := gnmi.WatchAll(t, td.ate.OTG(), sp, 2*time.Minute, func(val *ygnmi.Value[otgtelemetry.E_BgpPeer_SessionState]) bool { + state, ok := val.Val() + if !ok || state != otgtelemetry.BgpPeer_SessionState_ESTABLISHED { + return false + } + return true + }) + state, ok := watch.Await(t) + if !ok { + t.Fatalf("BGP sessions not established : verifyOTGBGPEstablished (%v)", state) + } +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + b := &gnmi.SetBatch{} + gnmi.BatchReplace(b, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) + gnmi.BatchReplace(b, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) + b.Set(t, dut) + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, p1) + fptest.SetPortSpeed(t, p2) + } + + fptest.ConfigureDefaultNetworkInstance(t, dut) + + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) + } +} + +func configureOTG(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) []gosnappi.Device { + t.Helper() + p1 := ate.Port(t, "port1") + p2 := ate.Port(t, "port2") + + d1 := atePort1.AddToOTG(top, p1, &dutPort1) + d2 := atePort2.AddToOTG(top, p2, &dutPort2) + return []gosnappi.Device{d1, d2} +} + +// TODO to move base setup config in helper. +func baseSetupConfigAndVerification(t *testing.T, td testData) { + td.advertiseRoutesWithEBGP(t) + td.ate.OTG().PushConfig(t, td.top) + td.ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, td.ate.OTG(), td.top, "IPv4") + otgutils.WaitForARP(t, td.ate.OTG(), td.top, "IPv6") + td.verifyDUTBGPEstablished(t) + td.verifyOTGBGPEstablished(t) + configureImportRoutingPolicyAllowAll(t, td.dut) + validateImportRoutingPolicyAllowAll(t, td.dut, td.ate) + createFlow(t, td, flowConfig{src: atePort2, dstNw: "v4-bgpNet-dev1", dstIP: v41TrafficStart}) + checkTraffic(t, td, v4Flow) + createFlowV6(t, td, flowConfig{src: atePort2, dstNw: "v6-bgpNet-dev1", dstIP: v61TrafficStart}) + checkTraffic(t, td, v6Flow) + createFlow(t, td, flowConfig{src: atePort2, dstNw: "v4-bgpNet-dev2", dstIP: v42TrafficStart}) + checkTraffic(t, td, v4Flow) + createFlowV6(t, td, flowConfig{src: atePort2, dstNw: "v6-bgpNet-dev2", dstIP: v62TrafficStart}) + checkTraffic(t, td, v6Flow) + createFlow(t, td, flowConfig{src: atePort2, dstNw: "v4-bgpNet-dev3", dstIP: v43TrafficStart}) + checkTraffic(t, td, v4Flow) + createFlowV6(t, td, flowConfig{src: atePort2, dstNw: "v6-bgpNet-dev3", dstIP: v63TrafficStart}) + checkTraffic(t, td, v6Flow) +} + +func verifyExtCommunityIndexV4(t *testing.T, td testData, v4Address string) { + dni := deviations.DefaultNetworkInstance(td.dut) + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv4Unicast_LocRib](t, td.dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast().LocRib().State()) + t.Logf("RIB: %v", locRib) + for route, prefix := range locRib.Route { + if prefix.GetPrefix() != v4Address { + continue + } + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", route.Prefix, route.Origin, route.PathId, prefix.GetPrefix()) + if prefix.ExtCommunityIndex == nil { + t.Fatalf("No V4 community index found") + } + extCommunity := bgpRIBPath.ExtCommunity(prefix.GetExtCommunityIndex()).ExtCommunity().State() + if extCommunity == nil { + t.Fatalf("No V4 community found at given index: %v", prefix.GetExtCommunityIndex()) + } + } +} + +func verifyExtCommunityIndexV6(t *testing.T, td testData, v6Address string) { + dni := deviations.DefaultNetworkInstance(td.dut) + bgpRIBPathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() + locRibv6 := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv6Unicast_LocRib](t, td.dut, bgpRIBPathV6.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast().LocRib().State()) + t.Logf("RIB: %v", locRibv6) + for route, prefix := range locRibv6.Route { + if prefix.GetPrefix() != v6Address { + continue + } + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", route.Prefix, route.Origin, route.PathId, prefix.GetPrefix()) + if prefix.ExtCommunityIndex == nil { + t.Fatalf("No V6 community index found") + } + extCommunity := bgpRIBPathV6.ExtCommunity(prefix.GetExtCommunityIndex()).ExtCommunity().State() + if extCommunity == nil { + t.Fatalf("No V6 community found at given index: %v", prefix.GetExtCommunityIndex()) + } + } +} diff --git a/feature/experimental/bgp/otg_tests/link_bandwidth_test/metadata.textproto b/feature/experimental/bgp/otg_tests/link_bandwidth_test/metadata.textproto new file mode 100644 index 00000000000..5e5b04d3695 --- /dev/null +++ b/feature/experimental/bgp/otg_tests/link_bandwidth_test/metadata.textproto @@ -0,0 +1,25 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "a8344612-0db0-42a1-96cf-38846a7f1603" +plan_id: "RT-7.5" +description: "BGP Policy - Match and Set Link Bandwidth Community" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + route_policy_under_afi_unsupported: true + omit_l2_mtu: true + missing_value_for_defaults: true + interface_enabled: true + default_network_instance: "default" + skip_set_rp_match_set_options: true + skip_setting_disable_metric_propagation: true + bgp_conditions_match_community_set_unsupported: true + bgp_extended_community_index_unsupported: true + } +} +tags: TAGS_AGGREGATION +tags: TAGS_DATACENTER_EDGE diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 6c2bedde4fd..c51d87f31d4 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -896,3 +896,8 @@ func PLQGeneratorCapabilitiesMaxMTU(dut *ondatra.DUTDevice) uint32 { func PLQGeneratorCapabilitiesMaxPPS(dut *ondatra.DUTDevice) uint64 { return lookupDUTDeviations(dut).GetPlqGeneratorCapabilitiesMaxPps() } + +// BgpExtendedCommunityIndexUnsupported return true if BGP extended community index is not supported. +func BgpExtendedCommunityIndexUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetBgpExtendedCommunityIndexUnsupported() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 51bf2118ac1..9ec70094cdf 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -471,7 +471,8 @@ message Metadata { uint32 plq_generator_capabilities_max_mtu = 165; // Device that does not support PLQ Generator max_pps to be atleast >= 100000000. uint64 plq_generator_capabilities_max_pps = 166; - + // Support for bgp extended community index + bool bgp_extended_community_index_unsupported = 167; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 81689727efc..41d04aaa027 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.23.4 +// protoc-gen-go v1.28.1 +// protoc v3.21.12 // source: metadata.proto package metadata_go_proto @@ -742,6 +742,8 @@ type Metadata_Deviations struct { PlqGeneratorCapabilitiesMaxMtu uint32 `protobuf:"varint,165,opt,name=plq_generator_capabilities_max_mtu,json=plqGeneratorCapabilitiesMaxMtu,proto3" json:"plq_generator_capabilities_max_mtu,omitempty"` // Device that does not support PLQ Generator max_pps to be atleast >= 100000000. PlqGeneratorCapabilitiesMaxPps uint64 `protobuf:"varint,166,opt,name=plq_generator_capabilities_max_pps,json=plqGeneratorCapabilitiesMaxPps,proto3" json:"plq_generator_capabilities_max_pps,omitempty"` + // Support for bgp extended community index + BgpExtendedCommunityIndexUnsupported bool `protobuf:"varint,167,opt,name=bgp_extended_community_index_unsupported,json=bgpExtendedCommunityIndexUnsupported,proto3" json:"bgp_extended_community_index_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1826,6 +1828,13 @@ func (x *Metadata_Deviations) GetPlqGeneratorCapabilitiesMaxPps() uint64 { return 0 } +func (x *Metadata_Deviations) GetBgpExtendedCommunityIndexUnsupported() bool { + if x != nil { + return x.BgpExtendedCommunityIndexUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1889,7 +1898,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdd, 0x5d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, 0x5e, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1920,7 +1929,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xde, 0x55, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xb7, 0x56, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2603,43 +2612,49 @@ var file_metadata_proto_rawDesc = []byte{ 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x70, 0x73, 0x18, 0xa6, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x50, - 0x70, 0x73, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, - 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, - 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, - 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, - 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, - 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, - 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, - 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, - 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, - 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, - 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, - 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, - 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, - 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, - 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, - 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x73, 0x12, 0x57, 0x0a, 0x28, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa7, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, + 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, + 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, + 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, + 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, + 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, + 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, + 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, + 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, + 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, + 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, + 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, + 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, + 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, + 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, + 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, + 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, + 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, + 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, + 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, + 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, + 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, + 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/testregistry.textproto b/testregistry.textproto index 846fa782588..fff14aa11e3 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -769,7 +769,7 @@ test: { test: { id: "RT-7.5" description: "BGP Policy - Set Link Bandwidth Community" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/bgp/otg_tests/link_bandwidth_test/README.md" } test: { id: "RT-7.6" From 17c0e03d016444f4090a8d0ca353440b3920f90b Mon Sep 17 00:00:00 2001 From: bkreddy143 <127771656+bkreddy143@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:03:19 -0400 Subject: [PATCH 57/97] updated pr4t and gribi process names (#2794) as part unified grpc server support gribi and p4rt services are moved as service inside grpc server instance.Also,restart of grpc_server will restart assosiates services as well. "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --- .../otg_tests/dut_daemon_failure/dut_daemon_failure_test.go | 2 +- .../p4rt_daemon_failure_test/p4rt_daemon_failure_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go b/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go index 1207b3b0346..a07108c8c39 100644 --- a/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go +++ b/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go @@ -93,7 +93,7 @@ var ( ondatra.ARISTA: "Gribi", ondatra.CISCO: "emsd", ondatra.JUNIPER: "rpd", - ondatra.NOKIA: "sr_gribi_server", + ondatra.NOKIA: "sr_grpc_server", } ) diff --git a/feature/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go b/feature/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go index e9dd420e736..239ea5ba306 100644 --- a/feature/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go +++ b/feature/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go @@ -85,7 +85,7 @@ var ( ondatra.ARISTA: "P4Runtime", ondatra.CISCO: "emsd", ondatra.JUNIPER: "p4-switch", - ondatra.NOKIA: "sr_p4rt_server", + ondatra.NOKIA: "sr_grpc_server", } ) @@ -359,7 +359,7 @@ func TestP4RTDaemonFailure(t *testing.T) { ate.OTG().StopTraffic(t) // Skip check for CISCO devices that use the same process for P4RT & gNMI. - if dut.Vendor() != ondatra.CISCO { + if dut.Vendor() != ondatra.CISCO && dut.Vendor() != ondatra.NOKIA { // Verify interfaceID did not change since the last time we read it. changedID, notOk := watchID.Await(t) if notOk { From 2135411a5aafab02d9dd9ca43eff10e41d5ef179 Mon Sep 17 00:00:00 2001 From: nraghavendran <107150544+nraghavendran@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:57:17 -0700 Subject: [PATCH 58/97] fixing duplicate test id issue for mpls forwarding static lsp test (#2862) --- feature/gribi/otg_tests/static_lsp/README.md | 2 +- testregistry.textproto | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/feature/gribi/otg_tests/static_lsp/README.md b/feature/gribi/otg_tests/static_lsp/README.md index 6df7598eb58..eced4b37bd8 100644 --- a/feature/gribi/otg_tests/static_lsp/README.md +++ b/feature/gribi/otg_tests/static_lsp/README.md @@ -1,4 +1,4 @@ -# TE-9.1: MPLS based forwarding Static LSP +# TE-9.2: MPLS based forwarding Static LSP ## Summary diff --git a/testregistry.textproto b/testregistry.textproto index fff14aa11e3..c6750412a35 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -1034,16 +1034,16 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/ate_tests/supervisor_failure_test/README.md" exec: " " } -test: { - id: "TE-9" - description: "MPLS based forwarding Static LSP" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/mpls_compliance/README.md" -} test: { id: "TE-9.1" description: "Base gRIBI MPLS Compliance" readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/static_lsp/README.md" } +test: { + id: "TE-9.2" + description: "MPLS based forwarding Static LSP" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/mpls_compliance/README.md" +} test: { id: "TE-10" description: "gRIBI MPLS Forwarding" From 6342007505160ae1556debbd7f41fa73a0fe3b3d Mon Sep 17 00:00:00 2001 From: prakashbadri-arista <127355794+prakashbadri-arista@users.noreply.github.com> Date: Mon, 1 Apr 2024 11:04:40 -0700 Subject: [PATCH 59/97] Remove the deletion of vrf selection policy parent OC path in the API used (#2858) for creating dcGate policies - 'configureVRFSelectionPolicyW' currently deletes '/network-instances/network-instance[name=default]/policy-forwarding/' when attempting to clean the old policies, before creating the new policies for a given test. But given that the function does a gNMI.replace() the deletion of the old policy is not required. Also a replace without the delete represents the realistic production scenario where the entire config for a device will be pushed. --- internal/vrfpolicy/vrfpolicy.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/vrfpolicy/vrfpolicy.go b/internal/vrfpolicy/vrfpolicy.go index 33f65574c24..c4580303c8c 100644 --- a/internal/vrfpolicy/vrfpolicy.go +++ b/internal/vrfpolicy/vrfpolicy.go @@ -197,9 +197,6 @@ func BuildVRFSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice, niName strin func ConfigureVRFSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice) { t.Helper() - t.Log("Delete existing vrf selection policy and Apply vrf selectioin policy W") - gnmi.Delete(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Config()) - port1 := dut.Port(t, "port1") interfaceID := port1.Name() if deviations.InterfaceRefInterfaceIDFormat(dut) { From 418a962276e4226b8cfaeb3a116c011cd32e3928 Mon Sep 17 00:00:00 2001 From: Nick Hawke Date: Mon, 1 Apr 2024 16:48:41 -0400 Subject: [PATCH 60/97] Update ondatra version to 0.5.5 (#2868) --- go.mod | 20 ++++++++++---------- go.sum | 35 ++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 0c9db6be366..54475cf8beb 100644 --- a/go.mod +++ b/go.mod @@ -15,11 +15,11 @@ require ( github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/kr/pretty v0.3.1 - github.com/open-traffic-generator/snappi/gosnappi v1.1.0 + github.com/open-traffic-generator/snappi/gosnappi v1.2.0 github.com/openconfig/entity-naming v0.0.0-20230912181021-7ac806551a31 - github.com/openconfig/gnmi v0.10.0 + github.com/openconfig/gnmi v0.11.0 github.com/openconfig/gnoi v0.4.0 - github.com/openconfig/gnoigo v0.0.0-20240214160338-8660e1580468 + github.com/openconfig/gnoigo v0.0.0-20240320202954-ebd033e3542c github.com/openconfig/gnsi v1.4.0 github.com/openconfig/gocloser v0.0.0-20220310182203-c6c950ed3b0b github.com/openconfig/goyang v1.4.5 @@ -27,16 +27,17 @@ require ( github.com/openconfig/gribigo v0.0.0-20231213034307-d0abeba7f432 github.com/openconfig/kne v0.1.17 github.com/openconfig/models-ci v1.0.2-0.20231113233730-f0986391428e - github.com/openconfig/ondatra v0.5.4 + github.com/openconfig/ondatra v0.5.5 github.com/openconfig/replayer v0.0.0-20240110192655-4e9cf83d8d30 github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 github.com/openconfig/ygnmi v0.11.1 github.com/openconfig/ygot v0.29.18 github.com/p4lang/p4runtime v1.4.0-rc.5.0.20220728214547-13f0d02a521e + github.com/pborman/uuid v1.2.1 github.com/protocolbuffers/txtpbfmt v0.0.0-20220608084003-fc78c767cd6a github.com/yoheimuta/go-protoparser/v4 v4.9.0 golang.org/x/crypto v0.21.0 - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 + golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 golang.org/x/text v0.14.0 google.golang.org/api v0.155.0 google.golang.org/grpc v1.62.1 @@ -116,8 +117,7 @@ require ( github.com/openconfig/grpctunnel v0.0.0-20220819142823-6f5422b8ca70 // indirect github.com/openconfig/lemming/operator v0.2.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pborman/uuid v1.2.1 // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect @@ -146,17 +146,17 @@ require ( go.opentelemetry.io/otel/trace v1.21.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.15.0 // indirect + golang.org/x/mod v0.16.0 // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.18.0 // indirect + golang.org/x/tools v0.19.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index ccba6217896..b7378eb1631 100644 --- a/go.sum +++ b/go.sum @@ -1625,18 +1625,19 @@ github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/open-traffic-generator/keng-operator v0.3.15 h1:4qMC8MaCfV7TmmrfqI7rTusOChkHpiA8maih88aLaqY= github.com/open-traffic-generator/keng-operator v0.3.15/go.mod h1:+koaOnSyrJHdzxnaye+M6k+ZbszQlWI9u3tMxSpORNA= -github.com/open-traffic-generator/snappi/gosnappi v1.1.0 h1:xPWa7kUaGNmF0zihv4hsBDHNSqR/YXGc6fD6tj8sJv4= -github.com/open-traffic-generator/snappi/gosnappi v1.1.0/go.mod h1:CaE4nisXftNXdXWvTSqb4eiW2WMFIXkJsH5rqPoipcg= +github.com/open-traffic-generator/snappi/gosnappi v1.2.0 h1:yBKLr7mXnpvEE4cFwS7KeYXr1+xw7SL64XVY3mDhkuw= +github.com/open-traffic-generator/snappi/gosnappi v1.2.0/go.mod h1:CaE4nisXftNXdXWvTSqb4eiW2WMFIXkJsH5rqPoipcg= github.com/openconfig/entity-naming v0.0.0-20230912181021-7ac806551a31 h1:K/9O+J20+liIof8WjquMydnebD0N1U9ItjhJYF6H4hg= github.com/openconfig/entity-naming v0.0.0-20230912181021-7ac806551a31/go.mod h1:ZRUrfwYYY+pLaOoWPad3p/8J4LLQcSqtXhBCkD2pXJc= github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= -github.com/openconfig/gnmi v0.10.0 h1:kQEZ/9ek3Vp2Y5IVuV2L/ba8/77TgjdXg505QXvYmg8= github.com/openconfig/gnmi v0.10.0/go.mod h1:Y9os75GmSkhHw2wX8sMsxfI7qRGAEcDh8NTa5a8vj6E= +github.com/openconfig/gnmi v0.11.0 h1:H7pLIb/o3xObu3+x0Fv9DCK7TH3FUh7mNwbYe+34hFw= +github.com/openconfig/gnmi v0.11.0/go.mod h1:9oJSQPPCpNvfMRj8e4ZoLVAw4wL8HyxXbiDlyuexCGU= github.com/openconfig/gnoi v0.4.0 h1:jbYXRMNmmvA8ZFv2FBLrYoxA1MFSui4tEui+8LAWyVc= github.com/openconfig/gnoi v0.4.0/go.mod h1:0d3/bgooXM/je6jI+fb7+9Iky8R8k6zSFG19xRYTRso= -github.com/openconfig/gnoigo v0.0.0-20240214160338-8660e1580468 h1:84ZrTGWMB73qVSX8uExxFNTHZKEmBJse1QXAdo/Eywc= -github.com/openconfig/gnoigo v0.0.0-20240214160338-8660e1580468/go.mod h1:iwgbKmQ8IU82mszJWXKpR0HSZiZ4DjeAnBZhYTp+l+4= +github.com/openconfig/gnoigo v0.0.0-20240320202954-ebd033e3542c h1:egPgBUBDn0XEtbz0CvE+Bh/I/3iTzwzMq5/rmtPJdQs= +github.com/openconfig/gnoigo v0.0.0-20240320202954-ebd033e3542c/go.mod h1:Se/HklUcFVcCGB66khgYouiesLRPoa4UL1ovvmE/68k= github.com/openconfig/gnsi v1.4.0 h1:E/OnAZh7jr3xpTdyawYXloVUg0cQbU3WQLtDGib/7L4= github.com/openconfig/gnsi v1.4.0/go.mod h1:jzPF4rVWPHhIG0F3t910Hh2VqqTbSfv18shbgE4AXhw= github.com/openconfig/gocloser v0.0.0-20220310182203-c6c950ed3b0b h1:NSYuxdlOWLldNpid1dThR6Dci96juXioUguMho6aliI= @@ -1661,8 +1662,8 @@ github.com/openconfig/lemming/operator v0.2.0 h1:dovZnR6lQkOHXcODli1NDOr/GVYrBY0 github.com/openconfig/lemming/operator v0.2.0/go.mod h1:LKgEXSR5VK2CAeh2uKijKAXFj42uQuwakrCHVPF0iII= github.com/openconfig/models-ci v1.0.2-0.20231113233730-f0986391428e h1:6N4jXpZa/SXYcNpJFjjZvenxO/xnTwuUCgCEinhNLfU= github.com/openconfig/models-ci v1.0.2-0.20231113233730-f0986391428e/go.mod h1:w38G/kObu95PbtwMYVp6SKhkHCegJFwL8B58Ns84g4s= -github.com/openconfig/ondatra v0.5.4 h1:ldyCk2HaJXIANFdGJHFdmLmb/amlYHLEDCliZYkkldA= -github.com/openconfig/ondatra v0.5.4/go.mod h1:QfGq//x6XIZcGmxFceyu1FYSgZk2nsLAc3NnYFyT51I= +github.com/openconfig/ondatra v0.5.5 h1:X/NSZcI8SQ9uhSoB2rJkh29YvBnqNWiVVgFFlSyRnEE= +github.com/openconfig/ondatra v0.5.5/go.mod h1:hFxrMsLsOmvOzHeUDDJZcypenZIo6lt6NrPOdDmnHHM= github.com/openconfig/replayer v0.0.0-20240110192655-4e9cf83d8d30 h1:KcHS08m7nFHq/D03ZfZKKNCSaS1jsuvdF3lCyDjPWJc= github.com/openconfig/replayer v0.0.0-20240110192655-4e9cf83d8d30/go.mod h1:VQ8FdPVaHwxKtamhcrwkPsvTeeoEgFYNK1xE8nHD0S8= github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 h1:X631iD/B0ximGFb5P9LY5wHju4SiedxUhc5UZEo7VSw= @@ -1683,8 +1684,8 @@ github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwp github.com/pborman/getopt v1.1.0/go.mod h1:FxXoW1Re00sQG/+KIkuSqRL/LwQgSkv7uyac+STFsbk= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= +github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= @@ -1894,8 +1895,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1941,8 +1942,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2288,8 +2289,8 @@ golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2600,8 +2601,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 h1:IR+hp6ypxjH24bkMfEJ0yHR21+gwPWdV+/IBrPQyn3k= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= From 5627ade321d3c934babe51e0937e9bacb2aabaaa Mon Sep 17 00:00:00 2001 From: anksaiki Date: Tue, 2 Apr 2024 00:06:35 -0400 Subject: [PATCH 61/97] MED policy code fix' (#2869) --- .../actions_MED_LocPref_prepend_flow_control_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go b/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go index facfd899135..28cbe43c023 100644 --- a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go +++ b/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go @@ -861,10 +861,10 @@ func TestBGPPolicy(t *testing.T) { verifyBgpPolicyTelemetry(t, dut, atePort2.IPv4, tc.defPolicyPort2, tc.policyTypePort2, true) verifyBgpPolicyTelemetry(t, dut, atePort2.IPv6, tc.defPolicyPort2, tc.policyTypePort2, false) // Validate Prefixes - validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, otgConfig, atePort1.Name+".BGP4.Route", tc.port1v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) - validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, otgConfig, atePort1.Name+".BGP6.Route", tc.port1v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) - validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, otgConfig, atePort2.Name+".BGP4.Route", tc.port2v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) - validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, otgConfig, atePort2.Name+".BGP6.Route", tc.port2v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, otgConfig, atePort1.Name+".BGP4.peer", tc.port1v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, otgConfig, atePort1.Name+".BGP6.peer", tc.port1v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, otgConfig, atePort2.Name+".BGP4.peer", tc.port2v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, otgConfig, atePort2.Name+".BGP6.peer", tc.port2v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) }) } } From 63d06bc32a739cffe52e801de93d21df86ae2cf0 Mon Sep 17 00:00:00 2001 From: Ram Date: Tue, 2 Apr 2024 10:10:30 +0530 Subject: [PATCH 62/97] Fixing RT 1.30 Nested Policy Test (#2851) * Fixing RT 1.30 Nested Policy Test * Added sleep after gnmi update on export policy --- .../nested_policies/nested_policies_test.go | 142 +++++------------- 1 file changed, 38 insertions(+), 104 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go b/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go index abbe6c49ab7..89b29749541 100644 --- a/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go +++ b/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go @@ -17,6 +17,7 @@ package nested_policies_test import ( "fmt" "net" + "strings" "testing" "time" @@ -41,13 +42,14 @@ const ( v42Route = "198.51.100.0" v42TrafficStart = "198.51.100.1" v4RoutePrefix = uint32(24) - v61Route = "2001:db8:128:128::0" + v61Route = "2001:db8:128:128::" v61TrafficStart = "2001:db8:128:128::1" - v62Route = "2001:db8:128:129::0" + v62Route = "2001:db8:128:129::" v62TrafficStart = "2001:db8:128:129::1" v6RoutePrefix = uint32(64) dutAS = uint32(65656) - ateAS = uint32(65657) + ateAS1 = uint32(65657) + ateAS2 = uint32(65658) bgpName = "BGP" maskLenExact = "exact" localPref = 200 @@ -177,10 +179,6 @@ func TestBGPNestedPolicies(t *testing.T) { otgutils.WaitForARP(t, ate.OTG(), top, "IPv6") td.verifyDUTBGPEstablished(t) td.verifyOTGBGPEstablished(t) - td.verifyNestedImportPolicyAttachedv4(t) - td.verifyNestedImportPolicyAttachedv6(t) - td.verifyNestedExportPolicyAttachedv4(t) - td.verifyNestedExportPolicyAttachedv6(t) testCases := []testCase{ { @@ -244,7 +242,7 @@ func configureImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", v4LPStatement, err) } - stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) stmt1.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(localPref) // Configure a route-policy to match the prefix. @@ -254,6 +252,7 @@ func configureImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Fatalf("AppendNewStatement(%s) failed: %v", v4PrefixStatement, err) } stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + t.Logf("Configuring nested policy") // Configure a prefix-set for route filtering/matching. prefixSet := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(v4PrefixSet) prefixSet.SetMode(oc.PrefixSet_Mode_IPV4) @@ -268,33 +267,25 @@ func configureImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { // Configure the nested policy. dni := deviations.DefaultNetworkInstance(dut) rpPolicy := root.GetOrCreateRoutingPolicy() - statPath := rpPolicy.GetOrCreatePolicyDefinition(v4LPPolicy).GetStatement(v4LPStatement).GetConditions() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v4LPPolicy).GetStatement(v4LPStatement).GetOrCreateConditions() statPath.SetCallPolicy(v4PrefixPolicy) gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) // Configure the parent BGP import policy. path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() - policy.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetImportPolicy([]string{v4LPPolicy}) gnmi.Update(t, dut, path.Config(), policy) - } func validateImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { dni := deviations.DefaultNetworkInstance(dut) - path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() - policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) - importPolicies := policy.GetImportPolicy() - if len(importPolicies) != 2 { - t.Errorf("ImportPolicy = %v, want %v", importPolicies, []string{v4PrefixPolicy, v4LPPolicy}) - } - bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv4Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast().LocRib().State()) found := false for k, lr := range locRib.Route { - if lr.GetPrefix() == advertisedIPv41.address { + prefixAddr := strings.Split(lr.GetPrefix(), "/") + if prefixAddr[0] == advertisedIPv41.address { found = true t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) @@ -314,6 +305,7 @@ func validateImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *onda func configureExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() + t.Logf("Configuring export routing policy") pdef1 := rp.GetOrCreatePolicyDefinition(v4ASPPolicy) stmt1, err := pdef1.AppendNewStatement(v4ASPStatement) if err != nil { @@ -334,34 +326,28 @@ func configureExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { // Configure the nested policy. dni := deviations.DefaultNetworkInstance(dut) rpPolicy := root.GetOrCreateRoutingPolicy() - statPath := rpPolicy.GetOrCreatePolicyDefinition(v4ASPPolicy).GetStatement(v4ASPStatement).GetConditions() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v4ASPPolicy).GetStatement(v4ASPStatement).GetOrCreateConditions() statPath.SetCallPolicy(v4MedPolicy) gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) + time.Sleep(time.Second * 60) // Configure the parent BGP import policy. path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() - policy.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetExportPolicy([]string{v4ASPPolicy}) gnmi.Update(t, dut, path.Config(), policy) + time.Sleep(time.Second * 60) } func validateExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { - dni := deviations.DefaultNetworkInstance(dut) - path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() - policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) - exportPolicies := policy.GetExportPolicy() - if len(exportPolicies) != 2 { - t.Errorf("ExportPolicy = %v, want %v", exportPolicies, []string{v4PrefixPolicy, v4LPPolicy}) - } - - bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv4Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("v4-bgpNet-dev2").UnicastIpv4PrefixAny().State()) + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv4Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("atePort1.BGP4.peer").UnicastIpv4PrefixAny().State()) found := false for _, bgpPrefix := range bgpPrefixes { if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == v42Route && bgpPrefix.PrefixLength != nil && bgpPrefix.GetPrefixLength() == v4RoutePrefix { found = true t.Logf("Prefix recevied on OTG is correct, got prefix %v, want prefix %v", bgpPrefix, v42Route) + t.Logf("Prefix MED %d", bgpPrefix.GetMultiExitDiscriminator()) if bgpPrefix.GetMultiExitDiscriminator() != med { t.Errorf("For Prefix %v, got MED %d want MED %d", bgpPrefix.GetAddress(), bgpPrefix.GetMultiExitDiscriminator(), med) } @@ -390,7 +376,7 @@ func validateExportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *onda func configureImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() - + t.Logf("Configuring import routing policy") pdef1 := rp.GetOrCreatePolicyDefinition(v6LPPolicy) stmt1, err := pdef1.AppendNewStatement(v6LPStatement) if err != nil { @@ -419,32 +405,26 @@ func configureImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { // Configure the nested policy. dni := deviations.DefaultNetworkInstance(dut) rpPolicy := root.GetOrCreateRoutingPolicy() - statPath := rpPolicy.GetOrCreatePolicyDefinition(v6LPPolicy).GetStatement(v6LPStatement).GetConditions() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v6LPPolicy).GetStatement(v6LPStatement).GetOrCreateConditions() statPath.SetCallPolicy(v6PrefixPolicy) gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) // Configure the parent BGP import policy. path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() - policy.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetImportPolicy([]string{v6LPPolicy}) gnmi.Update(t, dut, path.Config(), policy) } func validateImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { dni := deviations.DefaultNetworkInstance(dut) - path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() - policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) - importPolicies := policy.GetImportPolicy() - if len(importPolicies) != 2 { - t.Errorf("ImportPolicy = %v, want %v", importPolicies, []string{v6PrefixPolicy, v6LPPolicy}) - } - bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Rib() locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv6Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast().LocRib().State()) found := false for k, lr := range locRib.Route { - if lr.GetPrefix() == advertisedIPv61.address { + prefixAddr := strings.Split(lr.GetPrefix(), "/") + t.Logf("lr.GetPrefix() -> %s, prefixAddr[0] -> %s, advertisedIPv61.address = %s", lr.GetPrefix(), prefixAddr[0], advertisedIPv61.address) + if prefixAddr[0] == advertisedIPv61.address { found = true t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) @@ -454,7 +434,6 @@ func validateImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *on break } } - if !found { t.Errorf("No Route found for prefix %s", advertisedIPv61.address) } @@ -464,6 +443,7 @@ func validateImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *on func configureExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() + t.Logf("Configuring export routing policy") pdef1 := rp.GetOrCreatePolicyDefinition(v6ASPPolicy) stmt1, err := pdef1.AppendNewStatement(v6ASPStatement) if err != nil { @@ -484,28 +464,22 @@ func configureExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice) { // Configure the nested policy. dni := deviations.DefaultNetworkInstance(dut) rpPolicy := root.GetOrCreateRoutingPolicy() - statPath := rpPolicy.GetOrCreatePolicyDefinition(v6ASPPolicy).GetStatement(v6ASPStatement).GetConditions() + statPath := rpPolicy.GetOrCreatePolicyDefinition(v6ASPPolicy).GetStatement(v6ASPStatement).GetOrCreateConditions() statPath.SetCallPolicy(v6MedPolicy) gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpPolicy) + time.Sleep(time.Second * 60) // Configure the parent BGP export policy. path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort1.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() - policy.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policy.SetExportPolicy([]string{v6ASPPolicy}) gnmi.Update(t, dut, path.Config(), policy) + time.Sleep(time.Second * 60) } func validateExportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { - dni := deviations.DefaultNetworkInstance(dut) - path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() - policy := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy](t, dut, path.State()) - exportPolicies := policy.GetExportPolicy() - if len(exportPolicies) != 2 { - t.Errorf("ExportPolicy = %v, want %v", exportPolicies, []string{v6PrefixPolicy, v6LPPolicy}) - } + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv6Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("atePort1.BGP6.peer").UnicastIpv6PrefixAny().State()) - bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv6Prefix](t, ate.OTG(), gnmi.OTG().BgpPeer("v6-bgpNet-dev2").UnicastIpv6PrefixAny().State()) found := false for _, bgpPrefix := range bgpPrefixes { if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == v62Route && @@ -618,17 +592,17 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) nV41 := bgp.GetOrCreateNeighbor(atePort1.IPv4) - nV41.SetPeerAs(ateAS) + nV41.SetPeerAs(ateAS1) nV41.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) nV42 := bgp.GetOrCreateNeighbor(atePort2.IPv4) - nV42.SetPeerAs(ateAS) + nV42.SetPeerAs(ateAS2) nV42.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) nV61 := bgp.GetOrCreateNeighbor(atePort1.IPv6) - nV61.SetPeerAs(ateAS) + nV61.SetPeerAs(ateAS1) nV61.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) nV62 := bgp.GetOrCreateNeighbor(atePort2.IPv6) - nV62.SetPeerAs(ateAS) + nV62.SetPeerAs(ateAS2) nV62.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) gnmi.Update(t, td.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Config(), ni) @@ -636,11 +610,13 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { ipv41 := td.otgP1.Ethernets().Items()[0].Ipv4Addresses().Items()[0] dev1BGP := td.otgP1.Bgp().SetRouterId(atePort1.IPv4) bgp4Peer1 := dev1BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv41.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP4.peer") - bgp4Peer1.SetPeerAddress(dutPort1.IPv4).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer1.SetPeerAddress(dutPort1.IPv4).SetAsNumber(ateAS1).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer1.LearnedInformationFilter().SetUnicastIpv4Prefix(true) ipv61 := td.otgP1.Ethernets().Items()[0].Ipv6Addresses().Items()[0] bgp6Peer1 := dev1BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv61.Name()).Peers().Add().SetName(td.otgP1.Name() + ".BGP6.peer") - bgp6Peer1.SetPeerAddress(dutPort1.IPv6).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer1.SetPeerAddress(dutPort1.IPv6).SetAsNumber(ateAS1).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer1.LearnedInformationFilter().SetUnicastIpv6Prefix(true) // Configure emulated network on ATE port1. netv41 := bgp4Peer1.V4Routes().Add().SetName("v4-bgpNet-dev1") @@ -652,11 +628,13 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { ipv42 := td.otgP2.Ethernets().Items()[0].Ipv4Addresses().Items()[0] dev2BGP := td.otgP2.Bgp().SetRouterId(atePort2.IPv4) bgp4Peer2 := dev2BGP.Ipv4Interfaces().Add().SetIpv4Name(ipv42.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP4.peer") - bgp4Peer2.SetPeerAddress(dutPort2.IPv4).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer2.SetPeerAddress(dutPort2.IPv4).SetAsNumber(ateAS2).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + bgp4Peer2.LearnedInformationFilter().SetUnicastIpv4Prefix(true) ipv62 := td.otgP2.Ethernets().Items()[0].Ipv6Addresses().Items()[0] bgp6Peer2 := dev2BGP.Ipv6Interfaces().Add().SetIpv6Name(ipv62.Name()).Peers().Add().SetName(td.otgP2.Name() + ".BGP6.peer") - bgp6Peer2.SetPeerAddress(dutPort2.IPv6).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer2.SetPeerAddress(dutPort2.IPv6).SetAsNumber(ateAS2).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + bgp6Peer2.LearnedInformationFilter().SetUnicastIpv6Prefix(true) // Configure emulated network on ATE port2. netv42 := bgp4Peer2.V4Routes().Add().SetName("v4-bgpNet-dev2") @@ -697,50 +675,6 @@ func (td *testData) verifyOTGBGPEstablished(t *testing.T) { t.Log("OTG BGP sessions established") } -// verifyNestedImportPolicyAttachedv4 verifies on dut for IPV4 BGP parent import policy v4LPPolicy has a child policy attached. -func (td *testData) verifyNestedImportPolicyAttachedv4(t *testing.T) { - rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v4LPPolicy).State() - subResponse := gnmi.Get(t, td.dut, rpDefPath) - callPolicy := subResponse.GetStatement(v4LPStatement).Conditions.GetCallPolicy() - if callPolicy != v4PrefixPolicy { - t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v4PrefixPolicy) - } - t.Log("Nested policy 'v4PrefixPolicy' verified successfully") -} - -// verifyNestedExportPolicyAttachedv4 verifies on dut for IPV4 BGP parent export policy v4ASPPolicy has a child policy attached. -func (td *testData) verifyNestedExportPolicyAttachedv4(t *testing.T) { - rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v4ASPPolicy).State() - subResponse := gnmi.Get(t, td.dut, rpDefPath) - callPolicy := subResponse.GetStatement(v4ASPStatement).Conditions.GetCallPolicy() - if callPolicy != v4MedPolicy { - t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v4MedPolicy) - } - t.Log("Nested policy 'v4MedPolicy' verified successfully") -} - -// verifyNestedImportPolicyAttachedv6 verifies on dut for IPV6 BGP parent import policy v6LPPolicy has a child policy attached. -func (td *testData) verifyNestedImportPolicyAttachedv6(t *testing.T) { - rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v6LPPolicy).State() - subResponse := gnmi.Get(t, td.dut, rpDefPath) - callPolicy := subResponse.GetStatement(v6LPStatement).Conditions.GetCallPolicy() - if callPolicy != v6PrefixPolicy { - t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v6PrefixPolicy) - } - t.Log("Nested policy 'v6PrefixPolicy' verified successfully") -} - -// verifyNestedExportPolicyAttachedv6 verifies on dut for IPV6 BGP parent export policy v6ASPPolicy has a child policy attached. -func (td *testData) verifyNestedExportPolicyAttachedv6(t *testing.T) { - rpDefPath := gnmi.OC().RoutingPolicy().PolicyDefinition(v6ASPPolicy).State() - subResponse := gnmi.Get(t, td.dut, rpDefPath) - callPolicy := subResponse.GetStatement(v6ASPStatement).Conditions.GetCallPolicy() - if callPolicy != v6MedPolicy { - t.Fatalf("Incorrect nested policy. got: %s, want: %s", callPolicy, v6MedPolicy) - } - t.Log("Nested policy 'v6MedPolicy' verified successfully") -} - func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { t.Helper() p1 := dut.Port(t, "port1") From c13a18cd41a3456164541aeff1fafff81f3de583 Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Tue, 2 Apr 2024 12:29:33 +0530 Subject: [PATCH 63/97] Remove the deletion of vrf selection policy parent OC path in the API used for creating dcGate policies (#2870) --- .../base_hierarchical_route_installation_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go b/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go index 2d076e71219..6b7b4eb0003 100644 --- a/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go +++ b/feature/gribi/otg_tests/base_hierarchical_route_installation_test/base_hierarchical_route_installation_test.go @@ -175,11 +175,6 @@ func configNonDefaultNetworkInstance(t *testing.T, dut *ondatra.DUTDevice) { } } -func deleteVrfSelectionPolicy(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - gnmi.Delete(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Config()) -} - type policyFwRule struct { SeqId uint32 protocol oc.UnionUint8 @@ -624,7 +619,6 @@ func testRecursiveIPv4EntrywithVrfPolW(t *testing.T, args *testArgs) { } t.Log("Delete existing vrf selection policy and Apply vrf selectioin policy W") configNonDefaultNetworkInstance(t, args.dut) - deleteVrfSelectionPolicy(t, args.dut) configureVrfSelectionPolicyW(t, args.dut) t.Logf("Adding IP %v with NHG %d NH %d with IP %v as NH via gRIBI", ateIndirectNH, nhgIndex2, nhIndex2, atePort2.IPv4) From f402fb03d891fd68e5567e9074324757063d046c Mon Sep 17 00:00:00 2001 From: Rohit Rattan Date: Tue, 2 Apr 2024 13:53:04 +0530 Subject: [PATCH 64/97] Optimizing flows, validation and fixing bugs (#2871) * optimizing flows and validation * removing addpath and fixing a bug --- .../community_test/community_test.go | 97 ++++++++++--------- internal/cfgplugins/bgp.go | 6 +- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/community_test/community_test.go b/feature/bgp/policybase/otg_tests/community_test/community_test.go index 01a2f5b9c14..1086a26b0f7 100644 --- a/feature/bgp/policybase/otg_tests/community_test/community_test.go +++ b/feature/bgp/policybase/otg_tests/community_test/community_test.go @@ -15,6 +15,7 @@ package community_test import ( + "strconv" "testing" "time" @@ -45,9 +46,9 @@ var prefixesV4 = [][]string{ var prefixesV6 = [][]string{ {"2048:db1:64:64::0", "2048:db1:64:64::4"}, - {"2048:db1:64:64::8", "2048:db1:64:64::12"}, - {"2048:db1:64:64::16", "2048:db1:64:64::20"}, - {"2048:db1:64:64::24", "2048:db1:64:64::28"}, + {"2048:db1:64:64::8", "2048:db1:64:64::c"}, + {"2048:db1:64:64::10", "2048:db1:64:64::14"}, + {"2048:db1:64:64::18", "2048:db1:64:64::1c"}, } func TestMain(m *testing.M) { @@ -65,11 +66,14 @@ func configureImportBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) communitySet := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(communitySetName) + + cs := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} for _, commMatch := range communityMatch { if commMatch != "" { - communitySet.SetCommunityMember([]oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{oc.UnionString(commMatch)}) + cs = append(cs, oc.UnionString(commMatch)) } } + communitySet.SetCommunityMember(cs) communitySet.SetMatchSetOptions(matchSetOptions) if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { @@ -83,13 +87,13 @@ func configureImportBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, dni := deviations.DefaultNetworkInstance(dut) pathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() policyV6 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() - policyV6.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + // policyV6.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policyV6.SetImportPolicy([]string{"routePolicy"}) gnmi.Replace(t, dut, pathV6.Config(), policyV6) pathV4 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() policyV4 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() - policyV4.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + // policyV4.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) policyV4.SetImportPolicy([]string{"routePolicy"}) gnmi.Replace(t, dut, pathV4.Config(), policyV4) } @@ -100,23 +104,23 @@ func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string ipv4 := devices[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0] bgp4Peer := devices[1].Bgp().Ipv4Interfaces().Items()[0].Peers().Items()[0] - bgp4PeerRoute := bgp4Peer.V4Routes().Add() - bgp4PeerRoute.SetName(bs.ATEPorts[1].Name + ".BGP4.peer.dut") - bgp4PeerRoute.SetNextHopIpv4Address(ipv4.Address()) - ipv6 := devices[1].Ethernets().Items()[0].Ipv6Addresses().Items()[0] bgp6Peer := devices[1].Bgp().Ipv6Interfaces().Items()[0].Peers().Items()[0] - bgp6PeerRoute := bgp6Peer.V6Routes().Add() - bgp6PeerRoute.SetName(bs.ATEPorts[1].Name + ".BGP6.peer.dut") - bgp6PeerRoute.SetNextHopIpv6Address(ipv6.Address()) - for index, prefixes := range prefixesV4 { + bgp4PeerRoute := bgp4Peer.V4Routes().Add() + bgp4PeerRoute.SetName(bs.ATEPorts[1].Name + ".BGP4.peer.dut." + strconv.Itoa(index)) + bgp4PeerRoute.SetNextHopIpv4Address(ipv4.Address()) + route4Address1 := bgp4PeerRoute.Addresses().Add().SetAddress(prefixes[0]) route4Address1.SetPrefix(prefixV4Len) route4Address2 := bgp4PeerRoute.Addresses().Add().SetAddress(prefixes[1]) route4Address2.SetPrefix(prefixV4Len) + bgp6PeerRoute := bgp6Peer.V6Routes().Add() + bgp6PeerRoute.SetName(bs.ATEPorts[1].Name + ".BGP6.peer.dut." + strconv.Itoa(index)) + bgp6PeerRoute.SetNextHopIpv6Address(ipv6.Address()) + route6Address1 := bgp6PeerRoute.Addresses().Add().SetAddress(prefixesV6[index][0]) route6Address1.SetPrefix(prefixV6Len) route6Address2 := bgp6PeerRoute.Addresses().Add().SetAddress(prefixesV6[index][1]) @@ -138,24 +142,19 @@ func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string } } -func configureFlow(bs *cfgplugins.BGPSession, prefixPair []string, prefixType string) { - bs.ATETop.Flows().Clear() +func configureFlow(t *testing.T, bs *cfgplugins.BGPSession, prefixPair []string, prefixType string, index int) { - var rxNames []string - for i := 1; i < len(bs.ATEPorts); i++ { - rxNames = append(rxNames, bs.ATEPorts[i].Name+".BGP4.peer.dut") - } - flow := bs.ATETop.Flows().Add().SetName("flow") + flow := bs.ATETop.Flows().Add().SetName("flow" + prefixType + strconv.Itoa(index)) flow.Metrics().SetEnable(true) if prefixType == "ipv4" { flow.TxRx().Device(). - SetTxNames([]string{bs.ATEPorts[1].Name + ".IPv4"}). - SetRxNames(rxNames) + SetTxNames([]string{bs.ATEPorts[0].Name + ".IPv4"}). + SetRxNames([]string{bs.ATEPorts[1].Name + ".BGP4.peer.dut." + strconv.Itoa(index)}) } else { flow.TxRx().Device(). - SetTxNames([]string{bs.ATEPorts[1].Name + ".IPv6"}). - SetRxNames(rxNames) + SetTxNames([]string{bs.ATEPorts[0].Name + ".IPv6"}). + SetRxNames([]string{bs.ATEPorts[1].Name + ".BGP6.peer.dut." + strconv.Itoa(index)}) } flow.Duration().FixedPackets().SetPackets(totalPackets) @@ -167,18 +166,19 @@ func configureFlow(bs *cfgplugins.BGPSession, prefixPair []string, prefixType st if prefixType == "ipv4" { v4 := flow.Packet().Add().Ipv4() - v4.Src().SetValue(bs.ATEPorts[1].IPv4) + v4.Src().SetValue(bs.ATEPorts[0].IPv4) v4.Dst().SetValues(prefixPair) } else { v6 := flow.Packet().Add().Ipv6() - v6.Src().SetValue(bs.ATEPorts[1].IPv6) + v6.Src().SetValue(bs.ATEPorts[0].IPv6) v6.Dst().SetValues(prefixPair) } } -func verifyTraffic(t *testing.T, ate *ondatra.ATEDevice, ports int, testResults bool) { - framesTx := gnmi.Get[uint64](t, ate.OTG(), gnmi.OTG().Port(ate.Port(t, "port1").ID()).Counters().OutFrames().State()) - framesRx := gnmi.Get[uint64](t, ate.OTG(), gnmi.OTG().Port(ate.Port(t, "port2").ID()).Counters().InFrames().State()) +func verifyTraffic(t *testing.T, ate *ondatra.ATEDevice, prefixType string, testResults bool, index int) { + recvMetric := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow("flow"+prefixType+strconv.Itoa(index)).State()) + framesTx := recvMetric.GetCounters().GetOutPkts() + framesRx := recvMetric.GetCounters().GetInPkts() if framesTx == 0 { t.Error("No traffic was generated and frames transmitted were 0") @@ -209,10 +209,10 @@ func TestCommunitySet(t *testing.T) { {100, 1}, {101, 1}, {200, 2}, }, { - {109, 1}, + {107, 1}, {108, 1}, {109, 1}, }, { - {400, 1}, + {400, 1}, {500, 1}, {600, 1}, }, } @@ -261,25 +261,26 @@ func TestCommunitySet(t *testing.T) { t.Run(tc.desc, func(t *testing.T) { configureImportBGPPolicy(t, bs.DUT, ipv4, ipv6, tc.communitySetName, tc.communityMatch, tc.matchSetOptions) - sleepTime := time.Duration(totalPackets/trafficPps) + 5 + sleepTime := time.Duration(totalPackets/trafficPps) + 2 + bs.ATETop.Flows().Clear() for index, prefixPairV4 := range prefixesV4 { + configureFlow(t, bs, prefixPairV4, "ipv4", index) + configureFlow(t, bs, prefixesV6[index], "ipv6", index) + } + bs.PushAndStartATE(t) - t.Logf("Running traffic test for IPv4 prefixes: [%s, %s]. Expected Result: [%t]", prefixPairV4[0], prefixPairV4[1], tc.testResults[index]) - configureFlow(bs, prefixPairV4, "ipv4") - bs.ATE.OTG().StartTraffic(t) - time.Sleep(sleepTime * time.Second) - bs.ATE.OTG().StopTraffic(t) - otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) - verifyTraffic(t, bs.ATE, int(cfgplugins.PortCount2), tc.testResults[index]) - - t.Logf("Running traffic test for IPv6 prefixes: [%s, %s]. Expected Result: [%t]", prefixesV6[index][0], prefixesV6[index][1], tc.testResults[index]) - configureFlow(bs, prefixesV6[index], "ipv6") - bs.ATE.OTG().StartTraffic(t) - time.Sleep(sleepTime * time.Second) - bs.ATE.OTG().StopTraffic(t) - otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) - verifyTraffic(t, bs.ATE, int(cfgplugins.PortCount2), tc.testResults[index]) + t.Logf("Starting traffic for IPv4 and v6") + bs.ATE.OTG().StartTraffic(t) + time.Sleep(sleepTime * time.Second) + bs.ATE.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + + for index, prefixPairV4 := range prefixesV4 { + t.Logf("Validating traffic test for IPv4 prefixes: [%s, %s]. Expected Result: [%t]", prefixPairV4[0], prefixPairV4[1], tc.testResults[index]) + verifyTraffic(t, bs.ATE, "ipv4", tc.testResults[index], index) + t.Logf("Validating traffic test for IPv6 prefixes: [%s, %s]. Expected Result: [%t]", prefixesV6[index][0], prefixesV6[index][1], tc.testResults[index]) + verifyTraffic(t, bs.ATE, "ipv6", tc.testResults[index], index) } }) } diff --git a/internal/cfgplugins/bgp.go b/internal/cfgplugins/bgp.go index 62f00216b0e..0a72d34e13b 100644 --- a/internal/cfgplugins/bgp.go +++ b/internal/cfgplugins/bgp.go @@ -229,16 +229,14 @@ func (bs *BGPSession) WithEBGP(t *testing.T, afiTypes []oc.E_BgpTypes_AFI_SAFI_T bgp4Peer.SetPeerAddress(ipv4.Gateway()) bgp4Peer.SetAsNumber(uint32(asNumbers[i])) bgp4Peer.SetAsType(gosnappi.BgpV4PeerAsType.EBGP) - bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) - bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) case oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: ipv6 := devices[i].Ethernets().Items()[0].Ipv6Addresses().Items()[0] bgp6Peer := bgp.Ipv6Interfaces().Add().SetIpv6Name(ipv6.Name()).Peers().Add().SetName(devices[i].Name() + ".BGP6.peer") bgp6Peer.SetPeerAddress(ipv6.Gateway()) bgp6Peer.SetAsNumber(uint32(asNumbers[i])) bgp6Peer.SetAsType(gosnappi.BgpV6PeerAsType.EBGP) - bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true).SetExtendedNextHopEncoding(true) - bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + bgp6Peer.LearnedInformationFilter().SetUnicastIpv6Prefix(true) } } } From 0e10ba80197e67f3496e94e1c7311879beea59c1 Mon Sep 17 00:00:00 2001 From: Mohana Date: Wed, 3 Apr 2024 00:15:37 -0700 Subject: [PATCH 65/97] RT-1.28, RT-1.30: Added peer-group for BGP peer and deviation for ISIS enabled (#2827) * Added peer-group for BGP peer and deviation for ISIS enabled * Added peer-group for BGP neighbor --------- Co-authored-by: Swetha-haridasula --- .../bgp_isis_redistribution_test.go | 8 ++++++++ .../bgp_isis_redistribution_test/metadata.textproto | 8 ++++++++ .../otg_tests/nested_policies/nested_policies_test.go | 10 ++++++++++ 3 files changed, 26 insertions(+) diff --git a/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go b/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go index 4778afbec5b..c4430ea1534 100644 --- a/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go +++ b/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/bgp_isis_redistribution_test.go @@ -59,6 +59,8 @@ const ( v6PrefixSet = "prefix-set-v6" v6FlowName = "flow-v6" v6CommunitySet = "community-set-v6" + peerGrpNamev4 = "BGP-PEER-GROUP-V4" + peerGrpNamev6 = "BGP-PEER-GROUP-V6" ) var ( @@ -214,13 +216,19 @@ func setupEBGPAndAdvertise(t *testing.T, ts *isissession.TestSession) { g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + pgv4 := bgp.GetOrCreatePeerGroup(peerGrpNamev4) + pgv4.PeerGroupName = ygot.String(peerGrpNamev4) + pgv6 := bgp.GetOrCreatePeerGroup(peerGrpNamev6) + pgv6.PeerGroupName = ygot.String(peerGrpNamev6) nV4 := bgp.GetOrCreateNeighbor(isissession.ATETrafficAttrs.IPv4) nV4.SetPeerAs(ateAS) nV4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV4.PeerGroup = ygot.String(peerGrpNamev4) nV6 := bgp.GetOrCreateNeighbor(isissession.ATETrafficAttrs.IPv6) nV6.SetPeerAs(ateAS) nV6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nV6.PeerGroup = ygot.String(peerGrpNamev6) gnmi.Update(t, ts.DUT, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(ts.DUT)).Config(), dni) // setup eBGP on ATE port2 diff --git a/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/metadata.textproto b/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/metadata.textproto index e8a6d9696ba..a87078e24c0 100644 --- a/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/metadata.textproto +++ b/feature/bgp/bgp_isis_redistribution/otg_tests/bgp_isis_redistribution_test/metadata.textproto @@ -24,3 +24,11 @@ platform_exceptions: { bgp_conditions_match_community_set_unsupported: true } } +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + isis_level_enabled: true + } +} diff --git a/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go b/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go index 89b29749541..d787c209d6e 100644 --- a/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go +++ b/feature/bgp/policybase/otg_tests/nested_policies/nested_policies_test.go @@ -74,6 +74,8 @@ const ( v6ASPStatement = "asp-statement-v6" v6MedPolicy = "med-policy-v6" v6MedStatement = "med-statement-v6" + peerGrpNamev4 = "BGP-PEER-GROUP-V4" + peerGrpNamev6 = "BGP-PEER-GROUP-V6" ) var ( @@ -591,19 +593,27 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) g.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + pgv4 := bgp.GetOrCreatePeerGroup(peerGrpNamev4) + pgv4.PeerGroupName = ygot.String(peerGrpNamev4) + pgv6 := bgp.GetOrCreatePeerGroup(peerGrpNamev6) + pgv6.PeerGroupName = ygot.String(peerGrpNamev6) nV41 := bgp.GetOrCreateNeighbor(atePort1.IPv4) nV41.SetPeerAs(ateAS1) nV41.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV41.PeerGroup = ygot.String(peerGrpNamev4) nV42 := bgp.GetOrCreateNeighbor(atePort2.IPv4) nV42.SetPeerAs(ateAS2) nV42.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nV42.PeerGroup = ygot.String(peerGrpNamev4) nV61 := bgp.GetOrCreateNeighbor(atePort1.IPv6) nV61.SetPeerAs(ateAS1) nV61.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nV61.PeerGroup = ygot.String(peerGrpNamev6) nV62 := bgp.GetOrCreateNeighbor(atePort2.IPv6) nV62.SetPeerAs(ateAS2) nV62.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nV62.PeerGroup = ygot.String(peerGrpNamev6) gnmi.Update(t, td.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(td.dut)).Config(), ni) // Configure eBGP on OTG port1. From bc37772def113e682052073c87a1bb8c8094483c Mon Sep 17 00:00:00 2001 From: arvbaska1 <123760606+arvbaska1@users.noreply.github.com> Date: Wed, 3 Apr 2024 09:51:02 -0400 Subject: [PATCH 66/97] changing static arp config after intf config (#2802) --- .../ipv4_entry_with_aggregate_ports_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/ipv4_entry_with_aggregate_ports_test.go b/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/ipv4_entry_with_aggregate_ports_test.go index bb81fb2e943..7e8bdaf7c50 100644 --- a/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/ipv4_entry_with_aggregate_ports_test.go +++ b/feature/gribi/otg_tests/ipv4_entry_with_aggregate_ports_test/ipv4_entry_with_aggregate_ports_test.go @@ -407,14 +407,6 @@ func configureDUTBundle(t *testing.T, dut *ondatra.DUTDevice, aggPorts []*ondatr agg.GetOrCreateAggregation().LagType = oc.IfAggregate_AggregationType_STATIC gnmi.Replace(t, dut, gnmi.OC().Interface(aggID).Config(), agg) - // Static ARP configuration with neighbor IP as nh1IPAddr - if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) || deviations.GRIBIMACOverrideWithStaticARP(dut) { - ipv4 := agg.GetOrCreateSubinterface(0).GetOrCreateIpv4() - n4 := ipv4.GetOrCreateNeighbor(nh1IpAddr) - n4.LinkLayerAddress = ygot.String(staticDstMAC) - gnmi.Replace(t, dut, gnmi.OC().Interface(aggID).Config(), agg) - } - for _, port := range aggPorts { d := &oc.Root{} i := d.GetOrCreateInterface(port.Name()) @@ -426,6 +418,14 @@ func configureDUTBundle(t *testing.T, dut *ondatra.DUTDevice, aggPorts []*ondatr } gnmi.Replace(t, dut, gnmi.OC().Interface(port.Name()).Config(), i) } + + // Static ARP configuration with neighbor IP as nh1IPAddr + if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) || deviations.GRIBIMACOverrideWithStaticARP(dut) { + ipv4 := agg.GetOrCreateSubinterface(0).GetOrCreateIpv4() + n4 := ipv4.GetOrCreateNeighbor(nh1IpAddr) + n4.LinkLayerAddress = ygot.String(staticDstMAC) + gnmi.Replace(t, dut, gnmi.OC().Interface(aggID).Config(), agg) + } } // awaitTimeout calls a fluent client Await, adding a timeout to the context. From a5554eead305fd7a2cf96422defc2b80f685ce38 Mon Sep 17 00:00:00 2001 From: prakashbadri-arista <127355794+prakashbadri-arista@users.noreply.github.com> Date: Wed, 3 Apr 2024 20:37:13 -0700 Subject: [PATCH 67/97] Fix RT-7.1: BGP default policies test failure for Arista (#2873) The test was failing for the following reasons - Arista specific deviations were not getting applied when configuring ISIS - BGP neighbors were flapping because the OTG was sending update messages with pathId not set in the BGP NLRI even though add path capability was negotiated in the test Have fixed both the issues and it is passing now Co-authored-by: anksaiki --- .../bgp_default_policies_test.go | 20 +++++++++++++++++++ .../default_policies_test/metadata.textproto | 3 +++ 2 files changed, 23 insertions(+) diff --git a/feature/bgp/policybase/otg_tests/default_policies_test/bgp_default_policies_test.go b/feature/bgp/policybase/otg_tests/default_policies_test/bgp_default_policies_test.go index 74ae5be5c6f..e0465b1344a 100644 --- a/feature/bgp/policybase/otg_tests/default_policies_test/bgp_default_policies_test.go +++ b/feature/bgp/policybase/otg_tests/default_policies_test/bgp_default_policies_test.go @@ -352,10 +352,13 @@ func configureOTG(t *testing.T, otg *otg.OTG) { SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) bgpNeti1Bgp4PeerRoutes.Addresses().Add(). SetAddress(ipv4Prefix1).SetPrefix(32) + bgpNeti1Bgp4PeerRoutes.AddPath().SetPathId(1) bgpNeti1Bgp4PeerRoutes.Addresses().Add(). SetAddress(ipv4Prefix2).SetPrefix(32) + bgpNeti1Bgp4PeerRoutes.AddPath().SetPathId(1) bgpNeti1Bgp4PeerRoutes.Addresses().Add(). SetAddress(ipv4Prefix3).SetPrefix(32) + bgpNeti1Bgp4PeerRoutes.AddPath().SetPathId(1) // eBGP V6 routes from Port1. bgpNeti1Bgp6PeerRoutes := iDut1Bgp6Peer.V6Routes().Add().SetName(atePort1.Name + ".BGP6.Route") @@ -364,10 +367,13 @@ func configureOTG(t *testing.T, otg *otg.OTG) { SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) bgpNeti1Bgp6PeerRoutes.Addresses().Add(). SetAddress(ipv6Prefix1).SetPrefix(128) + bgpNeti1Bgp6PeerRoutes.AddPath().SetPathId(1) bgpNeti1Bgp6PeerRoutes.Addresses().Add(). SetAddress(ipv6Prefix2).SetPrefix(128) + bgpNeti1Bgp6PeerRoutes.AddPath().SetPathId(1) bgpNeti1Bgp6PeerRoutes.Addresses().Add(). SetAddress(ipv6Prefix3).SetPrefix(128) + bgpNeti1Bgp6PeerRoutes.AddPath().SetPathId(1) // iBGP V4 routes from Port2. bgpNeti2Bgp4PeerRoutes := iDut2Bgp4Peer.V4Routes().Add().SetName(atePort2.Name + ".BGP4.Route") @@ -376,10 +382,13 @@ func configureOTG(t *testing.T, otg *otg.OTG) { SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) bgpNeti2Bgp4PeerRoutes.Addresses().Add(). SetAddress(ipv4Prefix4).SetPrefix(32) + bgpNeti2Bgp4PeerRoutes.AddPath().SetPathId(1) bgpNeti2Bgp4PeerRoutes.Addresses().Add(). SetAddress(ipv4Prefix5).SetPrefix(32) + bgpNeti2Bgp4PeerRoutes.AddPath().SetPathId(1) bgpNeti2Bgp4PeerRoutes.Addresses().Add(). SetAddress(ipv4Prefix6).SetPrefix(32) + bgpNeti2Bgp4PeerRoutes.AddPath().SetPathId(1) // iBGP V6 routes from Port2. bgpNeti2Bgp6PeerRoutes := iDut2Bgp6Peer.V6Routes().Add().SetName(atePort2.Name + ".BGP6.Route") @@ -388,10 +397,13 @@ func configureOTG(t *testing.T, otg *otg.OTG) { SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) bgpNeti2Bgp6PeerRoutes.Addresses().Add(). SetAddress(ipv6Prefix4).SetPrefix(128) + bgpNeti2Bgp6PeerRoutes.AddPath().SetPathId(1) bgpNeti2Bgp6PeerRoutes.Addresses().Add(). SetAddress(ipv6Prefix5).SetPrefix(128) + bgpNeti2Bgp6PeerRoutes.AddPath().SetPathId(1) bgpNeti2Bgp6PeerRoutes.Addresses().Add(). SetAddress(ipv6Prefix6).SetPrefix(128) + bgpNeti2Bgp6PeerRoutes.AddPath().SetPathId(1) t.Logf("Pushing config to OTG and starting protocols...") otg.PushConfig(t, config) @@ -468,6 +480,7 @@ func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfName []string, dutA globalISIS.LevelCapability = oc.Isis_LevelType_LEVEL_2 globalISIS.Net = []string{fmt.Sprintf("%v.%v.00", dutAreaAddress, dutSysID)} globalISIS.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + globalISIS.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) if deviations.ISISInstanceEnabledRequired(dut) { globalISIS.Instance = ygot.String(isisInstance) } @@ -486,6 +499,12 @@ func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfName []string, dutA isisIntfLevelAfi := isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST) isisIntfLevelAfi.Metric = ygot.Uint32(200) isisIntfLevelAfi.Enabled = ygot.Bool(true) + if deviations.ISISInterfaceAfiUnsupported(dut) { + isisIntf.Af = nil + } + if deviations.MissingIsisInterfaceAfiSafiEnable(dut) { + isisIntfLevelAfi.Enabled = nil + } } gnmi.Replace(t, dut, dutConfIsisPath.Config(), prot) } @@ -798,6 +817,7 @@ func TestBGPDefaultPolicies(t *testing.T) { t.Run("Verify BGP session telemetry", func(t *testing.T) { verifyBgpTelemetry(t, dut) }) + t.Run("Verify BGP capabilities", func(t *testing.T) { verifyBGPCapabilities(t, dut) }) diff --git a/feature/bgp/policybase/otg_tests/default_policies_test/metadata.textproto b/feature/bgp/policybase/otg_tests/default_policies_test/metadata.textproto index 7e05dc47964..a2f6c21c4cd 100644 --- a/feature/bgp/policybase/otg_tests/default_policies_test/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/default_policies_test/metadata.textproto @@ -21,6 +21,9 @@ platform_exceptions: { deviations: { interface_enabled: true default_network_instance: "default" + missing_isis_interface_afi_safi_enable: true + isis_interface_afi_unsupported: true + isis_instance_enabled_required: true } } platform_exceptions: { From b352e78759f06a50a89cf991ded42f2e088a9c24 Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Thu, 4 Apr 2024 12:36:21 -0700 Subject: [PATCH 68/97] Update to Ondatra v0.5.6 (#2874) * Update to Ondatra v0.5.6 * Fix staticcheck errors on deprecated funcs. --- .../tls_authentication_over_grpc_test.go | 9 ++- go.mod | 35 ++++++----- go.sum | 60 ++++++++++++------- internal/check/check_test.go | 4 +- internal/cntrsrv/cntrsrv.go | 3 +- internal/cntrsrv/cntrsrv_test.go | 12 ++-- topologies/binding/binding.go | 1 + 7 files changed, 69 insertions(+), 55 deletions(-) diff --git a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go b/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go index 82508df4950..8581b9ed14c 100644 --- a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go +++ b/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go @@ -50,9 +50,8 @@ func keyboardInteraction(password string) ssh.KeyboardInteractiveChallenge { } } -func gnmiClient(ctx context.Context, dut *ondatra.DUTDevice, gnmiAddr string) (gpb.GNMIClient, error) { - conn, err := grpc.DialContext( - ctx, +func gnmiClient(dut *ondatra.DUTDevice, gnmiAddr string) (gpb.GNMIClient, error) { + conn, err := grpc.NewClient( gnmiAddr, grpc.WithTransportCredentials( credentials.NewTLS(&tls.Config{ @@ -60,7 +59,7 @@ func gnmiClient(ctx context.Context, dut *ondatra.DUTDevice, gnmiAddr string) (g })), ) if err != nil { - return nil, fmt.Errorf("grpc.DialContext => unexpected failure dialing GNMI (should not require auth): %w", err) + return nil, fmt.Errorf("grpc.NewClient => unexpected failure dialing GNMI (should not require auth): %w", err) } return gpb.NewGNMIClient(conn), nil } @@ -240,7 +239,7 @@ func TestAuthentication(t *testing.T) { context.Background(), "username", tc.user, "password", tc.pass) - gnmi, err := gnmiClient(ctx, dut, gnmiAddr) + gnmi, err := gnmiClient(dut, gnmiAddr) if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 54475cf8beb..5f0d029e085 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/openconfig/featureprofiles go 1.21 require ( - cloud.google.com/go/pubsub v1.34.0 + cloud.google.com/go/pubsub v1.36.1 cloud.google.com/go/storage v1.36.0 github.com/cisco-open/go-p4 v0.1.2 github.com/go-git/go-billy/v5 v5.5.0 @@ -15,7 +15,7 @@ require ( github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/kr/pretty v0.3.1 - github.com/open-traffic-generator/snappi/gosnappi v1.2.0 + github.com/open-traffic-generator/snappi/gosnappi v1.3.0 github.com/openconfig/entity-naming v0.0.0-20230912181021-7ac806551a31 github.com/openconfig/gnmi v0.11.0 github.com/openconfig/gnoi v0.4.0 @@ -27,7 +27,7 @@ require ( github.com/openconfig/gribigo v0.0.0-20231213034307-d0abeba7f432 github.com/openconfig/kne v0.1.17 github.com/openconfig/models-ci v1.0.2-0.20231113233730-f0986391428e - github.com/openconfig/ondatra v0.5.5 + github.com/openconfig/ondatra v0.5.6 github.com/openconfig/replayer v0.0.0-20240110192655-4e9cf83d8d30 github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 github.com/openconfig/ygnmi v0.11.1 @@ -39,8 +39,8 @@ require ( golang.org/x/crypto v0.21.0 golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 golang.org/x/text v0.14.0 - google.golang.org/api v0.155.0 - google.golang.org/grpc v1.62.1 + google.golang.org/api v0.162.0 + google.golang.org/grpc v1.63.0 google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/klog/v2 v2.100.1 @@ -49,15 +49,15 @@ require ( require ( github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - golang.org/x/oauth2 v0.16.0 + golang.org/x/oauth2 v0.17.0 ) require ( bitbucket.org/creachadair/stringset v0.0.14 // indirect cloud.google.com/go v0.112.0 // indirect - cloud.google.com/go/compute v1.23.3 // indirect + cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.5 // indirect + cloud.google.com/go/iam v1.1.6 // indirect dario.cat/mergo v1.0.0 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/aristanetworks/arista-ceoslab-operator/v2 v2.0.2 // indirect @@ -66,7 +66,6 @@ require ( github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect github.com/creack/pty v1.1.18 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect @@ -80,7 +79,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -139,23 +138,23 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/mod v0.16.0 // indirect - golang.org/x/net v0.22.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.19.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index b7378eb1631..21b80a0a0b3 100644 --- a/go.sum +++ b/go.sum @@ -318,8 +318,9 @@ cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdi cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= cloud.google.com/go/compute v1.23.2/go.mod h1:JJ0atRC0J/oWYiiVBmsSsrRnh92DhZPG4hFDcR04Rns= -cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -626,8 +627,9 @@ cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+K cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8= -cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= @@ -666,8 +668,9 @@ cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w= cloud.google.com/go/kms v1.15.3/go.mod h1:AJdXqHxS2GlPyduM99s9iGqi2nwbviBbhV/hdmt4iOQ= cloud.google.com/go/kms v1.15.4/go.mod h1:L3Sdj6QTHK8dfwK5D1JLsAyELsNMnd3tAIwGS4ltKpc= -cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM= cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= +cloud.google.com/go/kms v1.15.7 h1:7caV9K3yIxvlQPAcaFffhlT7d1qpxjB1wHBtjWa13SM= +cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= @@ -871,8 +874,9 @@ cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9 cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= -cloud.google.com/go/pubsub v1.34.0 h1:ZtPbfwfi5rLaPeSvDC29fFoE20/tQvGrUS6kVJZJvkU= cloud.google.com/go/pubsub v1.34.0/go.mod h1:alj4l4rBg+N3YTFDDC+/YyFTs6JAjam2QfYsddcAW4c= +cloud.google.com/go/pubsub v1.36.1 h1:dfEPuGCHGbWUhaMCTHUFjfroILEkx55iUmKBZTP5f+Y= +cloud.google.com/go/pubsub v1.36.1/go.mod h1:iYjCa9EzWOoBiTdd4ps7QoMtMln5NwaZQpK1hbRfBDE= cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= @@ -1261,7 +1265,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= @@ -1364,8 +1367,9 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= @@ -1625,8 +1629,8 @@ github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/open-traffic-generator/keng-operator v0.3.15 h1:4qMC8MaCfV7TmmrfqI7rTusOChkHpiA8maih88aLaqY= github.com/open-traffic-generator/keng-operator v0.3.15/go.mod h1:+koaOnSyrJHdzxnaye+M6k+ZbszQlWI9u3tMxSpORNA= -github.com/open-traffic-generator/snappi/gosnappi v1.2.0 h1:yBKLr7mXnpvEE4cFwS7KeYXr1+xw7SL64XVY3mDhkuw= -github.com/open-traffic-generator/snappi/gosnappi v1.2.0/go.mod h1:CaE4nisXftNXdXWvTSqb4eiW2WMFIXkJsH5rqPoipcg= +github.com/open-traffic-generator/snappi/gosnappi v1.3.0 h1:6SFSuZLTuncLW1xMcBG5HEvVCWh9wVuxiYb71C3yj7s= +github.com/open-traffic-generator/snappi/gosnappi v1.3.0/go.mod h1:CaE4nisXftNXdXWvTSqb4eiW2WMFIXkJsH5rqPoipcg= github.com/openconfig/entity-naming v0.0.0-20230912181021-7ac806551a31 h1:K/9O+J20+liIof8WjquMydnebD0N1U9ItjhJYF6H4hg= github.com/openconfig/entity-naming v0.0.0-20230912181021-7ac806551a31/go.mod h1:ZRUrfwYYY+pLaOoWPad3p/8J4LLQcSqtXhBCkD2pXJc= github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= @@ -1662,8 +1666,8 @@ github.com/openconfig/lemming/operator v0.2.0 h1:dovZnR6lQkOHXcODli1NDOr/GVYrBY0 github.com/openconfig/lemming/operator v0.2.0/go.mod h1:LKgEXSR5VK2CAeh2uKijKAXFj42uQuwakrCHVPF0iII= github.com/openconfig/models-ci v1.0.2-0.20231113233730-f0986391428e h1:6N4jXpZa/SXYcNpJFjjZvenxO/xnTwuUCgCEinhNLfU= github.com/openconfig/models-ci v1.0.2-0.20231113233730-f0986391428e/go.mod h1:w38G/kObu95PbtwMYVp6SKhkHCegJFwL8B58Ns84g4s= -github.com/openconfig/ondatra v0.5.5 h1:X/NSZcI8SQ9uhSoB2rJkh29YvBnqNWiVVgFFlSyRnEE= -github.com/openconfig/ondatra v0.5.5/go.mod h1:hFxrMsLsOmvOzHeUDDJZcypenZIo6lt6NrPOdDmnHHM= +github.com/openconfig/ondatra v0.5.6 h1:1NkkmyPG8To5+aoAO1bIGEstfHB4My/Szc13IM+Kup8= +github.com/openconfig/ondatra v0.5.6/go.mod h1:hFxrMsLsOmvOzHeUDDJZcypenZIo6lt6NrPOdDmnHHM= github.com/openconfig/replayer v0.0.0-20240110192655-4e9cf83d8d30 h1:KcHS08m7nFHq/D03ZfZKKNCSaS1jsuvdF3lCyDjPWJc= github.com/openconfig/replayer v0.0.0-20240110192655-4e9cf83d8d30/go.mod h1:VQ8FdPVaHwxKtamhcrwkPsvTeeoEgFYNK1xE8nHD0S8= github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 h1:X631iD/B0ximGFb5P9LY5wHju4SiedxUhc5UZEo7VSw= @@ -1811,6 +1815,8 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.einride.tech/aip v0.66.0 h1:XfV+NQX6L7EOYK11yoHHFtndeaWh3KbD9/cN/6iWEt8= +go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1820,22 +1826,27 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -2015,8 +2026,8 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2051,8 +2062,9 @@ golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQ golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2377,8 +2389,9 @@ google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWL google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+viBk= google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg= -google.golang.org/api v0.155.0 h1:vBmGhCYs0djJttDNynWo44zosHlPvHmA0XiN2zP2DtA= google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk= +google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= +google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2548,8 +2561,9 @@ google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRx google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= @@ -2572,8 +2586,9 @@ google.golang.org/genproto/googleapis/api v0.0.0-20231211222908-989df2bf70f3/go. google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU= google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= @@ -2654,8 +2669,9 @@ google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSs google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= +google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/internal/check/check_test.go b/internal/check/check_test.go index 529b0512abf..c021aaf7629 100644 --- a/internal/check/check_test.go +++ b/internal/check/check_test.go @@ -62,9 +62,9 @@ func newFakeGNMI(ctx context.Context) (*fakeGNMI, error) { if err != nil { return nil, err } - conn, err := grpc.DialContext(ctx, agent.Address(), grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.NewClient(agent.Address(), grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { - return nil, fmt.Errorf("DialContext(%s): %w", agent.Address(), err) + return nil, fmt.Errorf("NewClient(%s): %w", agent.Address(), err) } client, err := ygnmi.NewClient(gpb.NewGNMIClient(conn)) diff --git a/internal/cntrsrv/cntrsrv.go b/internal/cntrsrv/cntrsrv.go index ed51d122ed2..bbbf4c2f47f 100644 --- a/internal/cntrsrv/cntrsrv.go +++ b/internal/cntrsrv/cntrsrv.go @@ -89,8 +89,7 @@ func (r *rpcCredentials) RequireTransportSecurity() bool { // Dial connects to the remote gRPC CNTR server hosted at the address in the request proto. func (c *C) Dial(ctx context.Context, req *cpb.DialRequest) (*cpb.DialResponse, error) { - conn, err := grpc.DialContext(ctx, req.GetAddr(), - grpc.WithBlock(), + conn, err := grpc.NewClient(req.GetAddr(), grpc.WithPerRPCCredentials(&rpcCredentials{}), grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ InsecureSkipVerify: true, // NOLINT diff --git a/internal/cntrsrv/cntrsrv_test.go b/internal/cntrsrv/cntrsrv_test.go index e4f41913aed..4c358180e88 100644 --- a/internal/cntrsrv/cntrsrv_test.go +++ b/internal/cntrsrv/cntrsrv_test.go @@ -39,11 +39,8 @@ import ( spb "github.com/openconfig/gribi/v1/proto/service" ) -func newClient(ctx context.Context, t *testing.T, port uint) (cpb.CntrClient, func()) { - ctx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - - conn, err := grpc.DialContext(ctx, fmt.Sprintf("localhost:%d", port), grpc.WithBlock(), +func newClient(t *testing.T, port uint) (cpb.CntrClient, func()) { + conn, err := grpc.NewClient(fmt.Sprintf("localhost:%d", port), grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ InsecureSkipVerify: true, // NOLINT }))) @@ -181,6 +178,9 @@ func TestDial(t *testing.T) { inServer: startServer, inServerPort: 60061, inReq: &cpb.DialRequest{ + Request: &cpb.DialRequest_Ping{ + Ping: &cpb.PingRequest{}, + }, Addr: "localhost:6666", }, wantErr: true, @@ -278,7 +278,7 @@ func TestDial(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - client, stopC := newClient(ctx, t, 60061) + client, stopC := newClient(t, 60061) defer stopC() got, err := client.Dial(ctx, tt.inReq) diff --git a/topologies/binding/binding.go b/topologies/binding/binding.go index 3cdbc8ef903..71f7c21c034 100644 --- a/topologies/binding/binding.go +++ b/topologies/binding/binding.go @@ -47,6 +47,7 @@ import ( var ( // To be stubbed out by unit tests. + //lint:ignore SA1019 DialContext allows for blocking on new connections. grpcDialContextFn = grpc.DialContext gosnappiNewAPIFn = gosnappi.NewApi ) From 74b6a6875905e1a5e0b17f69b2a80a8b58367b46 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Thu, 4 Apr 2024 21:39:52 -0700 Subject: [PATCH 69/97] Add yaml for OCPaths/RPC to test README (#2863) * Add yaml spec for oc path/rpc to featureprofiles README test-requirements-template --- doc/test-requirements-template.md | 54 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/doc/test-requirements-template.md b/doc/test-requirements-template.md index b42c08871ef..5b0f61e89e5 100644 --- a/doc/test-requirements-template.md +++ b/doc/test-requirements-template.md @@ -4,7 +4,6 @@ about: Use this template to document the requirements for a new test to be imple title: '' labels: enhancement assignees: '' - --- # Instructions for this template @@ -28,40 +27,39 @@ Write a few sentences or paragraphs describing the purpose and scope of the test ## Procedure +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + * TestID-x.y.z - Name of subtest * Step 1 * Step 2 - * Validation and pass fail criteria + * Validation and pass/fail criteria * TestID-x.y.z - Name of subtest * Step 1 * Step 2 - * Validation and pass fail criteria - -## Config Parameter Coverage - -Add list of OpenConfig 'config' paths used in this test, if any. - -## Telemetry Parameter Coverage - -Add list of OpenConfig 'state' paths used in this test, if any. - -## Protocol/RPC Parameter Coverage - -Add list of OpenConfig RPC's (gNMI, gNOI, gNSI, gRIBI) used in the list, if any. - -For example: - -* gNMI - * Set - * Subscribe -* gNOI - * System - * KillProcess - * Healthz - * Get - * Check - * Artifact + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +```yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +``` ## Required DUT platform From 54bd7080e75b4a6d1917febb5fc1a6a60885c71c Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Fri, 5 Apr 2024 11:15:50 +0530 Subject: [PATCH 70/97] fix med, local pref and as path prepend test (#2876) --- .../README.md | 312 ++---------------- ...s_MED_LocPref_prepend_flow_control_test.go | 293 ++++++---------- .../metadata.textproto | 1 + 3 files changed, 133 insertions(+), 473 deletions(-) rename feature/bgp/policybase/otg_tests/{actions_MED_LocPref_prepend_flow_control => actions_med_localpref_prepend_flow_control}/README.md (53%) rename feature/bgp/policybase/otg_tests/{actions_MED_LocPref_prepend_flow_control => actions_med_localpref_prepend_flow_control}/actions_MED_LocPref_prepend_flow_control_test.go (79%) rename feature/bgp/policybase/otg_tests/{actions_MED_LocPref_prepend_flow_control => actions_med_localpref_prepend_flow_control}/metadata.textproto (99%) diff --git a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/README.md b/feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/README.md similarity index 53% rename from feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/README.md rename to feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/README.md index 2efc3269fb3..d0cb2d10659 100644 --- a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/README.md +++ b/feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/README.md @@ -42,47 +42,6 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * Local Preference = 50 ### RT-1.32.1 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] -#### IPv4, IPv6 iBGP set MED ---- -##### Configure a route-policy to set MED -* Configure an route-policy definition with the name ```med-policy``` - * /routing-policy/policy-definitions/policy-definition/config/name -* For routing-policy ```med-policy``` configure a statement with the name ```match-statement-1``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```med-policy``` statement ```match-statement-1``` set policy-result as ```ACCEPT_ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```med-policy``` statement ```match-statement-1``` set MED as ```100``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med -##### Configure bgp import and export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-1 -* Set default import and export policy to `REJECT_ROUTE`. (Note: even though this is the OC default, the DUT should still accept this configuration) - - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Add `policy-definition["med-policy"]` to import-policy and export-policy leaf-lists. - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Configure default policies for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-2 -* Set default import and export policy to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -##### Verification -* Verify that policies are successfully applied to the DUT BGP neighbor on ATE Port-1 and default policies are set to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Verify that there are no policies applied to the DUT BGP neighbor on ATE Port-2 and default policies are set to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -#### Validate test results -* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 100 -* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 100 -* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 100 -* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 100 - -### RT-1.32.2 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] #### IPv4, IPv6 eBGP set MED --- ##### Configure a route-policy to set MED @@ -125,51 +84,7 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 100 * Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 100 -### RT-1.32.3 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] -#### IPv4, IPv6 iBGP increase MED ---- -##### Configure a route-policy to increase MED -* Configure an route-policy definition with the name ```med-policy``` - * /routing-policy/policy-definitions/policy-definition/config/name -* For routing-policy ```med-policy``` configure a statement with the name ```match-statement-1``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```med-policy``` statement ```match-statement-1``` set policy-result as ```ACCEPT_ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```med-policy``` statement ```match-statement-1``` set MED as ```+100``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med -##### Configure bgp import and export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-1 -* Set default import and export policy to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Add `policy-definition["med-policy"]` to import-policy and export-policy leaf-lists. -* ``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Configure default policies and remove any import, export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-2 -* Set default import and export policy to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Remove policy as import and export as a chain/list ```[med-policy]``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Verification -* Verify that policies are successfully applied to the DUT BGP neighbor on ATE Port-1 and default policies are set to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Verify that there is no policies applied to the DUT BGP neighbor on ATE Port-2 and default policies are set to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -#### Validate test results -* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-1 and it has MED == 150 -* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-1 and it has MED == 150 -* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-2 and it has MED == 150 -* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-2 and it has MED == 150 - -### RT-1.32.4 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] +### RT-1.32.2 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] #### IPv4, IPv6 eBGP increase MED --- ##### Configure a route-policy to increase MED @@ -212,7 +127,7 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 150 * Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 150 -### RT-1.32.5 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] +### RT-1.32.3 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] #### IPv4, IPv6 iBGP set Local Preference --- ##### Configure a route-policy to set Local Preference @@ -255,24 +170,29 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has LocPref == 100 * Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has LocPref == 100 - -### RT-1.32.6 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] -#### IPv4, IPv6 eBGP set Local Preference +### RT-1.32.4 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] +#### IPv4, IPv6 eBGP NEXT-STATEMENT --- -##### Configure a route-policy to set Local Preference -* Configure an route-policy definition with the name ```lp-policy``` +##### Configure a route-policy set MED, LocalPreferemce is separate statements +* Configure an route-policy definition with the name ```flow-control-policy``` * /routing-policy/policy-definitions/policy-definition/config/name -* For routing-policy ```lp-policy``` configure a statement with the name ```match-statement-1``` +* For routing-policy ```flow-control-policy``` configure a statement with the name ```match-statement-1``` * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```lp-policy``` statement ```match-statement-1``` set policy-result as ```ACCEPT_ROUTE``` +* For routing-policy ```flow-control-policy``` statement ```match-statement-1``` set policy-result as ```NEXT-STATEMENT``` * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```lp-policy``` statement ```match-statement-1``` set Local Preference as ```100``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-local-pref +* For routing-policy ```flow-control-policy``` statement ```match-statement-1``` set MED to 70 + * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med +* For routing-policy ```flow-control-policy``` configure a statement with the name ```match-statement-2``` + * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name +* For routing-policy ```flow-control-policy``` statement ```match-statement-2``` set policy-result as ```ACCEPT-ROUTE``` + * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result +* For routing-policy ```flow-control-policy``` statement ```match-statement-2``` prepend as-path with local ASN ```10``` times + * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n ##### Configure bgp import and export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-2 * Set default import and export policy to ```REJECT_ROUTE``` * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Add `policy-definition["lp-policy"]` to import-policy and export-policy leaf-lists. +* Apply as import and export only policy - ```[flow-control-policy]``` * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy ##### Configure default policies and remove any import, export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-1 @@ -294,55 +214,12 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy #### Validate test results -* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-2 and it has LocPref == 100 -* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-2 and it has LocPref == 100 -* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has LocPref == 100 -* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has LocPref == 100 - -### RT-1.32.7 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] -#### IPv4, IPv6 iBGP prepend 10 x local ASN ---- -##### Configure a route-policy to prepend 10 -* Configure an route-policy definition with the name ```prepend-policy``` - * /routing-policy/policy-definitions/policy-definition/config/name -* For routing-policy ```prepend-policy``` configure a statement with the name ```match-statement-1``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```prepend-policy``` statement ```match-statement-1``` set policy-result as ```ACCEPT_ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```prepend-policy``` statement ```match-statement-1``` prepend as-path with local ASN ```10``` times - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n -##### Configure bgp import and export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-1 -* Set default import and export policy to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Apply as import and export only policy - ```[prepend-policy]``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Configure default policies and remove any import, export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-2 -* Set default import and export policy to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Remove all import and export policies - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Verification -* Verify that policies are successfully applied to the DUT BGP neighbor on ATE Port-1 and default policies are set to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Verify that there is no policies applied to the DUT BGP neighbor on ATE Port-2 and default policies are set to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -#### Validate test results -* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-2 and it has 11 ASN on as-path. All equal to DUT's ASN. -* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-2 and it has 11 ASN on as-path. All equal to DUT's ASN. -* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equial to ATE port-2 ASN and other equal to DUT's ASN. -* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equial to ATE port-2 ASN and other equal to DUT's ASN. +* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 70 and it has 11 ASN on as-path. All equal to DUT's ASN. +* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 70 and it has 11 ASN on as-path. All equal to DUT's ASN. +* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 70 and it has 11 ASN on as-path. All equal to DUT's ASN. +* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 70 and it has 11 ASN on as-path. All equal to DUT's ASN. -### RT-1.32.8 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] +### RT-1.32.5 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] #### IPv4, IPv6 eBGP prepend 10 x local ASN --- ##### Configure a route-policy to prepend 10 @@ -385,51 +262,7 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equial to ATE port-2 ASN and other equal to DUT's ASN. * Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equial to ATE port-2 ASN and other equal to DUT's ASN. -### RT-1.32.9 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] -#### IPv4, IPv6 iBGP prepend 10 x ASN ---- -##### Configure a route-policy to prepend 10 -* Configure an route-policy definition with the name ```prepend-policy``` - * /routing-policy/policy-definitions/policy-definition/config/name -* For routing-policy ```prepend-policy``` configure a statement with the name ```match-statement-1``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```prepend-policy``` statement ```match-statement-1``` set policy-result as ```ACCEPT_ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```prepend-policy``` statement ```match-statement-1``` prepend as-path with ```23456``` ASN ```10``` times - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/asn -##### Configure bgp import and export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-1 -* Set default import and export policy to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Apply as import and export only policy - ```[prepend-policy]``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Configure default policies and remove any import, export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-2 -* Set default import and export policy to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Remove all import and export policies - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Verification -* Verify that policies are successfully applied to the DUT BGP neighbor on ATE Port-1 and default policies are set to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Verify that there is no policies applied to the DUT BGP neighbor on ATE Port-2 and default policies are set to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -#### Validate test results -* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-2 and it has 11 ASN on as-path. First 10 equal to ```23456``` and last equal to DUT's ASN. -* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-2 and it has 11 ASN on as-path. First 10 equal to ```23456``` and last equal to DUT's ASN. -* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equal to ATE port-2 ASN and other 10 equal to ```23456``` ASN. -* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equal to ATE port-2 ASN and other 10 equal to ```23456``` ASN. - -### RT-1.32.10 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] +### RT-1.32.6 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] #### IPv4, IPv6 eBGP prepend 10 x ASN --- ##### Configure a route-policy to prepend 10 @@ -473,104 +306,6 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c * Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equal to ATE port-2 ASN and other 10 equal to ```23456``` ASN. * Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has 11 ASN on as-path. First equal to ATE port-2 ASN and other 10 equal to ```23456``` ASN. -### RT-1.32.11 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] -#### IPv4, IPv6 iBGP NEXT-STATEMENT ---- -##### Configure a route-policy set MED, LocalPreferemce is separate statements -* Configure an route-policy definition with the name ```flow-control-policy``` - * /routing-policy/policy-definitions/policy-definition/config/name -* For routing-policy ```flow-control-policy``` configure a statement with the name ```match-statement-1``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```flow-control-policy``` statement ```match-statement-1``` set policy-result as ```NEXT-STATEMENT``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```flow-control-policy``` statement ```match-statement-1``` set MED to 70 - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med -* For routing-policy ```flow-control-policy``` configure a statement with the name ```match-statement-2``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```flow-control-policy``` statement ```match-statement-2``` set policy-result as ```ACCEPT-ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```flow-control-policy``` statement ```match-statement-2``` set LocalPreference to 70 - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-local-pref -##### Configure bgp import and export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-1 -* Set default import and export policy to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Apply as import and export only policy - ```[flow-control-policy]``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Configure default policies and remove any import, export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-2 -* Set default import and export policy to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Remove all import and export policies - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Verification -* Verify that policies are successfully applied to the DUT BGP neighbor on ATE Port-1 and default policies are set to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Verify that there is no policies applied to the DUT BGP neighbor on ATE Port-2 and default policies are set to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -#### Validate test results -* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 70. -* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 70. -* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 70 and Local Preference == 70. -* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 70 and Local Preference == 70. - -### RT-1.32.12 [TODO: https://github.com/openconfig/featureprofiles/issues/2615] -#### IPv4, IPv6 eBGP NEXT-STATEMENT ---- -##### Configure a route-policy set MED, LocalPreferemce is separate statements -* Configure an route-policy definition with the name ```flow-control-policy``` - * /routing-policy/policy-definitions/policy-definition/config/name -* For routing-policy ```flow-control-policy``` configure a statement with the name ```match-statement-1``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```flow-control-policy``` statement ```match-statement-1``` set policy-result as ```NEXT-STATEMENT``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```flow-control-policy``` statement ```match-statement-1``` set MED to 70 - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med -* For routing-policy ```flow-control-policy``` configure a statement with the name ```match-statement-2``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/config/name -* For routing-policy ```flow-control-policy``` statement ```match-statement-2``` set policy-result as ```ACCEPT-ROUTE``` - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result -* For routing-policy ```flow-control-policy``` statement ```match-statement-2``` set LocalPreference to 70 - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-local-pref -##### Configure bgp import and export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-2 -* Set default import and export policy to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Apply as import and export only policy - ```[flow-control-policy]``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Configure default policies and remove any import, export policy for the DUT IPv4 and IPv6 BGP neighbors on ATE Port-1 -* Set default import and export policy to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Remove all import and export policies - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy -##### Verification -* Verify that policies are successfully applied to the DUT BGP neighbor on ATE Port-2 and default policies are set to ```REJECT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -* Verify that there is no policies applied to the DUT BGP neighbor on ATE Port-1 and default policies are set to ```ACCEPT_ROUTE``` - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-import-policy - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/default-export-policy -#### Validate test results -* Validate that the ATE receives the prefix ```ipv4-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 70. -* Validate that the ATE receives the prefix ```ipv6-network-1``` from DUT neighbor on ATE Port-2 and it has MED == 70. -* Validate that the ATE receives the prefix ```ipv4-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 70 and Local Preference == 70. -* Validate that the ATE receives the prefix ```ipv6-network-2``` from DUT neighbor on ATE Port-1 and it has MED == 70 and Local Preference == 70. - ## Config parameter coverage * /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/config/ @@ -603,3 +338,4 @@ For each section of configuration below, prepare a gnmi.SetBatch with all the c ## Required DUT platform * FFF + diff --git a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go b/feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go similarity index 79% rename from feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go rename to feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go index 28cbe43c023..2ab76c4fb6c 100644 --- a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go +++ b/feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/actions_MED_LocPref_prepend_flow_control_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package actions_MED_LocPref_prepend_flow_control_test +package actions_med_localpref_prepend_flow_control_test import ( "strconv" @@ -67,6 +67,7 @@ const ( nxtLocalPref = 70 setNxtPolicy = "flow-control-policy" matchStatement2 = "match-statement-2" + asnRepeatN = 10 ) var ( @@ -249,12 +250,15 @@ func configureASLocalPrefMEDPolicy(t *testing.T, dut *ondatra.DUTDevice, policyT t.Fatal(err) } actions2 := stmt2.GetOrCreateActions() - actions2.GetOrCreateBgpActions().SetLocalPref = ygot.Uint32(uint32(metric)) + asPrepend := actions2.GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend() + asPrepend.Asn = ygot.Uint32(ASN) + asPrepend.RepeatN = ygot.Uint8(asnRepeatN) actions2.PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE default: rp = nil } gnmi.BatchReplace(batchConfig, gnmi.OC().RoutingPolicy().Config(), rp) + batchConfig.Set(t, dut) } // configureBGPDefaultImportExportPolicy configures default import/export policies @@ -371,15 +375,19 @@ func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { iDut1Bgp := iDut1Dev.Bgp().SetRouterId(iDut1Ipv4.Address()) iDut1Bgp4Peer := iDut1Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut1Ipv4.Name()).Peers().Add().SetName(atePort1.Name + ".BGP4.peer") iDut1Bgp4Peer.SetPeerAddress(iDut1Ipv4.Gateway()).SetAsNumber(dutAS).SetAsType(gosnappi.BgpV4PeerAsType.IBGP) + iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) iDut1Bgp6Peer := iDut1Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut1Ipv6.Name()).Peers().Add().SetName(atePort1.Name + ".BGP6.peer") iDut1Bgp6Peer.SetPeerAddress(iDut1Ipv6.Gateway()).SetAsNumber(dutAS).SetAsType(gosnappi.BgpV6PeerAsType.IBGP) + iDut1Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) // eBGP v4 and v6 sessions on port2 iDut2Bgp := iDut2Dev.Bgp().SetRouterId(iDut2Ipv4.Address()) iDut2Bgp4Peer := iDut2Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut2Ipv4.Name()).Peers().Add().SetName(atePort2.Name + ".BGP4.peer") iDut2Bgp4Peer.SetPeerAddress(iDut2Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut2Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) iDut2Bgp6Peer := iDut2Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut2Ipv6.Name()).Peers().Add().SetName(atePort2.Name + ".BGP6.peer") iDut2Bgp6Peer.SetPeerAddress(iDut2Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + iDut2Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) // iBGP V4 routes from Port1 and set MED, Local Preference. bgpNeti1Bgp4PeerRoutes := iDut1Bgp4Peer.V4Routes().Add().SetName(atePort1.Name + ".BGP4.Route") @@ -388,8 +396,8 @@ func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) bgpNeti1Bgp4PeerRoutes.Addresses().Add(). SetAddress(advertisedRoutesv4Net1).SetPrefix(advertisedRoutesv4PrefixLen) - bgpNeti1Bgp4PeerRoutes.Advanced().SetMultiExitDiscriminator(50) - bgpNeti1Bgp4PeerRoutes.Advanced().SetLocalPreference(50) + bgpNeti1Bgp4PeerRoutes.Advanced().SetIncludeMultiExitDiscriminator(true).SetMultiExitDiscriminator(50) + bgpNeti1Bgp4PeerRoutes.Advanced().SetIncludeLocalPreference(true).SetLocalPreference(50) // iBGP V6 routes from Port1 and set MED, Local Preference. bgpNeti1Bgp6PeerRoutes := iDut1Bgp6Peer.V6Routes().Add().SetName(atePort1.Name + ".BGP6.Route") @@ -398,8 +406,8 @@ func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) bgpNeti1Bgp6PeerRoutes.Addresses().Add(). SetAddress(advertisedRoutesv6Net1).SetPrefix(advertisedRoutesv6PrefixLen) - bgpNeti1Bgp6PeerRoutes.Advanced().SetMultiExitDiscriminator(50) - bgpNeti1Bgp6PeerRoutes.Advanced().SetLocalPreference(50) + bgpNeti1Bgp6PeerRoutes.Advanced().SetIncludeMultiExitDiscriminator(true).SetMultiExitDiscriminator(50) + bgpNeti1Bgp6PeerRoutes.Advanced().SetIncludeLocalPreference(true).SetLocalPreference(50) // eBGP V4 routes from Port2 and set MED, Local Preference. bgpNeti2Bgp4PeerRoutes := iDut2Bgp4Peer.V4Routes().Add().SetName(atePort2.Name + ".BGP4.Route") @@ -408,8 +416,8 @@ func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) bgpNeti2Bgp4PeerRoutes.Addresses().Add(). SetAddress(advertisedRoutesv4Net2).SetPrefix(advertisedRoutesv4PrefixLen) - bgpNeti2Bgp4PeerRoutes.Advanced().SetMultiExitDiscriminator(50) - bgpNeti2Bgp4PeerRoutes.Advanced().SetLocalPreference(50) + bgpNeti2Bgp4PeerRoutes.Advanced().SetIncludeMultiExitDiscriminator(true).SetMultiExitDiscriminator(50) + bgpNeti2Bgp4PeerRoutes.Advanced().SetIncludeLocalPreference(true).SetLocalPreference(50) // eBGP V6 routes from Port2 and set MED, Local Preference. bgpNeti2Bgp6PeerRoutes := iDut2Bgp6Peer.V6Routes().Add().SetName(atePort2.Name + ".BGP6.Route") @@ -418,8 +426,8 @@ func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) bgpNeti2Bgp6PeerRoutes.Addresses().Add(). SetAddress(advertisedRoutesv6Net2).SetPrefix(advertisedRoutesv6PrefixLen) - bgpNeti2Bgp6PeerRoutes.Advanced().SetMultiExitDiscriminator(50) - bgpNeti2Bgp6PeerRoutes.Advanced().SetLocalPreference(50) + bgpNeti2Bgp6PeerRoutes.Advanced().SetIncludeMultiExitDiscriminator(true).SetMultiExitDiscriminator(50) + bgpNeti2Bgp6PeerRoutes.Advanced().SetIncludeLocalPreference(true).SetLocalPreference(50) t.Logf("Pushing config to ATE and starting protocols...") otg.PushConfig(t, config) @@ -428,19 +436,19 @@ func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { } // validateOTGBgpPrefixV4AndASLocalPrefMED verifies that the IPv4 prefix is received on OTG. -func validateOTGBgpPrefixV4AndASLocalPrefMED(t *testing.T, otg *otg.OTG, config gosnappi.Config, peerName, ipAddr string, prefixLen uint32, pathAttr string, metric uint32) { - t.Helper() +func validateOTGBgpPrefixV4AndASLocalPrefMED(t *testing.T, otg *otg.OTG, dut *ondatra.DUTDevice, config gosnappi.Config, peerName, ipAddr string, prefixLen uint32, pathAttr string, metric uint32) { + // t.Helper() _, ok := gnmi.WatchAll(t, otg, gnmi.OTG().BgpPeer(peerName).UnicastIpv4PrefixAny().State(), - time.Minute, + 30*time.Second, func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { _, present := v.Val() return present }).Await(t) var foundPrefix = false if ok { - bgpPrefixes := gnmi.GetAll(t, otg, gnmi.OTG().BgpPeer(peerName).UnicastIpv4PrefixAny().State()) + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv4Prefix](t, otg, gnmi.OTG().BgpPeer(peerName).UnicastIpv4PrefixAny().State()) for _, bgpPrefix := range bgpPrefixes { if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == ipAddr && bgpPrefix.PrefixLength != nil && bgpPrefix.GetPrefixLength() == prefixLen { @@ -454,14 +462,10 @@ func validateOTGBgpPrefixV4AndASLocalPrefMED(t *testing.T, otg *otg.OTG, config t.Logf("For Prefix %v, got MED %d want MED %d", bgpPrefix.GetAddress(), bgpPrefix.GetMultiExitDiscriminator(), metric) } case setLocalPrefPolicy: - if bgpPrefix.GetLocalPreference() != metric { - t.Errorf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } else { - t.Logf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } + validateImportRoutingPolicy(t, dut, ipAddr, metric) case setPrependPolicy: - if len(bgpPrefix.AsPath) != int(metric) { - t.Errorf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath), int(metric)) + if len(bgpPrefix.AsPath[0].GetAsNumbers()) != int(metric) { + t.Errorf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath[0].GetAsNumbers()), int(metric)) } else { t.Logf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath), int(metric)) } @@ -471,12 +475,10 @@ func validateOTGBgpPrefixV4AndASLocalPrefMED(t *testing.T, otg *otg.OTG, config } else { t.Logf("For Prefix %v, got MED %d want MED %d", bgpPrefix.GetAddress(), bgpPrefix.GetMultiExitDiscriminator(), metric) } - if !strings.Contains(peerName, atePort2.Name) { - if bgpPrefix.GetLocalPreference() != metric { - t.Errorf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } else { - t.Logf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } + if len(bgpPrefix.AsPath[0].GetAsNumbers()) != asnRepeatN+1 { + t.Errorf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath[0].GetAsNumbers()), asnRepeatN+1) + } else { + t.Logf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath), asnRepeatN+1) } default: t.Errorf("Incorrect BGP Path Attribute. Expected MED, Local Pref or AS Path Prepend!!!!") @@ -491,19 +493,19 @@ func validateOTGBgpPrefixV4AndASLocalPrefMED(t *testing.T, otg *otg.OTG, config } // validateOTGBgpPrefixV6AndASLocalPrefMED verifies that the IPv6 prefix is received on OTG. -func validateOTGBgpPrefixV6AndASLocalPrefMED(t *testing.T, otg *otg.OTG, config gosnappi.Config, peerName, ipAddr string, prefixLen uint32, pathAttr string, metric uint32) { - t.Helper() +func validateOTGBgpPrefixV6AndASLocalPrefMED(t *testing.T, otg *otg.OTG, dut *ondatra.DUTDevice, config gosnappi.Config, peerName, ipAddr string, prefixLen uint32, pathAttr string, metric uint32) { + // t.Helper() _, ok := gnmi.WatchAll(t, otg, gnmi.OTG().BgpPeer(peerName).UnicastIpv6PrefixAny().State(), - time.Minute, + 30*time.Second, func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv6Prefix]) bool { _, present := v.Val() return present }).Await(t) var foundPrefix = false if ok { - bgpPrefixes := gnmi.GetAll(t, otg, gnmi.OTG().BgpPeer(peerName).UnicastIpv6PrefixAny().State()) + bgpPrefixes := gnmi.GetAll[*otgtelemetry.BgpPeer_UnicastIpv6Prefix](t, otg, gnmi.OTG().BgpPeer(peerName).UnicastIpv6PrefixAny().State()) for _, bgpPrefix := range bgpPrefixes { if bgpPrefix.Address != nil && bgpPrefix.GetAddress() == ipAddr && bgpPrefix.PrefixLength != nil && bgpPrefix.GetPrefixLength() == prefixLen { @@ -517,14 +519,10 @@ func validateOTGBgpPrefixV6AndASLocalPrefMED(t *testing.T, otg *otg.OTG, config t.Logf("For Prefix %v, got MED %d want MED %d", bgpPrefix.GetAddress(), bgpPrefix.GetMultiExitDiscriminator(), metric) } case setLocalPrefPolicy: - if bgpPrefix.GetLocalPreference() != metric { - t.Errorf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } else { - t.Logf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } + validateImportRoutingPolicyV6(t, dut, ipAddr, metric) case setPrependPolicy: - if len(bgpPrefix.AsPath) != int(metric) { - t.Errorf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath), int(metric)) + if len(bgpPrefix.AsPath[0].GetAsNumbers()) != int(metric) { + t.Errorf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath[0].GetAsNumbers()), int(metric)) } else { t.Logf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath), int(metric)) } @@ -534,12 +532,10 @@ func validateOTGBgpPrefixV6AndASLocalPrefMED(t *testing.T, otg *otg.OTG, config } else { t.Logf("For Prefix %v, got MED %d want MED %d", bgpPrefix.GetAddress(), bgpPrefix.GetMultiExitDiscriminator(), metric) } - if !strings.Contains(peerName, atePort2.Name) { - if bgpPrefix.GetLocalPreference() != metric { - t.Errorf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } else { - t.Logf("For Prefix %v, got Local Preference %d want Local Preference %d", bgpPrefix.GetAddress(), bgpPrefix.GetLocalPreference(), metric) - } + if len(bgpPrefix.AsPath[0].GetAsNumbers()) != asnRepeatN+1 { + t.Errorf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath[0].GetAsNumbers()), asnRepeatN+1) + } else { + t.Logf("For Prefix %v, got AS Path Prepend %d want AS Path Prepend %d", bgpPrefix.GetAddress(), len(bgpPrefix.AsPath), asnRepeatN+1) } default: t.Errorf("Incorrect Routing Policy. Expected MED, Local Pref or AS Path Prepend!!!!") @@ -600,26 +596,6 @@ func TestBGPPolicy(t *testing.T) { deleteNbrv4, deleteNbrv6 string polNbrv4, polNbrv6 string }{{ - desc: "Configure iBGP set MED Import Export Policy", - rpPolicy: setMEDPolicy, - policyTypePort1: setMEDPolicy, - policyValue: "100", - policyStatement: matchStatement1, - defPolicyPort1: defRejectRoute, - defPolicyPort2: defAcceptRoute, - policyTypePort2: "", - port1v4Prefix: advertisedRoutesv4Net2, - port1v6Prefix: advertisedRoutesv6Net2, - port2v4Prefix: advertisedRoutesv4Net1, - port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 100, - polNbrv4: atePort1.IPv4, - polNbrv6: atePort1.IPv6, - isDeletePolicy: false, - deleteNbrv4: "", - deleteNbrv6: "", - asn: dutAS, - }, { desc: "Configure eBGP set MED Import Export Policy", rpPolicy: setMEDPolicy, policyTypePort1: "", @@ -639,26 +615,6 @@ func TestBGPPolicy(t *testing.T) { deleteNbrv4: atePort1.IPv4, deleteNbrv6: atePort1.IPv6, asn: dutAS, - }, { - desc: "Configure iBGP increase MED Import Export Policy", - rpPolicy: setMEDPolicy, - policyTypePort1: setMEDPolicy, - policyValue: "+100", - policyStatement: matchStatement1, - defPolicyPort1: defRejectRoute, - defPolicyPort2: defAcceptRoute, - policyTypePort2: "", - port1v4Prefix: advertisedRoutesv4Net1, - port1v6Prefix: advertisedRoutesv6Net1, - port2v4Prefix: advertisedRoutesv4Net2, - port2v6Prefix: advertisedRoutesv6Net2, - metricValue: 150, - polNbrv4: atePort1.IPv4, - polNbrv6: atePort1.IPv6, - isDeletePolicy: true, - deleteNbrv4: atePort2.IPv4, - deleteNbrv6: atePort2.IPv6, - asn: dutAS, }, { desc: "Configure eBGP increase MED Import Export Policy", rpPolicy: setMEDPolicy, @@ -700,171 +656,138 @@ func TestBGPPolicy(t *testing.T) { deleteNbrv6: atePort2.IPv6, asn: dutAS, }, { - desc: "Configure eBGP set Local Preference Import Export Policy", - rpPolicy: setLocalPrefPolicy, + desc: "Configure eBGP set NEXT-STATEMENT Import Export Policy", + rpPolicy: setNxtPolicy, policyTypePort1: "", - policyValue: "100", + policyValue: "70", policyStatement: matchStatement1, defPolicyPort1: defAcceptRoute, defPolicyPort2: defRejectRoute, - policyTypePort2: setLocalPrefPolicy, + policyTypePort2: setNxtPolicy, port1v4Prefix: advertisedRoutesv4Net2, port1v6Prefix: advertisedRoutesv6Net2, port2v4Prefix: advertisedRoutesv4Net1, port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 100, + metricValue: 70, polNbrv4: atePort2.IPv4, polNbrv6: atePort2.IPv6, isDeletePolicy: true, deleteNbrv4: atePort1.IPv4, deleteNbrv6: atePort1.IPv6, asn: dutAS, - }, { - desc: "Configure iBGP prepend 10 x local ASN Import Export Policy", - rpPolicy: setPrependPolicy, - policyTypePort1: setPrependPolicy, - policyValue: "10", - policyStatement: matchStatement1, - defPolicyPort1: defRejectRoute, - defPolicyPort2: defAcceptRoute, - policyTypePort2: "", - port1v4Prefix: advertisedRoutesv4Net2, - port1v6Prefix: advertisedRoutesv6Net2, - port2v4Prefix: advertisedRoutesv4Net1, - port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 11, - polNbrv4: atePort1.IPv4, - polNbrv6: atePort1.IPv6, - isDeletePolicy: true, - deleteNbrv4: atePort2.IPv4, - deleteNbrv6: atePort2.IPv6, - asn: dutAS, }, { desc: "Configure eBGP prepend 10 x local ASN Import Export Policy", rpPolicy: setPrependPolicy, policyTypePort1: "", policyValue: "10", policyStatement: matchStatement1, - defPolicyPort1: defRejectRoute, - defPolicyPort2: defAcceptRoute, + defPolicyPort1: defAcceptRoute, + defPolicyPort2: defRejectRoute, policyTypePort2: setPrependPolicy, port1v4Prefix: advertisedRoutesv4Net2, port1v6Prefix: advertisedRoutesv6Net2, port2v4Prefix: advertisedRoutesv4Net1, port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 11, + metricValue: asnRepeatN + 1, polNbrv4: atePort2.IPv4, polNbrv6: atePort2.IPv6, isDeletePolicy: true, deleteNbrv4: atePort1.IPv4, deleteNbrv6: atePort1.IPv6, asn: dutAS, - }, { - desc: "Configure iBGP prepend 10 x ASN Import Export Policy", - rpPolicy: setPrependPolicy, - policyTypePort1: setPrependPolicy, - policyValue: "10", - policyStatement: matchStatement1, - defPolicyPort1: defRejectRoute, - defPolicyPort2: defAcceptRoute, - policyTypePort2: "", - port1v4Prefix: advertisedRoutesv4Net2, - port1v6Prefix: advertisedRoutesv6Net2, - port2v4Prefix: advertisedRoutesv4Net1, - port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 11, - polNbrv4: atePort1.IPv4, - polNbrv6: atePort1.IPv6, - isDeletePolicy: true, - deleteNbrv4: atePort2.IPv4, - deleteNbrv6: atePort2.IPv6, - asn: 23456, }, { desc: "Configure eBGP prepend 10 x ASN Import Export Policy", rpPolicy: setPrependPolicy, policyTypePort1: "", policyValue: "10", policyStatement: matchStatement1, - defPolicyPort1: defRejectRoute, - defPolicyPort2: defAcceptRoute, - policyTypePort2: setPrependPolicy, - port1v4Prefix: advertisedRoutesv4Net2, - port1v6Prefix: advertisedRoutesv6Net2, - port2v4Prefix: advertisedRoutesv4Net1, - port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 11, - polNbrv4: atePort2.IPv4, - polNbrv6: atePort2.IPv6, - isDeletePolicy: true, - deleteNbrv4: atePort1.IPv4, - deleteNbrv6: atePort1.IPv6, - asn: 23456, - }, { - desc: "Configure iBGP set NEXT-STATEMENT Import Export Policy", - rpPolicy: setNxtPolicy, - policyTypePort1: setNxtPolicy, - policyValue: "70", - policyStatement: matchStatement1, - defPolicyPort1: defRejectRoute, - defPolicyPort2: defAcceptRoute, - policyTypePort2: "", - port1v4Prefix: advertisedRoutesv4Net2, - port1v6Prefix: advertisedRoutesv6Net2, - port2v4Prefix: advertisedRoutesv4Net1, - port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 70, - polNbrv4: atePort1.IPv4, - polNbrv6: atePort1.IPv6, - isDeletePolicy: false, - deleteNbrv4: atePort2.IPv4, - deleteNbrv6: atePort2.IPv6, - asn: dutAS, - }, { - desc: "Configure eBGP set NEXT-STATEMENT Import Export Policy", - rpPolicy: setNxtPolicy, - policyTypePort1: "", - policyValue: "70", - policyStatement: matchStatement1, defPolicyPort1: defAcceptRoute, defPolicyPort2: defRejectRoute, - policyTypePort2: setNxtPolicy, + policyTypePort2: setPrependPolicy, port1v4Prefix: advertisedRoutesv4Net2, port1v6Prefix: advertisedRoutesv6Net2, port2v4Prefix: advertisedRoutesv4Net1, port2v6Prefix: advertisedRoutesv6Net1, - metricValue: 70, + metricValue: asnRepeatN + 1, polNbrv4: atePort2.IPv4, polNbrv6: atePort2.IPv6, isDeletePolicy: true, deleteNbrv4: atePort1.IPv4, deleteNbrv6: atePort1.IPv6, - asn: dutAS, + asn: 23456, }} for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { - + // Delete BGP import export policy + if tc.isDeletePolicy { + deleteBGPImportExportPolicy(t, dut, tc.deleteNbrv4, tc.deleteNbrv6) + } // Configure Routing Policy on the DUT. configureASLocalPrefMEDPolicy(t, dut, tc.rpPolicy, tc.policyValue, tc.policyStatement, tc.asn) // Configure BGP default import export policy on Port1 configureBGPDefaultImportExportPolicy(t, dut, atePort1.IPv4, atePort1.IPv6, tc.defPolicyPort1) - // Configure BGP default import export policy on Port1 + // Configure BGP default import export policy on Port2 configureBGPDefaultImportExportPolicy(t, dut, atePort2.IPv4, atePort2.IPv6, tc.defPolicyPort2) // Configure BGP import export policy configureBGPImportExportPolicy(t, dut, tc.polNbrv4, tc.polNbrv6, tc.rpPolicy) - // Delete BGP import export policy - if tc.isDeletePolicy { - deleteBGPImportExportPolicy(t, dut, tc.deleteNbrv4, tc.deleteNbrv6) - } + // Verify BGP policy verifyBgpPolicyTelemetry(t, dut, atePort1.IPv4, tc.defPolicyPort1, tc.policyTypePort1, true) verifyBgpPolicyTelemetry(t, dut, atePort1.IPv6, tc.defPolicyPort1, tc.policyTypePort1, false) verifyBgpPolicyTelemetry(t, dut, atePort2.IPv4, tc.defPolicyPort2, tc.policyTypePort2, true) verifyBgpPolicyTelemetry(t, dut, atePort2.IPv6, tc.defPolicyPort2, tc.policyTypePort2, false) + // Validate Prefixes - validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, otgConfig, atePort1.Name+".BGP4.peer", tc.port1v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) - validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, otgConfig, atePort1.Name+".BGP6.peer", tc.port1v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) - validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, otgConfig, atePort2.Name+".BGP4.peer", tc.port2v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) - validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, otgConfig, atePort2.Name+".BGP6.peer", tc.port2v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, dut, otgConfig, atePort1.Name+".BGP4.peer", tc.port1v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, dut, otgConfig, atePort1.Name+".BGP6.peer", tc.port1v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV4AndASLocalPrefMED(t, otg, dut, otgConfig, atePort2.Name+".BGP4.peer", tc.port2v4Prefix, advertisedRoutesv4PrefixLen, tc.rpPolicy, tc.metricValue) + validateOTGBgpPrefixV6AndASLocalPrefMED(t, otg, dut, otgConfig, atePort2.Name+".BGP6.peer", tc.port2v6Prefix, advertisedRoutesv6PrefixLen, tc.rpPolicy, tc.metricValue) }) } } + +func validateImportRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, prefix string, metricValue uint32) { + dni := deviations.DefaultNetworkInstance(dut) + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv4Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast().LocRib().State()) + found := false + for k, lr := range locRib.Route { + prefixAddr := strings.Split(lr.GetPrefix(), "/") + if prefixAddr[0] == prefix { + found = true + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) + attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) + if attrSet == nil || attrSet.GetLocalPref() != metricValue { + t.Errorf("No local pref found for prefix %s", prefix) + } + break + } + } + + if !found { + t.Errorf("No Route found for prefix %s", prefix) + } +} + +func validateImportRoutingPolicyV6(t *testing.T, dut *ondatra.DUTDevice, prefix string, metricValue uint32) { + dni := deviations.DefaultNetworkInstance(dut) + bgpRIBPath := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Rib() + locRib := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AfiSafi_Ipv6Unicast_LocRib](t, dut, bgpRIBPath.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast().LocRib().State()) + found := false + for k, lr := range locRib.Route { + prefixAddr := strings.Split(lr.GetPrefix(), "/") + if prefixAddr[0] == prefix { + found = true + t.Logf("Found Route(prefix %s, origin: %v, pathid: %d) => %s", k.Prefix, k.Origin, k.PathId, lr.GetPrefix()) + attrSet := gnmi.Get[*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet](t, dut, bgpRIBPath.AttrSet(lr.GetAttrIndex()).State()) + if attrSet == nil || attrSet.GetLocalPref() != metricValue { + t.Errorf("No local pref found for prefix %s", prefix) + } + break + } + } + + if !found { + t.Errorf("No Route found for prefix %s", prefix) + } +} diff --git a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/metadata.textproto b/feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/metadata.textproto similarity index 99% rename from feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/metadata.textproto rename to feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/metadata.textproto index 87b9598040b..0ad0280524f 100644 --- a/feature/bgp/policybase/otg_tests/actions_MED_LocPref_prepend_flow_control/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/actions_med_localpref_prepend_flow_control/metadata.textproto @@ -36,3 +36,4 @@ platform_exceptions: { default_network_instance: "default" } } + From 20c8fb905505278363350b1086de9d359b979250 Mon Sep 17 00:00:00 2001 From: NishaSadhasivam-work Date: Fri, 5 Apr 2024 12:09:44 +0530 Subject: [PATCH 71/97] =?UTF-8?q?DCGATE:=20[RT-7.11]=20BGP=20import/export?= =?UTF-8?q?=20policy=20-=20multifacet=20match=20and=20act=E2=80=A6=20(#286?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * DCGATE: [RT-7.11] BGP import/export policy - multifacet match and actions - Test Automation * Addressed review comments * addressing review comments * Validate Accept all traffic modification * Update import_export_multi.go fixing static analysis failure * Update import_export_multi.go static analysis failure * Modified multi policy configuration * static analysis failure update * removed default policy * fixing static analysis failure * fixing go fmt issues --- .../import_export_multi.go | 512 ++++++++++++++++++ .../import_export_multi/metadata.textproto | 17 + internal/deviations/deviations.go | 5 + proto/metadata.proto | 2 + proto/metadata_go_proto/metadata.pb.go | 94 ++-- 5 files changed, 590 insertions(+), 40 deletions(-) create mode 100644 feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go new file mode 100644 index 00000000000..ecc02d088bc --- /dev/null +++ b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go @@ -0,0 +1,512 @@ +// Copyright 2023 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 import_export_test + +import ( + "strconv" + "testing" + "time" + + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/featureprofiles/internal/cfgplugins" + "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" +) + +const ( + prefixV4Len = 30 + prefixV6Len = 126 + trafficPps = 100 + totalPackets = 1200 + bgpName = "BGP" + medValue = 100 + parentPolicy = "multiPolicy" + callPolicy = "match_community_regex" + rejectStatement = "reject_route_community" + nestedRejectStatement = "if_30_and_not_20_nested_reject" + callPolicyStatement = "match_community_regex" + addMissingCommunitiesStatement = "add_communities_if_missing" + matchCommPrefixAddCommuStatement = "match_comm_and_prefix_add_2_community_sets" + matchAspathSetMedStatement = "match_aspath_set_med" + rejectCommunitySet = "reject_communities" + nestedRejectCommunitySet = "accept_communities" + regexCommunitySet = "regex-community" + addCommunitiesSetRefs = "add-communities" + myCommunitySet = "my_community" + prefixSetName = "prefix-set-5" + myAsPathName = "my_aspath" + bgpActionMethod = oc.SetCommunity_Method_REFERENCE + bgpSetCommunityOptionType = oc.BgpPolicy_BgpSetCommunityOptionType_ADD + prefixSetNameSetOptions = oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY + matchAny = oc.BgpPolicy_MatchSetOptionsType_ANY + matchInvert = oc.BgpPolicy_MatchSetOptionsType_INVERT + rejectResult = oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE + nextstatementResult = oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT +) + +var prefixesV4 = [][]string{ + {"198.51.100.0", "198.51.100.4"}, + {"198.51.100.8", "198.51.100.12"}, + {"198.51.100.16", "198.51.100.20"}, + {"198.51.100.24", "198.51.100.28"}, + {"198.51.100.32", "198.51.100.36"}, + {"198.51.100.40", "198.51.100.44"}, +} + +var prefixesV6 = [][]string{ + {"2048:db1:64:64::0", "2048:db1:64:64::4"}, + {"2048:db1:64:64::8", "2048:db1:64:64::c"}, + {"2048:db1:64:64::10", "2048:db1:64:64::14"}, + {"2048:db1:64:64::18", "2048:db1:64:64::1c"}, + {"2048:db1:64:64::20", "2048:db1:64:64::24"}, + {"2048:db1:64:64::28", "2048:db1:64:64::2c"}, +} + +var communityMembers = [][][]int{ + { + {10, 1}, {11, 1}, + }, + { + {20, 1}, {21, 1}, + }, + { + {30, 1}, {31, 1}, + }, + { + {20, 2}, {30, 3}, + }, + { + {40, 1}, {41, 1}, + }, + { + {50, 1}, {51, 1}, + }, +} + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func configureImportExportAcceptAllBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, ipv6 string, matchSetOptions oc.E_BgpPolicy_MatchSetOptionsType) { + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + pdef1 := rp.GetOrCreatePolicyDefinition("routePolicy") + stmt1, err := pdef1.AppendNewStatement("routePolicyStatement") + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", "routePolicyStatement", err) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + dni := deviations.DefaultNetworkInstance(dut) + pathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policyV6 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policyV6.SetImportPolicy([]string{"routePolicy"}) + policyV6.SetExportPolicy([]string{"routePolicy"}) + gnmi.Replace(t, dut, pathV6.Config(), policyV6) + + pathV4 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policyV4 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() + policyV4.SetImportPolicy([]string{"routePolicy"}) + policyV4.SetExportPolicy([]string{"routePolicy"}) + gnmi.Replace(t, dut, pathV4.Config(), policyV4) + +} + +func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, ipv6 string) { + rejectCommunities := []string{"10:1"} + acceptCommunities := []string{"20:1"} + regexCommunities := []string{"^30:.*$"} + addCommunitiesRefs := []string{"40:1", "40:2"} + addCommunitiesSetRefsAction := []string{"add-communities"} + setCommunitySetRefs := []string{"add_comm_60", "add_comm_70"} + myCommunitySets := []string{"50:1"} + + // Configure the parent policy multi_policy. + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + pdef1 := rp.GetOrCreatePolicyDefinition(parentPolicy) + + // Configure multi_policy:STATEMENT1: reject_route_community + stmt1, err := pdef1.AppendNewStatement(rejectStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", rejectStatement, err) + } + stmt1.GetOrCreateActions().SetPolicyResult(rejectResult) + + // Configure reject_communities:[10:1] to reject_route_community statement + communitySetReject := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(rejectCommunitySet) + + cs1 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + for _, commMatch1 := range rejectCommunities { + if commMatch1 != "" { + cs1 = append(cs1, oc.UnionString(commMatch1)) + } + } + communitySetReject.SetCommunityMember(cs1) + communitySetReject.SetMatchSetOptions(matchAny) + + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(rejectCommunitySet) + } else { + stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(rejectCommunitySet) + } + + // Configure multi_policy:STATEMENT2:if_30:.*_and_not_20:1_nested_reject + + stmt2, err := pdef1.AppendNewStatement(nestedRejectStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", nestedRejectStatement, err) + } + stmt2.GetOrCreateActions().SetPolicyResult(rejectResult) + + // Configure accept_communities:[20:1] to if_30_and_not_20_nested_reject statement + communitySetNestedReject := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(nestedRejectCommunitySet) + + cs2 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + for _, commMatch2 := range acceptCommunities { + if commMatch2 != "" { + cs2 = append(cs2, oc.UnionString(commMatch2)) + } + } + communitySetNestedReject.SetCommunityMember(cs2) + communitySetNestedReject.SetMatchSetOptions(matchInvert) + + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + stmt2.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(nestedRejectCommunitySet) + } else { + stmt2.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(nestedRejectCommunitySet) + } + + // Configure the policy match_community_regex which will be called from multi_policy + + pdef2 := rp.GetOrCreatePolicyDefinition(callPolicy) + + // Configure match_community_regex:STATEMENT1:match_community_regex statement + + stmt3, err := pdef2.AppendNewStatement(callPolicyStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", callPolicyStatement, err) + } + stmt3.GetOrCreateActions().SetPolicyResult(nextstatementResult) + + // Configure regex_community:["^30:.*$"] to match_community_regex statement + communitySetRegex := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(regexCommunitySet) + + cs3 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + for _, commMatch3 := range regexCommunities { + if commMatch3 != "" { + cs3 = append(cs3, oc.UnionString(commMatch3)) + } + } + communitySetRegex.SetCommunityMember(cs3) + communitySetRegex.SetMatchSetOptions(matchAny) + + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + stmt3.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(regexCommunitySet) + } else { + stmt3.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(regexCommunitySet) + } + + // Call child policy match_community_regex from parent policy multi_policy + + dni := deviations.DefaultNetworkInstance(dut) + statPath := rp.GetOrCreatePolicyDefinition(parentPolicy).GetStatement(nestedRejectStatement).GetConditions() + statPath.SetCallPolicy(callPolicy) + + // Configure multi_policy:STATEMENT3: add_communities_if_missing statement + stmt4, err := pdef1.AppendNewStatement(addMissingCommunitiesStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", addMissingCommunitiesStatement, err) + } + stmt4.GetOrCreateActions().SetPolicyResult(nextstatementResult) + + // Configure add-communities: [ "40:1", "40:2" ] to add_communities_if_missing statement + communitySetRefsAddCommunities := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(addCommunitiesSetRefs) + + cs4 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + for _, commMatch4 := range addCommunitiesRefs { + if commMatch4 != "" { + cs4 = append(cs4, oc.UnionString(commMatch4)) + } + } + communitySetRefsAddCommunities.SetCommunityMember(cs4) + communitySetRefsAddCommunities.SetMatchSetOptions(matchInvert) + + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + stmt4.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(addCommunitiesSetRefs) + } else { + if deviations.BgpCommunitySetRefsUnsupported(dut) { + t.Logf("TODO: community-set-refs not supported b/316833803") + stmt4.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(addCommunitiesSetRefs) + } + } + + if deviations.BgpCommunitySetRefsUnsupported(dut) { + t.Logf("TODO: community-set-refs not supported b/316833803") + } else { + stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().GetOrCreateReference().SetCommunitySetRefs(addCommunitiesSetRefsAction) + stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetMethod(bgpActionMethod) + stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetOptions(bgpSetCommunityOptionType) + } + + // Configure multi_policy:STATEMENT4: match_comm_and_prefix_add_2_community_sets statement + + stmt5, err := pdef1.AppendNewStatement(matchCommPrefixAddCommuStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", matchCommPrefixAddCommuStatement, err) + } + stmt5.GetOrCreateActions().SetPolicyResult(nextstatementResult) + + // Configure my_community: [ "50:1" ] to match_comm_and_prefix_add_2_community_sets statement + communitySetMatchCommPrefixAddCommu := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(myCommunitySet) + + cs5 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + for _, commMatch5 := range myCommunitySets { + if commMatch5 != "" { + cs5 = append(cs5, oc.UnionString(commMatch5)) + } + } + communitySetMatchCommPrefixAddCommu.SetCommunityMember(cs5) + communitySetMatchCommPrefixAddCommu.SetMatchSetOptions(matchAny) + + // configure match-prefix-set: prefix-set-5 to match_comm_and_prefix_add_2_community_sets statement + stmt5.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet(prefixSetName) + stmt5.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(prefixSetNameSetOptions) + + pset := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(prefixSetName) + pset.GetOrCreatePrefix(prefixesV4[4][0]+"/29", "exact") + if !deviations.SkipPrefixSetMode(dut) { + pset.SetMode(oc.PrefixSet_Mode_IPV4) + } + + psetV6 := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(prefixSetName) + psetV6.GetOrCreatePrefix(prefixesV6[4][0]+"/125", "exact") + if !deviations.SkipPrefixSetMode(dut) { + psetV6.SetMode(oc.PrefixSet_Mode_IPV6) + } + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet(prefixSetName).Config(), pset) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet(prefixSetName).Config(), psetV6) + + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + stmt5.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(myCommunitySet) + } else { + stmt5.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(myCommunitySet) + } + + if deviations.BgpCommunitySetRefsUnsupported(dut) { + t.Logf("TODO: community-set-refs not supported b/316833803") + } else { + // TODO: Add bgp-actions: community-set-refs to match_comm_and_prefix_add_2_community_sets statement + stmt5.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().GetOrCreateReference().SetCommunitySetRefs(setCommunitySetRefs) + stmt5.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetMethod(oc.SetCommunity_Method_REFERENCE) + stmt5.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + } + + // Configure multi_policy:STATEMENT5: match_aspath_set_med statement + stmt6, err := pdef1.AppendNewStatement(matchAspathSetMedStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", matchAspathSetMedStatement, err) + } + stmt6.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + // TODO create as-path-set on the DUT, match-as-path-set not support. + // Configure set-med 100 + stmt6.GetOrCreateActions().GetOrCreateBgpActions().SetMed = oc.UnionUint32(medValue) + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + // Configure the parent BGP import and export policy. + pathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policyV6 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policyV6.SetImportPolicy([]string{parentPolicy}) + policyV6.SetExportPolicy([]string{parentPolicy}) + gnmi.Replace(t, dut, pathV6.Config(), policyV6) + + pathV4 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policyV4 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() + policyV4.SetImportPolicy([]string{parentPolicy}) + policyV4.SetExportPolicy([]string{parentPolicy}) + gnmi.Replace(t, dut, pathV4.Config(), policyV4) +} + +func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string, prefixesV6 [][]string, communityMembers [][][]int) { + devices := bs.ATETop.Devices().Items() + + ipv4 := devices[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0] + bgp4Peer := devices[1].Bgp().Ipv4Interfaces().Items()[0].Peers().Items()[0] + + ipv6 := devices[1].Ethernets().Items()[0].Ipv6Addresses().Items()[0] + bgp6Peer := devices[1].Bgp().Ipv6Interfaces().Items()[0].Peers().Items()[0] + + for index, prefixes := range prefixesV4 { + bgp4PeerRoute := bgp4Peer.V4Routes().Add() + bgp4PeerRoute.SetName(bs.ATEPorts[1].Name + ".BGP4.peer.dut." + strconv.Itoa(index)) + bgp4PeerRoute.SetNextHopIpv4Address(ipv4.Address()) + + route4Address1 := bgp4PeerRoute.Addresses().Add().SetAddress(prefixes[0]) + route4Address1.SetPrefix(prefixV4Len) + route4Address2 := bgp4PeerRoute.Addresses().Add().SetAddress(prefixes[1]) + route4Address2.SetPrefix(prefixV4Len) + + bgp6PeerRoute := bgp6Peer.V6Routes().Add() + bgp6PeerRoute.SetName(bs.ATEPorts[1].Name + ".BGP6.peer.dut." + strconv.Itoa(index)) + bgp6PeerRoute.SetNextHopIpv6Address(ipv6.Address()) + + route6Address1 := bgp6PeerRoute.Addresses().Add().SetAddress(prefixesV6[index][0]) + route6Address1.SetPrefix(prefixV6Len) + route6Address2 := bgp6PeerRoute.Addresses().Add().SetAddress(prefixesV6[index][1]) + route6Address2.SetPrefix(prefixV6Len) + + for _, commu := range communityMembers[index] { + if commu[0] != 0 { + commv4 := bgp4PeerRoute.Communities().Add() + commv4.SetType(gosnappi.BgpCommunityType.MANUAL_AS_NUMBER) + commv4.SetAsNumber(uint32(commu[0])) + commv4.SetAsCustom(uint32(commu[1])) + + commv6 := bgp6PeerRoute.Communities().Add() + commv6.SetType(gosnappi.BgpCommunityType.MANUAL_AS_NUMBER) + commv6.SetAsNumber(uint32(commu[0])) + commv6.SetAsCustom(uint32(commu[1])) + } + } + } +} + +func configureFlowV4(t *testing.T, bs *cfgplugins.BGPSession) { + for index, prefixPairV4 := range prefixesV4 { + flow := bs.ATETop.Flows().Add().SetName("flow" + "ipv4" + strconv.Itoa(index)) + flow.Metrics().SetEnable(true) + + flow.TxRx().Device(). + SetTxNames([]string{bs.ATEPorts[0].Name + ".IPv4"}). + SetRxNames([]string{bs.ATEPorts[1].Name + ".BGP4.peer.dut." + strconv.Itoa(index)}) + + flow.Duration().FixedPackets().SetPackets(totalPackets) + flow.Size().SetFixed(1500) + flow.Rate().SetPps(trafficPps) + + e := flow.Packet().Add().Ethernet() + e.Src().SetValue(bs.ATEPorts[1].MAC) + + v4 := flow.Packet().Add().Ipv4() + v4.Src().SetValue(bs.ATEPorts[0].IPv4) + v4.Dst().SetValues(prefixPairV4) + } +} + +func configureFlowV6(t *testing.T, bs *cfgplugins.BGPSession) { + for index, prefixPairV6 := range prefixesV6 { + flow := bs.ATETop.Flows().Add().SetName("flow" + "ipv6" + strconv.Itoa(index)) + flow.Metrics().SetEnable(true) + + flow.TxRx().Device(). + SetTxNames([]string{bs.ATEPorts[0].Name + ".IPv6"}). + SetRxNames([]string{bs.ATEPorts[1].Name + ".BGP6.peer.dut." + strconv.Itoa(index)}) + + flow.Duration().FixedPackets().SetPackets(totalPackets) + flow.Size().SetFixed(1500) + flow.Rate().SetPps(trafficPps) + + e := flow.Packet().Add().Ethernet() + e.Src().SetValue(bs.ATEPorts[1].MAC) + + v6 := flow.Packet().Add().Ipv6() + v6.Src().SetValue(bs.ATEPorts[0].IPv6) + v6.Dst().SetValues(prefixPairV6) + } +} + +func verifyTrafficV4AndV6(t *testing.T, bs *cfgplugins.BGPSession, testResults [6]bool) { + + sleepTime := time.Duration(totalPackets/trafficPps) + 2 + bs.ATE.OTG().StartTraffic(t) + time.Sleep(time.Second * sleepTime) + bs.ATE.OTG().StopTraffic(t) + + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + otgutils.LogPortMetrics(t, bs.ATE.OTG(), bs.ATETop) + + for index, prefixPairV4 := range prefixesV4 { + t.Logf("Running traffic test for IPv4 prefixes: [%s, %s]. Expected Result: [%t]", prefixPairV4[0], prefixPairV4[1], testResults[index]) + t.Logf("Running traffic test for IPv6 prefixes: [%s, %s]. Expected Result: [%t]", prefixesV6[index][0], prefixesV6[index][1], testResults[index]) + + t.Log("Checking flow telemetry for v4...") + recvMetric := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Flow("flow"+"ipv4"+strconv.Itoa(index)).State()) + txPackets := recvMetric.GetCounters().GetOutPkts() + rxPackets := recvMetric.GetCounters().GetInPkts() + lostPackets := txPackets - rxPackets + lossPct := lostPackets * 100 / txPackets + + t.Log("Checking flow telemetry for v6...") + recvMetric6 := gnmi.Get(t, bs.ATE.OTG(), gnmi.OTG().Flow("flow"+"ipv6"+strconv.Itoa(index)).State()) + txPackets6 := recvMetric6.GetCounters().GetOutPkts() + rxPackets6 := recvMetric6.GetCounters().GetInPkts() + lostPackets6 := txPackets6 - rxPackets6 + lossPct6 := lostPackets6 * 100 / txPackets6 + + if txPackets != rxPackets && testResults[index] { + t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want < 0%% traffic loss", lossPct, "flow"+"ipv4"+strconv.Itoa(index), prefixPairV4[0], prefixPairV4[1]) + t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want < 0%% traffic loss", lossPct6, "flow"+"ipv6"+strconv.Itoa(index), prefixesV6[index][0], prefixesV6[index][1]) + } else if rxPackets != 0 && !testResults[index] { + t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want >100%% traffic loss", lossPct, "flow"+"ipv4"+strconv.Itoa(index), prefixPairV4[0], prefixPairV4[1]) + t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want >100%% traffic loss", lossPct6, "flow"+"ipv6"+strconv.Itoa(index), prefixesV6[index][0], prefixesV6[index][1]) + } else { + t.Logf("Traffic validation successful for Prefixes: [%s, %s]. Result: [%t] PacketsTx: %d PacketsRx: %d", prefixPairV4[0], prefixPairV4[1], testResults[index], txPackets, rxPackets) + t.Logf("Traffic validation successful for Prefixes: [%s, %s]. Result: [%t] PacketsTx: %d PacketsRx: %d", prefixesV6[index][0], prefixesV6[index][1], testResults[index], txPackets6, rxPackets6) + } + + } +} + +func TestImportExportMultifacetMatchActionsBGPPolicy(t *testing.T) { + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{ + "port1", "port2"}, true, false) + + configureOTG(t, bs, prefixesV4, prefixesV6, communityMembers) + bs.PushAndStart(t) + + t.Log("Verify DUT BGP sessions up") + cfgplugins.VerifyDUTBGPEstablished(t, bs.DUT) + t.Log("Verify OTG BGP sessions up") + cfgplugins.VerifyOTGBGPEstablished(t, bs.ATE) + + ipv4 := bs.ATETop.Devices().Items()[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0].Address() + ipv6 := bs.ATETop.Devices().Items()[1].Ethernets().Items()[0].Ipv6Addresses().Items()[0].Address() + + t.Logf("Verify Import Export Accept all bgp policy") + configureImportExportAcceptAllBGPPolicy(t, bs.DUT, ipv4, ipv6, matchAny) + + configureFlowV4(t, bs) + configureFlowV6(t, bs) + + bs.PushAndStartATE(t) + + testResults := [6]bool{true, true, true, true, true, true} + verifyTrafficV4AndV6(t, bs, testResults) + + configureImportExportMultifacetMatchActionsBGPPolicy(t, bs.DUT, ipv4, ipv6) + + testResults1 := [6]bool{false, true, false, false, true, true} + verifyTrafficV4AndV6(t, bs, testResults1) +} diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto b/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto index 079f8dfbd6f..82c296ae6d0 100644 --- a/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/import_export_multi/metadata.textproto @@ -3,5 +3,22 @@ plan_id: "RT-7.11" description: "BGP Policy - Import/Export Policy Action Using Multiple Criteria" +uuid: "520f6013-0188-45a3-b5be-ce13c55ce7cd" + testbed: TESTBED_DUT_ATE_2LINKS tags: [TAGS_AGGREGATION, TAGS_DATACENTER_EDGE] +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + interface_enabled: true + default_network_instance: "default" + missing_value_for_defaults: true + skip_set_rp_match_set_options: true + bgp_community_set_refs_unsupported: true + bgp_conditions_match_community_set_unsupported: true + skip_prefix_set_mode: true + } +} diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index c51d87f31d4..c733fcf1611 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -901,3 +901,8 @@ func PLQGeneratorCapabilitiesMaxPPS(dut *ondatra.DUTDevice) uint64 { func BgpExtendedCommunityIndexUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetBgpExtendedCommunityIndexUnsupported() } + +// BgpCommunitySetRefsUnsupported return true if BGP community set refs is not supported. +func BgpCommunitySetRefsUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetBgpCommunitySetRefsUnsupported() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 9ec70094cdf..d7492900a0b 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -473,6 +473,8 @@ message Metadata { uint64 plq_generator_capabilities_max_pps = 166; // Support for bgp extended community index bool bgp_extended_community_index_unsupported = 167; + // Support for bgp community set refs + bool bgp_community_set_refs_unsupported = 168; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 41d04aaa027..974d864f1e0 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -744,6 +744,8 @@ type Metadata_Deviations struct { PlqGeneratorCapabilitiesMaxPps uint64 `protobuf:"varint,166,opt,name=plq_generator_capabilities_max_pps,json=plqGeneratorCapabilitiesMaxPps,proto3" json:"plq_generator_capabilities_max_pps,omitempty"` // Support for bgp extended community index BgpExtendedCommunityIndexUnsupported bool `protobuf:"varint,167,opt,name=bgp_extended_community_index_unsupported,json=bgpExtendedCommunityIndexUnsupported,proto3" json:"bgp_extended_community_index_unsupported,omitempty"` + // Support for bgp community set refs + BgpCommunitySetRefsUnsupported bool `protobuf:"varint,168,opt,name=bgp_community_set_refs_unsupported,json=bgpCommunitySetRefsUnsupported,proto3" json:"bgp_community_set_refs_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1835,6 +1837,13 @@ func (x *Metadata_Deviations) GetBgpExtendedCommunityIndexUnsupported() bool { return false } +func (x *Metadata_Deviations) GetBgpCommunitySetRefsUnsupported() bool { + if x != nil { + return x.BgpCommunitySetRefsUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1898,7 +1907,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, 0x5e, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x5f, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1929,7 +1938,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xb7, 0x56, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x84, 0x57, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -2617,44 +2626,49 @@ var file_metadata_proto_rawDesc = []byte{ 0x65, 0x78, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, - 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, - 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, - 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, - 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, - 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, - 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, - 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, - 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, - 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, - 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, - 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, - 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, - 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, - 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, - 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, - 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, - 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, - 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, - 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, - 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, - 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, - 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x62, + 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, + 0x5f, 0x72, 0x65, 0x66, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0xa8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, + 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, + 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, + 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, + 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, + 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, + 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, + 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, + 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, + 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, + 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, + 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, + 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, + 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, + 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 7a290fed272e04558daf81e0821d13ba7dc5a541 Mon Sep 17 00:00:00 2001 From: NishaSadhasivam-work Date: Fri, 5 Apr 2024 22:09:59 +0530 Subject: [PATCH 72/97] re-arranging PD1 and PD2Dcgate (#2878) * DCGATE: [RT-7.11] BGP import/export policy - multifacet match and actions - Test Automation * Addressed review comments * addressing review comments * Validate Accept all traffic modification * Update import_export_multi.go fixing static analysis failure * Update import_export_multi.go static analysis failure * Modified multi policy configuration * static analysis failure update * removed default policy * fixing static analysis failure * fixing go fmt issues * re-arranging PD1 and PD2 * Update import_export_multi.go --- .../import_export_multi.go | 163 ++++++++++-------- 1 file changed, 90 insertions(+), 73 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go index ecc02d088bc..447f10f9f6c 100644 --- a/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go +++ b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go @@ -36,6 +36,7 @@ const ( totalPackets = 1200 bgpName = "BGP" medValue = 100 + localPref = 5 parentPolicy = "multiPolicy" callPolicy = "match_community_regex" rejectStatement = "reject_route_community" @@ -139,9 +140,42 @@ func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ond setCommunitySetRefs := []string{"add_comm_60", "add_comm_70"} myCommunitySets := []string{"50:1"} - // Configure the parent policy multi_policy. root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() + + // Configure the policy match_community_regex which will be called from multi_policy + + pdef2 := rp.GetOrCreatePolicyDefinition(callPolicy) + + // Configure match_community_regex:STATEMENT1:match_community_regex statement + + pd2stmt1, err := pdef2.AppendNewStatement(callPolicyStatement) + if err != nil { + t.Fatalf("AppendNewStatement(%s) failed: %v", callPolicyStatement, err) + } + + // Configure regex_community:["^30:.*$"] to match_community_regex statement + communitySetRegex := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(regexCommunitySet) + + pd2cs1 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + for _, commMatchPd2Cs1 := range regexCommunities { + if commMatchPd2Cs1 != "" { + pd2cs1 = append(pd2cs1, oc.UnionString(commMatchPd2Cs1)) + } + } + communitySetRegex.SetCommunityMember(pd2cs1) + communitySetRegex.SetMatchSetOptions(matchAny) + + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + pd2stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(regexCommunitySet) + } else { + pd2stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(regexCommunitySet) + } + + pd2stmt1.GetOrCreateActions().SetPolicyResult(nextstatementResult) + + // Configure the parent policy multi_policy. + pdef1 := rp.GetOrCreatePolicyDefinition(parentPolicy) // Configure multi_policy:STATEMENT1: reject_route_community @@ -149,7 +183,6 @@ func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ond if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", rejectStatement, err) } - stmt1.GetOrCreateActions().SetPolicyResult(rejectResult) // Configure reject_communities:[10:1] to reject_route_community statement communitySetReject := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(rejectCommunitySet) @@ -169,13 +202,19 @@ func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ond stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(rejectCommunitySet) } + stmt1.GetOrCreateActions().SetPolicyResult(rejectResult) + // Configure multi_policy:STATEMENT2:if_30:.*_and_not_20:1_nested_reject stmt2, err := pdef1.AppendNewStatement(nestedRejectStatement) if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", nestedRejectStatement, err) } - stmt2.GetOrCreateActions().SetPolicyResult(rejectResult) + + // Call child policy match_community_regex from parent policy multi_policy + + statPath := rp.GetOrCreatePolicyDefinition(parentPolicy).GetStatement(nestedRejectStatement) + statPath.GetOrCreateConditions().SetCallPolicy(callPolicy) // Configure accept_communities:[20:1] to if_30_and_not_20_nested_reject statement communitySetNestedReject := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(nestedRejectCommunitySet) @@ -195,156 +234,133 @@ func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ond stmt2.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(nestedRejectCommunitySet) } - // Configure the policy match_community_regex which will be called from multi_policy - - pdef2 := rp.GetOrCreatePolicyDefinition(callPolicy) - - // Configure match_community_regex:STATEMENT1:match_community_regex statement - - stmt3, err := pdef2.AppendNewStatement(callPolicyStatement) - if err != nil { - t.Fatalf("AppendNewStatement(%s) failed: %v", callPolicyStatement, err) - } - stmt3.GetOrCreateActions().SetPolicyResult(nextstatementResult) - - // Configure regex_community:["^30:.*$"] to match_community_regex statement - communitySetRegex := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(regexCommunitySet) - - cs3 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} - for _, commMatch3 := range regexCommunities { - if commMatch3 != "" { - cs3 = append(cs3, oc.UnionString(commMatch3)) - } - } - communitySetRegex.SetCommunityMember(cs3) - communitySetRegex.SetMatchSetOptions(matchAny) - - if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { - stmt3.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(regexCommunitySet) - } else { - stmt3.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(regexCommunitySet) - } - - // Call child policy match_community_regex from parent policy multi_policy - - dni := deviations.DefaultNetworkInstance(dut) - statPath := rp.GetOrCreatePolicyDefinition(parentPolicy).GetStatement(nestedRejectStatement).GetConditions() - statPath.SetCallPolicy(callPolicy) + stmt2.GetOrCreateActions().SetPolicyResult(rejectResult) // Configure multi_policy:STATEMENT3: add_communities_if_missing statement - stmt4, err := pdef1.AppendNewStatement(addMissingCommunitiesStatement) + stmt3, err := pdef1.AppendNewStatement(addMissingCommunitiesStatement) if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", addMissingCommunitiesStatement, err) } - stmt4.GetOrCreateActions().SetPolicyResult(nextstatementResult) // Configure add-communities: [ "40:1", "40:2" ] to add_communities_if_missing statement + communitySetRefsAddCommunities := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(addCommunitiesSetRefs) - cs4 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + cs3 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} for _, commMatch4 := range addCommunitiesRefs { if commMatch4 != "" { - cs4 = append(cs4, oc.UnionString(commMatch4)) + cs3 = append(cs3, oc.UnionString(commMatch4)) } } - communitySetRefsAddCommunities.SetCommunityMember(cs4) + communitySetRefsAddCommunities.SetCommunityMember(cs3) communitySetRefsAddCommunities.SetMatchSetOptions(matchInvert) if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { - stmt4.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(addCommunitiesSetRefs) + stmt3.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(addCommunitiesSetRefs) } else { if deviations.BgpCommunitySetRefsUnsupported(dut) { t.Logf("TODO: community-set-refs not supported b/316833803") - stmt4.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(addCommunitiesSetRefs) + stmt3.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(addCommunitiesSetRefs) } } if deviations.BgpCommunitySetRefsUnsupported(dut) { t.Logf("TODO: community-set-refs not supported b/316833803") } else { - stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().GetOrCreateReference().SetCommunitySetRefs(addCommunitiesSetRefsAction) - stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetMethod(bgpActionMethod) - stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetOptions(bgpSetCommunityOptionType) + stmt3.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().GetOrCreateReference().SetCommunitySetRefs(addCommunitiesSetRefsAction) + stmt3.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetMethod(bgpActionMethod) + stmt3.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetOptions(bgpSetCommunityOptionType) } + stmt3.GetOrCreateActions().SetPolicyResult(nextstatementResult) + // Configure multi_policy:STATEMENT4: match_comm_and_prefix_add_2_community_sets statement - stmt5, err := pdef1.AppendNewStatement(matchCommPrefixAddCommuStatement) + stmt4, err := pdef1.AppendNewStatement(matchCommPrefixAddCommuStatement) if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", matchCommPrefixAddCommuStatement, err) } - stmt5.GetOrCreateActions().SetPolicyResult(nextstatementResult) // Configure my_community: [ "50:1" ] to match_comm_and_prefix_add_2_community_sets statement communitySetMatchCommPrefixAddCommu := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(myCommunitySet) - cs5 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + cs4 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} for _, commMatch5 := range myCommunitySets { if commMatch5 != "" { - cs5 = append(cs5, oc.UnionString(commMatch5)) + cs4 = append(cs4, oc.UnionString(commMatch5)) } } - communitySetMatchCommPrefixAddCommu.SetCommunityMember(cs5) + communitySetMatchCommPrefixAddCommu.SetCommunityMember(cs4) communitySetMatchCommPrefixAddCommu.SetMatchSetOptions(matchAny) + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + stmt4.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(myCommunitySet) + } else { + stmt4.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(myCommunitySet) + } + // configure match-prefix-set: prefix-set-5 to match_comm_and_prefix_add_2_community_sets statement - stmt5.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet(prefixSetName) - stmt5.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(prefixSetNameSetOptions) + stmt4.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet(prefixSetName) + stmt4.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(prefixSetNameSetOptions) pset := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(prefixSetName) - pset.GetOrCreatePrefix(prefixesV4[4][0]+"/29", "exact") + pset.GetOrCreatePrefix(prefixesV4[4][0]+"/29", "29..30") if !deviations.SkipPrefixSetMode(dut) { pset.SetMode(oc.PrefixSet_Mode_IPV4) } - psetV6 := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(prefixSetName) - psetV6.GetOrCreatePrefix(prefixesV6[4][0]+"/125", "exact") + psetV6 := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(prefixSetName + "_V6") + psetV6.GetOrCreatePrefix(prefixesV6[4][0]+"/125", "125..126") if !deviations.SkipPrefixSetMode(dut) { psetV6.SetMode(oc.PrefixSet_Mode_IPV6) } gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet(prefixSetName).Config(), pset) - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet(prefixSetName).Config(), psetV6) - - if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { - stmt5.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(myCommunitySet) - } else { - stmt5.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(myCommunitySet) - } + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet(prefixSetName+"_V6").Config(), psetV6) if deviations.BgpCommunitySetRefsUnsupported(dut) { t.Logf("TODO: community-set-refs not supported b/316833803") } else { // TODO: Add bgp-actions: community-set-refs to match_comm_and_prefix_add_2_community_sets statement - stmt5.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().GetOrCreateReference().SetCommunitySetRefs(setCommunitySetRefs) - stmt5.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetMethod(oc.SetCommunity_Method_REFERENCE) - stmt5.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().GetOrCreateReference().SetCommunitySetRefs(setCommunitySetRefs) + stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetMethod(oc.SetCommunity_Method_REFERENCE) + stmt4.GetOrCreateActions().GetOrCreateBgpActions().GetSetCommunity().SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) } + // set-local-pref = 5 + stmt4.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(localPref) + + stmt4.GetOrCreateActions().SetPolicyResult(nextstatementResult) // Configure multi_policy:STATEMENT5: match_aspath_set_med statement - stmt6, err := pdef1.AppendNewStatement(matchAspathSetMedStatement) + stmt5, err := pdef1.AppendNewStatement(matchAspathSetMedStatement) if err != nil { t.Fatalf("AppendNewStatement(%s) failed: %v", matchAspathSetMedStatement, err) } - stmt6.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) // TODO create as-path-set on the DUT, match-as-path-set not support. // Configure set-med 100 - stmt6.GetOrCreateActions().GetOrCreateBgpActions().SetMed = oc.UnionUint32(medValue) + stmt5.GetOrCreateActions().GetOrCreateBgpActions().SetMed = oc.UnionUint32(medValue) + + stmt5.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) // Configure the parent BGP import and export policy. + dni := deviations.DefaultNetworkInstance(dut) pathV6 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() policyV6 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() policyV6.SetImportPolicy([]string{parentPolicy}) policyV6.SetExportPolicy([]string{parentPolicy}) + policyV6.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + policyV6.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) gnmi.Replace(t, dut, pathV6.Config(), policyV6) pathV4 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(ipv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() policyV4 := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(ipv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() policyV4.SetImportPolicy([]string{parentPolicy}) policyV4.SetExportPolicy([]string{parentPolicy}) + policyV4.SetDefaultImportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + policyV4.SetDefaultExportPolicy(oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) gnmi.Replace(t, dut, pathV4.Config(), policyV4) } @@ -466,12 +482,13 @@ func verifyTrafficV4AndV6(t *testing.T, bs *cfgplugins.BGPSession, testResults [ if txPackets != rxPackets && testResults[index] { t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want < 0%% traffic loss", lossPct, "flow"+"ipv4"+strconv.Itoa(index), prefixPairV4[0], prefixPairV4[1]) - t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want < 0%% traffic loss", lossPct6, "flow"+"ipv6"+strconv.Itoa(index), prefixesV6[index][0], prefixesV6[index][1]) } else if rxPackets != 0 && !testResults[index] { t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want >100%% traffic loss", lossPct, "flow"+"ipv4"+strconv.Itoa(index), prefixPairV4[0], prefixPairV4[1]) + } else if txPackets6 != rxPackets6 && testResults[index] { + t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want < 0%% traffic loss", lossPct6, "flow"+"ipv6"+strconv.Itoa(index), prefixesV6[index][0], prefixesV6[index][1]) + } else if rxPackets6 != 0 && !testResults[index] { t.Errorf("FAIL- got %v%% packet loss for %s flow and prefixes: [%s, %s]; want >100%% traffic loss", lossPct6, "flow"+"ipv6"+strconv.Itoa(index), prefixesV6[index][0], prefixesV6[index][1]) } else { - t.Logf("Traffic validation successful for Prefixes: [%s, %s]. Result: [%t] PacketsTx: %d PacketsRx: %d", prefixPairV4[0], prefixPairV4[1], testResults[index], txPackets, rxPackets) t.Logf("Traffic validation successful for Prefixes: [%s, %s]. Result: [%t] PacketsTx: %d PacketsRx: %d", prefixesV6[index][0], prefixesV6[index][1], testResults[index], txPackets6, rxPackets6) } From f300636c622aa086c07ea7752fe6fce674b8a1bf Mon Sep 17 00:00:00 2001 From: AmrNJ <155722765+AmrNJ@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:46:58 +0530 Subject: [PATCH 73/97] Update zr_firmware_version_test.go (#2883) Updated the timeout counter for interface status check. --- .../tests/zr_firmware_version_test/zr_firmware_version_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go b/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go index 4958e4b516d..d89ac708fe8 100644 --- a/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go +++ b/feature/platform/transceiver/tests/zr_firmware_version_test/zr_firmware_version_test.go @@ -76,7 +76,7 @@ func TestZRFirmwareVersionState(t *testing.T) { t.Logf("dut1 dp1 name: %v", dp1.Name()) configInterface(t, dut1, dp1, true) configInterface(t, dut1, dp2, true) - gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), time.Minute*2, oc.Interface_OperStatus_UP) transceiverName := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) // Check if TRANSCEIVER is of type 400ZR if dp1.PMD() != ondatra.PMD400GBASEZR { From 7d92195a0b9efaeb1d7e4615b39710ba4b072f7b Mon Sep 17 00:00:00 2001 From: Wen Bo Li <50884368+wenovus@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:58:56 -0700 Subject: [PATCH 74/97] Validation Script for OC Path and RPC Coverage in READMEs (#2865) * Add yaml spec for oc path/rpc to test-requirements-template * revise yaml * revise yaml * Validation Script for OC Path and RPC Coverage in READMEs * `mdocspec` package parses ocpath.proto and ocrpcs.proto from yaml according to the format shown below by mdocspec.Parse's documentation. * `tools/validate_readme_spec/validate_readme_spec.go` script is added that can parse and then validate OC Paths and RPCs according to existing repo states in github.com/openconfig. ```go // Parse extracts sorted OpenConfig Path and RPC Coverage from an FNT README. // // The first yaml code block after a heading line named exactly as // "OpenConfig Path and RPC Coverage" will be used. Any other code blocks are // ignored. // // Expected markdown format: // // ## OpenConfig Path and RPC Coverage // // ```yaml // paths: // /interfaces/interface/config/description: // /interfaces/interface/config/enabled: // /components/component/state/name: // platform_type: "CHASSIS" // // rpcs: // gnmi: // gNMI.Set: // union_replace: true // gNMI.Subscribe: // on_change: true // ``` // // Note: For `rpcs`, only the RPC name and methods are validated. Any // attributes defined below RPC methods (e.g. union_replace) are not validated. ``` * Add invalid README example * Fix style * Make YAMLRenderer unexported * Improve comments * Update tools/internal/mdocspec/ocspec.go Co-authored-by: Darren Loher * Minor improvements for OC coverage validation * Skip repo-cloning during validation if repo already cloned. * Validate that at least one RPC method is specified for any coverage spec. * Add additional validation for script in bash file. * Style Improvements. * Improve logic by searching from header rather than YAML block * add another corner case test * add another corner case test * Improve doc comment * Improve doc comments * Fix doc comment --------- Co-authored-by: Darren Loher --- .github/workflows/readme_oc_path_and_rpc.yml | 33 + go.mod | 3 +- go.sum | 1 + tools/internal/mdocspec/md.go | 87 +++ tools/internal/mdocspec/md_test.go | 602 ++++++++++++++++++ tools/internal/mdocspec/ocspec.go | 131 ++++ tools/internal/mdocspec/ocspec_test.go | 518 +++++++++++++++ tools/internal/ocpaths/clone_public.go | 47 ++ tools/internal/ocrpcs/ocrpcs.go | 10 + tools/nosimage/validate/validate.go | 27 +- .../testdata/invalid_all_empty.md | 6 + .../testdata/invalid_empty_rpcs.md | 7 + .../testdata/invalid_heading.md | 6 + .../testdata/invalid_path.md | 9 + .../testdata/valid_empty_paths.md | 7 + .../validate_readme_spec.go | 111 ++++ .../validate_readme_spec_test.sh | 28 + 17 files changed, 1606 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/readme_oc_path_and_rpc.yml create mode 100644 tools/internal/mdocspec/md.go create mode 100644 tools/internal/mdocspec/md_test.go create mode 100644 tools/internal/mdocspec/ocspec.go create mode 100644 tools/internal/mdocspec/ocspec_test.go create mode 100644 tools/internal/ocpaths/clone_public.go create mode 100644 tools/validate_readme_spec/testdata/invalid_all_empty.md create mode 100644 tools/validate_readme_spec/testdata/invalid_empty_rpcs.md create mode 100644 tools/validate_readme_spec/testdata/invalid_heading.md create mode 100644 tools/validate_readme_spec/testdata/invalid_path.md create mode 100644 tools/validate_readme_spec/testdata/valid_empty_paths.md create mode 100644 tools/validate_readme_spec/validate_readme_spec.go create mode 100755 tools/validate_readme_spec/validate_readme_spec_test.sh diff --git a/.github/workflows/readme_oc_path_and_rpc.yml b/.github/workflows/readme_oc_path_and_rpc.yml new file mode 100644 index 00000000000..98d120d02b2 --- /dev/null +++ b/.github/workflows/readme_oc_path_and_rpc.yml @@ -0,0 +1,33 @@ +name: README OpenConfig Path and RPC Coverage + +on: + push: + branches: [ main ] + pull_request: + schedule: + - cron: "49 0 * * *" + +jobs: + integration-test: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v3 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: stable + cache: false + + - name: Validate Validation Script + run: | + cd tools/validate_readme_spec + ./validate_readme_spec_test.sh + + - name: Validate Template README + run: | + go run tools/validate_readme_spec/validate_readme_spec.go -alsologtostderr doc/test-requirements-template.md; rm -rf tmp + + - name: Validate Test READMEs + run: | + # TODO: Add READMEs here that have converted to the new format. diff --git a/go.mod b/go.mod index 5f0d029e085..217b05894c9 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/pborman/uuid v1.2.1 github.com/protocolbuffers/txtpbfmt v0.0.0-20220608084003-fc78c767cd6a github.com/yoheimuta/go-protoparser/v4 v4.9.0 + github.com/yuin/goldmark v1.4.13 golang.org/x/crypto v0.21.0 golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 golang.org/x/text v0.14.0 @@ -43,6 +44,7 @@ require ( google.golang.org/grpc v1.63.0 google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 k8s.io/klog/v2 v2.100.1 ) @@ -159,7 +161,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.26.3 // indirect k8s.io/apimachinery v0.26.3 // indirect k8s.io/client-go v0.26.3 // indirect diff --git a/go.sum b/go.sum index 21b80a0a0b3..037ee5d349d 100644 --- a/go.sum +++ b/go.sum @@ -1812,6 +1812,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= diff --git a/tools/internal/mdocspec/md.go b/tools/internal/mdocspec/md.go new file mode 100644 index 00000000000..2fa9005e998 --- /dev/null +++ b/tools/internal/mdocspec/md.go @@ -0,0 +1,87 @@ +package mdocspec + +import ( + "io" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/renderer" +) + +const ( + // OCSpecHeading is the MarkDown heading that MUST precede the yaml + // section containing the OC path and RPC listing. + OCSpecHeading = "OpenConfig Path and RPC Coverage" +) + +type mdOCSpecs struct{} + +// MDOCSpecs is an extension that only renders the first yaml block from a +// functional test README that comes after the pre-established OC Spec heading +// `OCSpecHeading`. +var MDOCSpecs = &mdOCSpecs{} + +func (e *mdOCSpecs) Extend(m goldmark.Markdown) { + extension.GFM.Extend(m) + m.SetRenderer(&yamlRenderer{}) +} + +type yamlRenderer struct{} + +func (r *yamlRenderer) Render(w io.Writer, source []byte, n ast.Node) error { + return ast.Walk(n, func(n ast.Node, entering bool) (ast.WalkStatus, error) { + return renderYAML(w, source, n, entering) + }) +} + +func (r *yamlRenderer) AddOptions(...renderer.Option) {} + +func ocSpecHeading(source []byte, n ast.Node) (heading *ast.Heading, ok bool) { + if h, ok := n.(*ast.Heading); ok { + headingSegment := h.Lines().At(0) + if string(headingSegment.Value(source)) == OCSpecHeading { + return h, true + } + } + return nil, false +} + +func yamlCodeBlock(source []byte, n ast.Node) (block *ast.FencedCodeBlock, ok bool) { + if c, ok := n.(*ast.FencedCodeBlock); ok && c.Info != nil { + if lang := c.Info.Text(source); len(lang) > 0 && string(lang) == "yaml" { + return c, true + } + } + return nil, false +} + +func renderYAML(w io.Writer, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + return ast.WalkContinue, nil + } + heading, ok := ocSpecHeading(source, n) + if !ok { + return ast.WalkContinue, nil + } + // Check if prior to the next heading of the same level, + // a yaml code block can be found. + for next := heading.NextSibling(); next != nil; next = next.NextSibling() { + if h, ok := next.(*ast.Heading); ok && h.Level <= heading.Level { + // End of heading reached. + return ast.WalkContinue, nil + } + if c, ok := yamlCodeBlock(source, next); ok { + l := c.Lines().Len() + for i := 0; i != l; i++ { + line := c.Lines().At(i) + if _, err := w.Write(line.Value(source)); err != nil { + return ast.WalkStop, err + } + } + // Stop after finding the first such YAML block. + return ast.WalkStop, nil + } + } + return ast.WalkContinue, nil +} diff --git a/tools/internal/mdocspec/md_test.go b/tools/internal/mdocspec/md_test.go new file mode 100644 index 00000000000..74467f16bf1 --- /dev/null +++ b/tools/internal/mdocspec/md_test.go @@ -0,0 +1,602 @@ +package mdocspec + +import ( + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/yuin/goldmark" +) + +func TestRenderer(t *testing.T) { + tests := []struct { + desc string + inSource []byte + want string + }{{ + desc: "basic", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +# Instructions for this template + +Below is the required template for writing test requirements. Good examples of test +requirements include: + +* [TE-3.7: Base Hierarchical NHG Update](/feature/gribi/otg_tests/base_hierarchical_nhg_update/README.md) +* [gNMI-1.13: Telemetry: Optics Power and Bias Current](https://github.com/openconfig/featureprofiles/blob/main/feature/platform/tests/optics_power_and_bias_current_test/README.md) +* [RT-5.1: Singleton Interface](https://github.com/openconfig/featureprofiles/blob/main/feature/interface/singleton/otg_tests/singleton_test/README.md) + +# TestID-x.y: Short name of test here + +## Summary + +Write a few sentences or paragraphs describing the purpose and scope of the test. + +## Testbed type + +* Specify the .testbed topology file from the [topologies](https://github.com/openconfig/featureprofiles/tree/main/topologies) folder to be used with this test + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +` + "```" + ` + +## Required DUT platform + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: `paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +`, + }, { + desc: "second-yaml-block-in-separate-heading", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +` + "```" + ` + +## Required DUT platform + +` + "```" + `yaml +paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +` + "```" + ` + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: `paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +`, + }, { + desc: "two-yaml-blocks-same-heading", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +` + "```" + ` + +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +` + "```" + ` + +## Required DUT platform + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: `paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +`, + }, { + desc: "yaml-block-after-next-heading-ignored", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +## Required DUT platform + +` + "```" + `yaml +paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +` + "```" + ` + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: ``, + }, { + desc: "yaml-block-after-next-higher-heading-ignored", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +# Required DUT platform + +Some text + +` + "```" + `yaml +paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +` + "```" + ` + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: ``, + }, { + desc: "yaml-block-after-next-lower-heading-accepted", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +### Required DUT platform + +Some text + +` + "```" + `yaml +paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +` + "```" + ` + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: `paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +`, + }, { + desc: "two-blocks-same-heading-first-language-not-specified-and-ignored", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + ` +paths: + # interface configuration + /a/b/c: + /d/e/f: + +rpcs: + fooi: + fooi.Set: + union_replace: true + fooi.Subscribe: + on_change: true +` + "```" + ` + +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +` + "```" + ` + +## Required DUT platform + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: `paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true +`, + }, { + desc: "no-yaml-blocks", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +## Required DUT platform + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: ``, + }, { + desc: "no-yaml-blocks-last-heading", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`), + want: ``, + }} + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + var buf strings.Builder + md := goldmark.New( + goldmark.WithExtensions(MDOCSpecs), + ) + if err := md.Convert(tt.inSource, &buf); err != nil { + t.Fatalf("MDOCSpecs.Convert: %v", err) + } + if diff := cmp.Diff(tt.want, buf.String()); diff != "" { + t.Errorf("MDOCSpecs.Convert (-want, +got):\n%s", diff) + } + }) + } +} diff --git a/tools/internal/mdocspec/ocspec.go b/tools/internal/mdocspec/ocspec.go new file mode 100644 index 00000000000..8233ffba588 --- /dev/null +++ b/tools/internal/mdocspec/ocspec.go @@ -0,0 +1,131 @@ +// Package mdocspec parses yaml OC requirements from functional test READMEs. +package mdocspec + +import ( + "bytes" + "fmt" + "sort" + + "github.com/yuin/goldmark" + "golang.org/x/exp/maps" + "gopkg.in/yaml.v3" + + ppb "github.com/openconfig/featureprofiles/proto/ocpaths_go_proto" + rpb "github.com/openconfig/featureprofiles/proto/ocrpcs_go_proto" +) + +// ErrNotFound indicates the OpenConfig Path and RPC Coverage YAML block was +// not found or was invalid. +var ErrNotFound = fmt.Errorf(`did not detect valid yaml block under a heading titled %q, please see https://github.com/openconfig/featureprofiles/blob/main/doc/test-requirements-template.md for example`, OCSpecHeading) + +// Parse extracts sorted OpenConfig Path and RPC Coverage from a +// featureprofiles README. +// +// If such a coverage section is not found in the README, `ErrNotFound` will be +// returned. +// +// Expected markdown format: +// +// ## OpenConfig Path and RPC Coverage +// +// ```yaml +// paths: +// /interfaces/interface/config/description: +// /interfaces/interface/config/enabled: +// /components/component/state/name: +// platform_type: "CHASSIS" +// +// rpcs: +// gnmi: +// gNMI.Set: +// union_replace: true +// gNMI.Subscribe: +// on_change: true +// ``` +// +// The first yaml code block after a heading line named exactly as +// "OpenConfig Path and RPC Coverage" will be parsed. Any other code blocks are +// ignored. +func Parse(source []byte) (*ppb.OCPaths, *rpb.OCRPCs, error) { + var buf bytes.Buffer + md := goldmark.New( + goldmark.WithExtensions(MDOCSpecs), + ) + if err := md.Convert(source, &buf); err != nil { + return nil, nil, fmt.Errorf("MDOCSpec.Convert: %v", err) + } + if buf.Len() == 0 { + return nil, nil, ErrNotFound + } + + return parseYAML(buf.Bytes()) +} + +func parseYAML(source []byte) (*ppb.OCPaths, *rpb.OCRPCs, error) { + s := map[string]map[string]map[string]any{} + if err := yaml.Unmarshal(source, &s); err != nil { + return nil, nil, fmt.Errorf("mdocspec: error parsing YAML: %v", err) + } + + protoPaths := &ppb.OCPaths{} + + paths := s["paths"] + pathNames := maps.Keys(paths) + sort.Strings(pathNames) + for _, name := range pathNames { + var platformType string + for propertyName, property := range paths[name] { + switch propertyName { + case "platform_type": + p, ok := property.(string) + if !ok { + return nil, nil, fmt.Errorf("mdocspec: only string values expected for `platform_type` attribute, got (%T, %v)", property, property) + } + platformType = p + default: + return nil, nil, fmt.Errorf("mdocspec: only `platform_type` is expected as a valid attribute for paths, got %q", propertyName) + } + } + ocPath := &ppb.OCPath{ + Name: name, + } + if platformType != "" { + ocPath.OcpathConstraint = &ppb.OCPathConstraint{ + Constraint: &ppb.OCPathConstraint_PlatformType{ + PlatformType: platformType, + }, + } + } + protoPaths.Ocpaths = append(protoPaths.Ocpaths, ocPath) + } + + protoRPCs := &rpb.OCRPCs{ + OcProtocols: map[string]*rpb.OCProtocol{}, + } + + rpcs, ok := s["rpcs"] + if !ok { + return nil, nil, fmt.Errorf("mdocspec: YAML does not have mandatory top-level \"rpcs\" attribute") + } + rpcNames := maps.Keys(rpcs) + sort.Strings(rpcNames) + var hasMethod bool + for _, name := range rpcNames { + methods := maps.Keys(rpcs[name]) + if len(methods) > 0 { + hasMethod = true + } + sort.Strings(methods) + for i, method := range methods { + methods[i] = name + "." + method + } + protoRPCs.OcProtocols[name] = &rpb.OCProtocol{ + MethodName: methods, + } + } + if !hasMethod { + return nil, nil, fmt.Errorf("mdocspec: YAML does not have least one RPC method specified") + } + + return protoPaths, protoRPCs, nil +} diff --git a/tools/internal/mdocspec/ocspec_test.go b/tools/internal/mdocspec/ocspec_test.go new file mode 100644 index 00000000000..1c749ef07ad --- /dev/null +++ b/tools/internal/mdocspec/ocspec_test.go @@ -0,0 +1,518 @@ +package mdocspec + +import ( + "errors" + "testing" + + "github.com/google/go-cmp/cmp" + ppb "github.com/openconfig/featureprofiles/proto/ocpaths_go_proto" + rpb "github.com/openconfig/featureprofiles/proto/ocrpcs_go_proto" + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/testing/protocmp" +) + +func mustOCPaths(t *testing.T, textproto string) *ppb.OCPaths { + ocPaths := &ppb.OCPaths{} + if err := prototext.Unmarshal([]byte(textproto), ocPaths); err != nil { + t.Fatal(err) + } + return ocPaths +} + +func mustOCRPCs(t *testing.T, textproto string) *rpb.OCRPCs { + ocRPCs := &rpb.OCRPCs{} + if err := prototext.Unmarshal([]byte(textproto), ocRPCs); err != nil { + t.Fatal(err) + } + return ocRPCs +} + +func TestParse(t *testing.T) { + tests := []struct { + desc string + inMD string + wantOCPaths *ppb.OCPaths + wantOCRPCs *rpb.OCRPCs + wantNotFoundErr bool + wantErr bool + }{{ + desc: "good", + inMD: `--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +# Instructions for this template + +Below is the required template for writing test requirements. Good examples of test +requirements include: + +* [TE-3.7: Base Hierarchical NHG Update](/feature/gribi/otg_tests/base_hierarchical_nhg_update/README.md) +* [gNMI-1.13: Telemetry: Optics Power and Bias Current](https://github.com/openconfig/featureprofiles/blob/main/feature/platform/tests/optics_power_and_bias_current_test/README.md) +* [RT-5.1: Singleton Interface](https://github.com/openconfig/featureprofiles/blob/main/feature/interface/singleton/otg_tests/singleton_test/README.md) + +# TestID-x.y: Short name of test here + +## Summary + +Write a few sentences or paragraphs describing the purpose and scope of the test. + +## Testbed type + +* Specify the .testbed topology file from the [topologies](https://github.com/openconfig/featureprofiles/tree/main/topologies) folder to be used with this test + +## Procedure + +* Test environment setup + * Description of procedure to configure ATE and DUT with pre-requisites making it possible to cover the intended paths and RPC's. + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +* TestID-x.y.z - Name of subtest + * Step 1 + * Step 2 + * Validation and pass/fail criteria + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true + gnoi: + healthz.Healthz.Get: + healthz.Healthz.List: + healthz.Healthz.Acknowledge: + healthz.Healthz.Artifact: + healthz.Healthz.Check: + bgp.BGP.ClearBGPNeighbor: +` + "```" + ` + +## Required DUT platform + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device +`, + wantOCPaths: mustOCPaths(t, ` +ocpaths: { + name: "/components/component/state/name" + ocpath_constraint: { + platform_type: "CHASSIS" + } +} +ocpaths: { + name: "/interfaces/interface/config/description" +} +ocpaths: { + name: "/interfaces/interface/config/enabled" +} +`), + wantOCRPCs: mustOCRPCs(t, ` +oc_protocols: { + key: "gnmi" + value: { + method_name: "gnmi.gNMI.Set" + method_name: "gnmi.gNMI.Subscribe" + } +} +oc_protocols: { + key: "gnoi" + value: { + method_name: "gnoi.bgp.BGP.ClearBGPNeighbor" + method_name: "gnoi.healthz.Healthz.Acknowledge" + method_name: "gnoi.healthz.Healthz.Artifact" + method_name: "gnoi.healthz.Healthz.Check" + method_name: "gnoi.healthz.Healthz.Get" + method_name: "gnoi.healthz.Healthz.List" + } +} +`), + }, { + desc: "empty", + inMD: ``, + wantNotFoundErr: true, + wantErr: true, + }, { + desc: "no-heading", + inMD: ` +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +` + "```" + ` + `, + wantNotFoundErr: true, + wantErr: true, + }, { + desc: "zero-rpcs", + inMD: `--- +name: New featureprofiles test requirement +--- + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" +rpcs: +` + "```" + ` + +## Required DUT platform +`, + wantErr: true, + }, { + desc: "no-rpcs", + inMD: `--- +name: New featureprofiles test requirement +--- + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +` + "```" + ` + +## Required DUT platform +`, + wantErr: true, + }, { + desc: "zero-paths-one-rpc", + inMD: ` +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: +rpcs: + gnoi: + healthz.Healthz.Get: +` + "```" + ` + +## Required DUT platform +`, + wantOCPaths: mustOCPaths(t, ``), + wantOCRPCs: mustOCRPCs(t, ` +oc_protocols: { + key: "gnoi" + value: { + method_name: "gnoi.healthz.Healthz.Get" + } +} +`), + }, { + desc: "no-paths-one-rpc", + inMD: ` +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +rpcs: + gnoi: + healthz.Healthz.Get: +` + "```" + ` + +## Required DUT platform +`, + wantOCPaths: mustOCPaths(t, ``), + wantOCRPCs: mustOCRPCs(t, ` +oc_protocols: { + key: "gnoi" + value: { + method_name: "gnoi.healthz.Healthz.Get" + } +} +`), + }, { + desc: "zero-paths-one-rpc-zero-methods", + inMD: ` +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: +rpcs: + gnoi: +` + "```" + ` + +## Required DUT platform +`, + wantErr: true, + }, { + desc: "zero-paths-zero-rpcs", + inMD: ` +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +paths: +rpcs: +` + "```" + ` + +## Required DUT platform +`, + wantErr: true, + }} + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + gotOCPaths, gotOCRPCs, err := Parse([]byte(tt.inMD)) + if gotNotFoundErr := errors.Is(err, ErrNotFound); gotNotFoundErr != tt.wantNotFoundErr { + t.Fatalf("Parse gotNotFoundErr: %v, wantNotFoundErr: %v", gotNotFoundErr, tt.wantNotFoundErr) + } + if gotErr := err != nil; gotErr != tt.wantErr { + t.Fatalf("Parse gotErr: %v, wantErr: %v", err, tt.wantErr) + } + if diff := cmp.Diff(tt.wantOCPaths, gotOCPaths, protocmp.Transform()); diff != "" { + t.Errorf("Parse OCPaths (-want, +got):\n%s", diff) + } + if diff := cmp.Diff(tt.wantOCRPCs, gotOCRPCs, protocmp.Transform()); diff != "" { + t.Errorf("Parse OCRPCs (-want, +got):\n%s", diff) + } + }) + } +} + +func TestParseYAML(t *testing.T) { + tests := []struct { + desc string + inYAML string + wantOCPaths *ppb.OCPaths + wantOCRPCs *rpb.OCRPCs + wantErr bool + }{{ + desc: "good", + inYAML: `paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true + gnoi: + healthz.Healthz.Get: + healthz.Healthz.List: + healthz.Healthz.Acknowledge: + healthz.Healthz.Artifact: + healthz.Healthz.Check: + bgp.BGP.ClearBGPNeighbor: +`, + wantOCPaths: mustOCPaths(t, ` +ocpaths: { + name: "/components/component/state/name" + ocpath_constraint: { + platform_type: "CHASSIS" + } +} +ocpaths: { + name: "/interfaces/interface/config/description" +} +ocpaths: { + name: "/interfaces/interface/config/enabled" +} +`), + wantOCRPCs: mustOCRPCs(t, ` +oc_protocols: { + key: "gnmi" + value: { + method_name: "gnmi.gNMI.Set" + method_name: "gnmi.gNMI.Subscribe" + } +} +oc_protocols: { + key: "gnoi" + value: { + method_name: "gnoi.bgp.BGP.ClearBGPNeighbor" + method_name: "gnoi.healthz.Healthz.Acknowledge" + method_name: "gnoi.healthz.Healthz.Artifact" + method_name: "gnoi.healthz.Healthz.Check" + method_name: "gnoi.healthz.Healthz.Get" + method_name: "gnoi.healthz.Healthz.List" + } +} +`), + }, { + desc: "missing-rpcs", + inYAML: `paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" +`, + wantErr: true, + }, { + desc: "missing-paths", + inYAML: `rpcs: + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true + gnoi: + healthz.Healthz.Get: + healthz.Healthz.List: + healthz.Healthz.Acknowledge: + healthz.Healthz.Artifact: + healthz.Healthz.Check: + bgp.BGP.ClearBGPNeighbor: +`, + wantOCPaths: mustOCPaths(t, ``), + wantOCRPCs: mustOCRPCs(t, ` +oc_protocols: { + key: "gnmi" + value: { + method_name: "gnmi.gNMI.Set" + method_name: "gnmi.gNMI.Subscribe" + } +} +oc_protocols: { + key: "gnoi" + value: { + method_name: "gnoi.bgp.BGP.ClearBGPNeighbor" + method_name: "gnoi.healthz.Healthz.Acknowledge" + method_name: "gnoi.healthz.Healthz.Artifact" + method_name: "gnoi.healthz.Healthz.Check" + method_name: "gnoi.healthz.Healthz.Get" + method_name: "gnoi.healthz.Healthz.List" + } +} +`), + }, { + desc: "empty", + inYAML: ``, + wantErr: true, + }, { + desc: "extra-spaces", + inYAML: ` +paths: + # interface configuration + /interfaces/interface/config/description: + /interfaces/interface/config/enabled: + # name of chassis component + /components/component/state/name: + platform_type: "CHASSIS" + + + +rpcs: + + + gnmi: + gNMI.Set: + union_replace: true + gNMI.Subscribe: + on_change: true + gnoi: + healthz.Healthz.Get: + healthz.Healthz.List: + healthz.Healthz.Acknowledge: + healthz.Healthz.Artifact: + healthz.Healthz.Check: + bgp.BGP.ClearBGPNeighbor: + +`, + wantOCPaths: mustOCPaths(t, ` +ocpaths: { + name: "/components/component/state/name" + ocpath_constraint: { + platform_type: "CHASSIS" + } +} +ocpaths: { + name: "/interfaces/interface/config/description" +} +ocpaths: { + name: "/interfaces/interface/config/enabled" +} +`), + wantOCRPCs: mustOCRPCs(t, ` +oc_protocols: { + key: "gnmi" + value: { + method_name: "gnmi.gNMI.Set" + method_name: "gnmi.gNMI.Subscribe" + } +} +oc_protocols: { + key: "gnoi" + value: { + method_name: "gnoi.bgp.BGP.ClearBGPNeighbor" + method_name: "gnoi.healthz.Healthz.Acknowledge" + method_name: "gnoi.healthz.Healthz.Artifact" + method_name: "gnoi.healthz.Healthz.Check" + method_name: "gnoi.healthz.Healthz.Get" + method_name: "gnoi.healthz.Healthz.List" + } +} +`), + }} + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + gotOCPaths, gotOCRPCs, err := parseYAML([]byte(tt.inYAML)) + if gotErr := err != nil; gotErr != tt.wantErr { + t.Fatalf("parseYAML gotErr: %v, wantErr: %v", err, tt.wantErr) + } + if diff := cmp.Diff(tt.wantOCPaths, gotOCPaths, protocmp.Transform()); diff != "" { + t.Errorf("parseYAML OCPaths (-want, +got):\n%s", diff) + } + if diff := cmp.Diff(tt.wantOCRPCs, gotOCRPCs, protocmp.Transform()); diff != "" { + t.Errorf("parseYAML OCRPCs (-want, +got):\n%s", diff) + } + }) + } +} diff --git a/tools/internal/ocpaths/clone_public.go b/tools/internal/ocpaths/clone_public.go new file mode 100644 index 00000000000..4821cab0db0 --- /dev/null +++ b/tools/internal/ocpaths/clone_public.go @@ -0,0 +1,47 @@ +package ocpaths + +import ( + "fmt" + "io" + "os" + "os/exec" + "path/filepath" +) + +// ClonePublicRepo clones the openconfig/public repo at the given path. +// +// - branch is the branch to be downloaded (passed to git clone -b). If it is empty then the argument will be omitted. +// +// # Note +// +// - If the "public" folder already exists, then no additional downloads will +// be made. +// - A manual deletion of the downloadPath folder is required if no longer used. +func ClonePublicRepo(downloadPath, branch string) (string, error) { + if downloadPath == "" { + return "", fmt.Errorf("must provide download path") + } + publicPath := filepath.Join(downloadPath, "public") + + if _, err := os.Stat(publicPath); err == nil { // If NO error + return publicPath, nil + } + + args := []string{"clone", "--depth", "1", "https://github.com/openconfig/public.git", publicPath} + if branch != "" { + args = append(args, "-b", branch, "--single-branch") + } + cmd := exec.Command("git", args...) + stderr, err := cmd.StderrPipe() + if err != nil { + return "", err + } + if err := cmd.Start(); err != nil { + return "", fmt.Errorf("failed to clone public repo: %v, command failed to start: %q", err, cmd.String()) + } + stderrOutput, _ := io.ReadAll(stderr) + if err := cmd.Wait(); err != nil { + return "", fmt.Errorf("failed to clone public repo: %v, command failed during execution: %q\n%s", err, cmd.String(), stderrOutput) + } + return publicPath, nil +} diff --git a/tools/internal/ocrpcs/ocrpcs.go b/tools/internal/ocrpcs/ocrpcs.go index b948c9778a0..d460d60997c 100644 --- a/tools/internal/ocrpcs/ocrpcs.go +++ b/tools/internal/ocrpcs/ocrpcs.go @@ -15,12 +15,22 @@ import ( "github.com/openconfig/gnmi/errlist" ) +// cloneAPIRepo clones the openconfig/ repo at the given path. +// +// # Note +// +// * If the folder already exists, then no additional downloads will be made. +// * A manual deletion of the folder is required if no longer used. func cloneAPIRepo(downloadPath, api string) (string, error) { if downloadPath == "" { return "", fmt.Errorf("must provide download path") } repoPath := filepath.Join(downloadPath, api) + if _, err := os.Stat(repoPath); err == nil { // If NO error + return repoPath, nil + } + cmd := exec.Command("git", "clone", "--single-branch", "--depth", "1", fmt.Sprintf("https://github.com/openconfig/%s.git", api), repoPath) stderr, err := cmd.StderrPipe() if err != nil { diff --git a/tools/nosimage/validate/validate.go b/tools/nosimage/validate/validate.go index 614fdbe8694..e6fab17705c 100644 --- a/tools/nosimage/validate/validate.go +++ b/tools/nosimage/validate/validate.go @@ -18,10 +18,7 @@ package main import ( "flag" "fmt" - "io" "os" - "os/exec" - "path/filepath" "github.com/openconfig/featureprofiles/tools/internal/ocpaths" "github.com/openconfig/featureprofiles/tools/internal/ocrpcs" @@ -58,27 +55,6 @@ func init() { config = New(nil) } -func clonePublicRepo(downloadPath, branch string) (string, error) { - if downloadPath == "" { - return "", fmt.Errorf("must provide download path") - } - publicPath := filepath.Join(config.DownloadPath, "public") - - cmd := exec.Command("git", "clone", "-b", branch, "--single-branch", "--depth", "1", "https://github.com/openconfig/public.git", publicPath) - stderr, err := cmd.StderrPipe() - if err != nil { - return "", err - } - if err := cmd.Start(); err != nil { - return "", fmt.Errorf("failed to clone public repo: %v, command failed to start: %q", err, cmd.String()) - } - stderrOutput, _ := io.ReadAll(stderr) - if err := cmd.Wait(); err != nil { - return "", fmt.Errorf("failed to clone public repo: %v, command failed during execution: %q\n%s", err, cmd.String(), stderrOutput) - } - return publicPath, nil -} - func unmarshalFile(filePath string) (*npb.NOSImageProfile, error) { if filePath == "" { return nil, fmt.Errorf("must provide non-empty file path to read from") @@ -92,7 +68,6 @@ func unmarshalFile(filePath string) (*npb.NOSImageProfile, error) { return nil, err } return profile, nil - } func main() { @@ -107,7 +82,7 @@ func main() { if err := os.MkdirAll(config.DownloadPath, 0750); err != nil { fmt.Println(fmt.Errorf("cannot create download path directory: %v", config.DownloadPath)) } - publicPath, err := clonePublicRepo(config.DownloadPath, "v"+profile.Ocpaths.GetVersion()) + publicPath, err := ocpaths.ClonePublicRepo(config.DownloadPath, "v"+profile.Ocpaths.GetVersion()) if err != nil { fmt.Println(err) os.Exit(1) diff --git a/tools/validate_readme_spec/testdata/invalid_all_empty.md b/tools/validate_readme_spec/testdata/invalid_all_empty.md new file mode 100644 index 00000000000..fafa429c9fc --- /dev/null +++ b/tools/validate_readme_spec/testdata/invalid_all_empty.md @@ -0,0 +1,6 @@ +## OpenConfig Path and RPC Coverage + +```yaml +paths: +rpcs: +``` diff --git a/tools/validate_readme_spec/testdata/invalid_empty_rpcs.md b/tools/validate_readme_spec/testdata/invalid_empty_rpcs.md new file mode 100644 index 00000000000..e52afb6b707 --- /dev/null +++ b/tools/validate_readme_spec/testdata/invalid_empty_rpcs.md @@ -0,0 +1,7 @@ +## OpenConfig Path and RPC Coverage + +```yaml +paths: + /interfaces/interface/config/name: +rpcs: +``` diff --git a/tools/validate_readme_spec/testdata/invalid_heading.md b/tools/validate_readme_spec/testdata/invalid_heading.md new file mode 100644 index 00000000000..bcaf33c72bb --- /dev/null +++ b/tools/validate_readme_spec/testdata/invalid_heading.md @@ -0,0 +1,6 @@ +## Hello world + +```yaml +paths: +rpcs: +``` diff --git a/tools/validate_readme_spec/testdata/invalid_path.md b/tools/validate_readme_spec/testdata/invalid_path.md new file mode 100644 index 00000000000..f5f7a93ed2f --- /dev/null +++ b/tools/validate_readme_spec/testdata/invalid_path.md @@ -0,0 +1,9 @@ +## OpenConfig Path and RPC Coverage + +```yaml +paths: + /interfaces/interface/config: +rpcs: + gnmi: + gNMI.Subscribe: +``` diff --git a/tools/validate_readme_spec/testdata/valid_empty_paths.md b/tools/validate_readme_spec/testdata/valid_empty_paths.md new file mode 100644 index 00000000000..3dfaf3ef72b --- /dev/null +++ b/tools/validate_readme_spec/testdata/valid_empty_paths.md @@ -0,0 +1,7 @@ +## OpenConfig Path and RPC Coverage + +```yaml +rpcs: + gnmi: + gNMI.Subscribe: +``` diff --git a/tools/validate_readme_spec/validate_readme_spec.go b/tools/validate_readme_spec/validate_readme_spec.go new file mode 100644 index 00000000000..0c37ba80872 --- /dev/null +++ b/tools/validate_readme_spec/validate_readme_spec.go @@ -0,0 +1,111 @@ +// Copyright 2023 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 +// +// https://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. + +// Command validate_readme_spec validates Paths and RPCs listed by MarkDown +// (READMEs) against the most recent repository states in +// github.com/openconfig. +// +// Note: For `rpcs`, only the RPC name and methods are validated. Any +// attributes defined below RPC methods (e.g. union_replace) are not validated. +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + log "github.com/golang/glog" + "github.com/openconfig/featureprofiles/tools/internal/mdocspec" + "github.com/openconfig/featureprofiles/tools/internal/ocpaths" + "github.com/openconfig/featureprofiles/tools/internal/ocrpcs" + "golang.org/x/exp/maps" +) + +// Config is the set of flags for this binary. +type Config struct { + DownloadPath string +} + +// New registers a flagset with the configuration needed by this binary. +func New(fs *flag.FlagSet) *Config { + c := &Config{} + + if fs == nil { + fs = flag.CommandLine + } + fs.StringVar(&c.DownloadPath, "download-path", "./tmp", "path into which to download OpenConfig GitHub repos for validation") + + return c +} + +var ( + config *Config +) + +func init() { + config = New(nil) +} + +func main() { + flag.Parse() + + files := flag.NArg() + if files == 0 { + flag.Usage() + log.Exit("Must provide README files as arguments") + } + + if err := os.MkdirAll(config.DownloadPath, 0750); err != nil { + fmt.Println(fmt.Errorf("cannot create download path directory: %v", config.DownloadPath)) + } + publicPath, err := ocpaths.ClonePublicRepo(config.DownloadPath, "") + if err != nil { + log.Exit(err) + } + + erredFiles := map[string]struct{}{} + for _, file := range flag.Args() { + log.Infof("Validating %q", file) + b, err := os.ReadFile(file) + if err != nil { + log.Exitf("Error reading file: %q", file) + } + ocPaths, ocRPCs, err := mdocspec.Parse(b) + if err != nil { + log.Errorf("file %v: %v", file, err) + erredFiles[file] = struct{}{} + continue + } + + paths, invalidPaths, err := ocpaths.ValidatePaths(ocPaths.GetOcpaths(), publicPath) + if err != nil { + log.Errorf("%q contains %d invalid OCPaths:\n%v", file, len(invalidPaths), err) + erredFiles[file] = struct{}{} + } else { + log.Infof("%q contains %d valid OCPaths\n", file, len(paths)) + } + + rpcValidCount, err := ocrpcs.ValidateRPCs(config.DownloadPath, ocRPCs.GetOcProtocols()) + if err != nil { + log.Errorf("%q contains invalid RPCs: %v", file, err) + erredFiles[file] = struct{}{} + } else { + log.Infof("%q contains %d valid OCRPCs\n", file, rpcValidCount) + } + } + if len(erredFiles) > 0 { + log.Exitf("The following files have errors:\n%v", strings.Join(maps.Keys(erredFiles), "\n")) + } +} diff --git a/tools/validate_readme_spec/validate_readme_spec_test.sh b/tools/validate_readme_spec/validate_readme_spec_test.sh new file mode 100755 index 00000000000..8731769c74a --- /dev/null +++ b/tools/validate_readme_spec/validate_readme_spec_test.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +filename=invalid_all_empty.md +if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then + echo "Validation passed, but failure expected" + exit 1 +fi +filename=invalid_empty_rpcs.md +if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then + echo "Validation passed, but failure expected" + exit 1 +fi +filename=invalid_heading.md +if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then + echo "Validation passed, but failure expected" + exit 1 +fi +filename=invalid_path.md +if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then + echo "Validation passed, but failure expected" + exit 1 +fi +filename=valid_empty_paths.md +if ! go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then + echo "Validation failed, but pass expected" + exit 1 +fi +echo "PASS" From a23545aac611a4076283ee8c67e9faa037137158 Mon Sep 17 00:00:00 2001 From: Wen Bo Li <50884368+wenovus@users.noreply.github.com> Date: Tue, 9 Apr 2024 08:57:47 -0700 Subject: [PATCH 75/97] Validate first README.md for OC path and RPC (#2881) * Add yaml spec for oc path/rpc to test-requirements-template * revise yaml * revise yaml * Validation Script for OC Path and RPC Coverage in READMEs * `mdocspec` package parses ocpath.proto and ocrpcs.proto from yaml according to the format shown below by mdocspec.Parse's documentation. * `tools/validate_readme_spec/validate_readme_spec.go` script is added that can parse and then validate OC Paths and RPCs according to existing repo states in github.com/openconfig. ```go // Parse extracts sorted OpenConfig Path and RPC Coverage from an FNT README. // // The first yaml code block after a heading line named exactly as // "OpenConfig Path and RPC Coverage" will be used. Any other code blocks are // ignored. // // Expected markdown format: // // ## OpenConfig Path and RPC Coverage // // ```yaml // paths: // /interfaces/interface/config/description: // /interfaces/interface/config/enabled: // /components/component/state/name: // platform_type: "CHASSIS" // // rpcs: // gnmi: // gNMI.Set: // union_replace: true // gNMI.Subscribe: // on_change: true // ``` // // Note: For `rpcs`, only the RPC name and methods are validated. Any // attributes defined below RPC methods (e.g. union_replace) are not validated. ``` * Add invalid README example * Fix style * Make YAMLRenderer unexported * Improve comments * Update tools/internal/mdocspec/ocspec.go Co-authored-by: Darren Loher * Minor improvements for OC coverage validation * Skip repo-cloning during validation if repo already cloned. * Validate that at least one RPC method is specified for any coverage spec. * Add additional validation for script in bash file. * Style Improvements. * Improve logic by searching from header rather than YAML block * add another corner case test * add another corner case test * Improve doc comment * Improve doc comments * Validate first README.md for OC path and RPC * README.md converted for feature/bgp/policybase/otg_tests/import_export_multi/README.md * ./tools/validate_readme_spec binary improved to allow for recursive validation. * Common constant and helper routine moved from `addrundata` to new `fpciutil` package. * README.md allow-list created (currently unused). * CI workflow now validates feature/bgp/policybase/otg_tests/import_export_multi/README.md * Fix style * Add gnmi.Set * Fix doc comment --------- Co-authored-by: Darren Loher --- .github/workflows/readme_oc_path_and_rpc.yml | 7 +- .../otg_tests/import_export_multi/README.md | 72 ++++++++++--------- tools/addrundata/case.go | 5 +- tools/addrundata/main.go | 30 +------- tools/internal/fpciutil/filepathutil.go | 54 ++++++++++++++ tools/internal/mdocspec/md.go | 17 +++++ tools/internal/mdocspec/md_test.go | 32 +++++++++ tools/internal/mdocspec/ocspec.go | 14 ++++ tools/internal/mdocspec/ocspec_test.go | 14 ++++ .../validate_readme_spec/readme_allowlist.go | 23 ++++++ .../validate_readme_spec.go | 59 +++++++++++++-- .../validate_readme_spec_test.sh | 26 +++++-- 12 files changed, 277 insertions(+), 76 deletions(-) create mode 100644 tools/internal/fpciutil/filepathutil.go create mode 100644 tools/validate_readme_spec/readme_allowlist.go diff --git a/.github/workflows/readme_oc_path_and_rpc.yml b/.github/workflows/readme_oc_path_and_rpc.yml index 98d120d02b2..1110244659f 100644 --- a/.github/workflows/readme_oc_path_and_rpc.yml +++ b/.github/workflows/readme_oc_path_and_rpc.yml @@ -26,8 +26,11 @@ jobs: - name: Validate Template README run: | - go run tools/validate_readme_spec/validate_readme_spec.go -alsologtostderr doc/test-requirements-template.md; rm -rf tmp + go install ./tools/validate_readme_spec + validate_readme_spec -alsologtostderr doc/test-requirements-template.md - name: Validate Test READMEs run: | - # TODO: Add READMEs here that have converted to the new format. + go install ./tools/validate_readme_spec + # TODO: Remove -feature-dir argument after all READMEs have converted to the new format. + validate_readme_spec -alsologtostderr -feature-dir feature/bgp/policybase/otg_tests/import_export_multi diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/README.md b/feature/bgp/policybase/otg_tests/import_export_multi/README.md index 824872838f2..6e8fca19c0c 100644 --- a/feature/bgp/policybase/otg_tests/import_export_multi/README.md +++ b/feature/bgp/policybase/otg_tests/import_export_multi/README.md @@ -176,62 +176,68 @@ This replace method should guarantee that the previous step's import-policy is r | prefix-set-5 | True | [ "40:1","40:2", "60:1", "70:1" ] | 65000 65100 | 5 | 100 | accepted and match_comm_and_prefix_add_2_community_sets | | prefix-set-6 | True | [ "10:1", "40:1", "40:2" ] | 65000 65100 | n/a | 100 | accepted | -## OpenConfig Path Coverage +## OpenConfig Path and RPC Coverage The below yaml defines the OC paths intended to be covered by this test. OC paths used for test setup are not listed here. ```yaml -config_paths: +paths: + ## Config Paths ## # Policy definition - - /routing-policy/policy-definitions/policy-definition/config/name - - /routing-policy/policy-definitions/policy-definition/statements/statement/config/name + /routing-policy/policy-definitions/policy-definition/config/name: + /routing-policy/policy-definitions/policy-definition/statements/statement/config/name: # Policy for community-set configuration - - /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/community-set-name - - /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/community-member + /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/ext-community-set-name: + /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/ext-community-member: # Policy for match configuration - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/community-set - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/match-set-options + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/community-set: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-community-set/config/match-set-options: - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-as-path-set/config/as-path-set - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-as-path-set/config/match-set-options + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-as-path-set/config/as-path-set: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-as-path-set/config/match-set-options: - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options: # Policy for bgp actions - - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/config/method - - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/config/options - - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/reference/config/community-set-ref - - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/reference/config/community-set-refs - - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-local-pref - - /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/config/method: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/config/options: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/reference/config/community-set-ref: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-community/reference/config/community-set-refs: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-local-pref: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med: # Policy for bgp attachment - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy: -state_paths: + ## State Paths ## # Policy definition state - - /routing-policy/policy-definitions/policy-definition/state/name - - /routing-policy/policy-definitions/policy-definition/statements/statement/state/name + /routing-policy/policy-definitions/policy-definition/state/name: + /routing-policy/policy-definitions/policy-definition/statements/statement/state/name: # Policy for community-set match state - - /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-set-name - - /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-member - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-ext-community-set/state/match-set-options - - /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/state/community-set + /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-set-name: + /routing-policy/defined-sets/bgp-defined-sets/community-sets/community-set/state/community-member: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/match-ext-community-set/state/match-set-options: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/bgp-conditions/state/community-set: # Paths to verify policy state - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/export-policy: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/state/import-policy: # Paths to verify prefixes sent and received - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/sent - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received-pre-policy - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received - - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/installed + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/sent: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received-pre-policy: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/received: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/installed: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: ``` ## Minimum DUT Required diff --git a/tools/addrundata/case.go b/tools/addrundata/case.go index 6be28a9404e..03fa2e8622d 100644 --- a/tools/addrundata/case.go +++ b/tools/addrundata/case.go @@ -11,6 +11,7 @@ import ( "github.com/google/uuid" mpb "github.com/openconfig/featureprofiles/proto/metadata_go_proto" + "github.com/openconfig/featureprofiles/tools/internal/fpciutil" "google.golang.org/protobuf/proto" ) @@ -23,8 +24,8 @@ type testcase struct { // read reads the markdown and existing rundata from the test directory. func (tc *testcase) read(testdir string) error { - if err := readFile(filepath.Join(testdir, "README.md"), tc.readMarkdown); err != nil { - return fmt.Errorf("could not parse README.md: %w", err) + if err := readFile(filepath.Join(testdir, fpciutil.READMEname), tc.readMarkdown); err != nil { + return fmt.Errorf("could not parse %s: %w", fpciutil.READMEname, err) } if err := readFile(filepath.Join(testdir, "metadata.textproto"), tc.readProto); err != nil && !os.IsNotExist(err) { return fmt.Errorf("could not parse metadata.textproto: %w", err) diff --git a/tools/addrundata/main.go b/tools/addrundata/main.go index 4322510e96c..dcc68dc748c 100644 --- a/tools/addrundata/main.go +++ b/tools/addrundata/main.go @@ -14,15 +14,13 @@ package main import ( - "errors" "fmt" "os" - "path/filepath" - "runtime" "flag" "github.com/golang/glog" + "github.com/openconfig/featureprofiles/tools/internal/fpciutil" ) var ( @@ -32,37 +30,13 @@ var ( mergejson = flag.String("mergejson", "", "Merge the JSON listing from this JSON file.") ) -func isDir(path string) bool { - info, err := os.Stat(path) - if err != nil { - return false - } - return info.IsDir() -} - -func featureDir() (string, error) { - _, path, _, ok := runtime.Caller(0) - if !ok { - return "", errors.New("could not detect caller") - } - newpath := filepath.Dir(path) - for newpath != "." && newpath != "/" { - featurepath := filepath.Join(newpath, "feature") - if isDir(featurepath) { - return featurepath, nil - } - newpath = filepath.Dir(newpath) - } - return "", fmt.Errorf("feature root not found from %s", path) -} - func main() { flag.Parse() featuredir := *dir if featuredir == "" { var err error - featuredir, err = featureDir() + featuredir, err = fpciutil.FeatureDir() if err != nil { glog.Exitf("Unable to locate feature root: %v", err) } diff --git a/tools/internal/fpciutil/filepathutil.go b/tools/internal/fpciutil/filepathutil.go new file mode 100644 index 00000000000..2abd4ae2062 --- /dev/null +++ b/tools/internal/fpciutil/filepathutil.go @@ -0,0 +1,54 @@ +// 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 +// +// https://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 fpciutil contains filepath related utilities for featureprofiles CI. +package fpciutil + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "runtime" +) + +const ( + // READMEname is the name of all test READMEs according to the contribution guide. + READMEname = "README.md" +) + +func isDir(path string) bool { + info, err := os.Stat(path) + if err != nil { + return false + } + return info.IsDir() +} + +// FeatureDir finds the path to the feature directory from CWD. +func FeatureDir() (string, error) { + _, path, _, ok := runtime.Caller(0) + if !ok { + return "", errors.New("could not detect caller") + } + newpath := filepath.Dir(path) + for newpath != "." && newpath != "/" { + featurepath := filepath.Join(newpath, "feature") + if isDir(featurepath) { + return featurepath, nil + } + newpath = filepath.Dir(newpath) + } + return "", fmt.Errorf("feature root not found from %s", path) +} diff --git a/tools/internal/mdocspec/md.go b/tools/internal/mdocspec/md.go index 2fa9005e998..f1fc8601bae 100644 --- a/tools/internal/mdocspec/md.go +++ b/tools/internal/mdocspec/md.go @@ -1,3 +1,17 @@ +// 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 +// +// https://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 mdocspec import ( @@ -39,6 +53,9 @@ func (r *yamlRenderer) AddOptions(...renderer.Option) {} func ocSpecHeading(source []byte, n ast.Node) (heading *ast.Heading, ok bool) { if h, ok := n.(*ast.Heading); ok { + if h.Lines().Len() == 0 { + return nil, false + } headingSegment := h.Lines().At(0) if string(headingSegment.Value(source)) == OCSpecHeading { return h, true diff --git a/tools/internal/mdocspec/md_test.go b/tools/internal/mdocspec/md_test.go index 74467f16bf1..e7b6a997c88 100644 --- a/tools/internal/mdocspec/md_test.go +++ b/tools/internal/mdocspec/md_test.go @@ -1,3 +1,17 @@ +// 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 +// +// https://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 mdocspec import ( @@ -581,6 +595,24 @@ This example yaml defines the OC paths intended to be covered by this test. OC * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components * FFF - fixed form factor * vRX - virtual router device +`), + want: ``, + }, { + desc: "yaml-block-empty", + inSource: []byte(`--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' +--- + +## OpenConfig Path and RPC Coverage + +This example yaml defines the OC paths intended to be covered by this test. OC paths used for test environment setup are not required to be listed here. + +` + "```" + `yaml +` + "```" + ` `), want: ``, }} diff --git a/tools/internal/mdocspec/ocspec.go b/tools/internal/mdocspec/ocspec.go index 8233ffba588..a40c3ff1fc0 100644 --- a/tools/internal/mdocspec/ocspec.go +++ b/tools/internal/mdocspec/ocspec.go @@ -1,3 +1,17 @@ +// 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 +// +// https://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 mdocspec parses yaml OC requirements from functional test READMEs. package mdocspec diff --git a/tools/internal/mdocspec/ocspec_test.go b/tools/internal/mdocspec/ocspec_test.go index 1c749ef07ad..92ef91d06ef 100644 --- a/tools/internal/mdocspec/ocspec_test.go +++ b/tools/internal/mdocspec/ocspec_test.go @@ -1,3 +1,17 @@ +// 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 +// +// https://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 mdocspec import ( diff --git a/tools/validate_readme_spec/readme_allowlist.go b/tools/validate_readme_spec/readme_allowlist.go new file mode 100644 index 00000000000..fb3aafbaa24 --- /dev/null +++ b/tools/validate_readme_spec/readme_allowlist.go @@ -0,0 +1,23 @@ +// 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 +// +// https://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 main + +var ( + // nonTestREADMEs are exempt from coverage spec validation. + nonTestREADMEs = map[string]struct{}{ + "security/gnsi/certz/test_data/README.md": {}, + "experimental/p4rt/README.md": {}, + } +) diff --git a/tools/validate_readme_spec/validate_readme_spec.go b/tools/validate_readme_spec/validate_readme_spec.go index 0c37ba80872..dc9bb3561aa 100644 --- a/tools/validate_readme_spec/validate_readme_spec.go +++ b/tools/validate_readme_spec/validate_readme_spec.go @@ -1,4 +1,4 @@ -// Copyright 2023 Google LLC +// 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. @@ -23,10 +23,13 @@ package main import ( "flag" "fmt" + "io/fs" "os" + "path/filepath" "strings" log "github.com/golang/glog" + "github.com/openconfig/featureprofiles/tools/internal/fpciutil" "github.com/openconfig/featureprofiles/tools/internal/mdocspec" "github.com/openconfig/featureprofiles/tools/internal/ocpaths" "github.com/openconfig/featureprofiles/tools/internal/ocrpcs" @@ -36,6 +39,7 @@ import ( // Config is the set of flags for this binary. type Config struct { DownloadPath string + FeatureDir string } // New registers a flagset with the configuration needed by this binary. @@ -46,6 +50,7 @@ func New(fs *flag.FlagSet) *Config { fs = flag.CommandLine } fs.StringVar(&c.DownloadPath, "download-path", "./tmp", "path into which to download OpenConfig GitHub repos for validation") + fs.StringVar(&c.FeatureDir, "feature-dir", "", "path to the feature directory of featureprofiles, for which all README.md files are validated for their coverage spec aside from the allow-list in readme_allowlist.go") return c } @@ -58,13 +63,55 @@ func init() { config = New(nil) } +func readmeFiles(featureDir string) ([]string, error) { + var files []string + err := filepath.WalkDir(featureDir, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.Name() != fpciutil.READMEname { + return nil + } + relpath, err := filepath.Rel(filepath.Dir(featureDir), path) + if err != nil { + return fmt.Errorf("unexpected error: cannot take relative path of file %q against feature directory %q", path, featureDir) + } + if _, ok := nonTestREADMEs[relpath]; ok { + // Allowlist + return nil + } + + files = append(files, path) + return nil + }) + return files, err +} + func main() { flag.Parse() - files := flag.NArg() - if files == 0 { - flag.Usage() - log.Exit("Must provide README files as arguments") + fileCount := flag.NArg() + var files []string + switch { + case fileCount != 0 && config.FeatureDir != "": + log.Exit("If -feature-dir flag is specified, README files must not be specified as positional arguments.") + case fileCount == 0 && config.FeatureDir == "": + var err error + config.FeatureDir, err = fpciutil.FeatureDir() + if err != nil { + log.Exitf("Unable to locate feature root: %v", err) + } + fallthrough + case config.FeatureDir != "": + var err error + files, err = readmeFiles(config.FeatureDir) + if err != nil { + log.Exitf("Error gathering README.md files for validation: %v", err) + } + case fileCount != 0: + files = flag.Args() + default: + log.Exit("Program internal error: input not handled.") } if err := os.MkdirAll(config.DownloadPath, 0750); err != nil { @@ -76,7 +123,7 @@ func main() { } erredFiles := map[string]struct{}{} - for _, file := range flag.Args() { + for _, file := range files { log.Infof("Validating %q", file) b, err := os.ReadFile(file) if err != nil { diff --git a/tools/validate_readme_spec/validate_readme_spec_test.sh b/tools/validate_readme_spec/validate_readme_spec_test.sh index 8731769c74a..faea2862eb2 100755 --- a/tools/validate_readme_spec/validate_readme_spec_test.sh +++ b/tools/validate_readme_spec/validate_readme_spec_test.sh @@ -1,27 +1,43 @@ +# 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 +# +# https://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. + #!/bin/bash +go install ./ + filename=invalid_all_empty.md -if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then +if validate_readme_spec -alsologtostderr testdata/"${filename}"; then echo "Validation passed, but failure expected" exit 1 fi filename=invalid_empty_rpcs.md -if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then +if validate_readme_spec -alsologtostderr testdata/"${filename}"; then echo "Validation passed, but failure expected" exit 1 fi filename=invalid_heading.md -if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then +if validate_readme_spec -alsologtostderr testdata/"${filename}"; then echo "Validation passed, but failure expected" exit 1 fi filename=invalid_path.md -if go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then +if validate_readme_spec -alsologtostderr testdata/"${filename}"; then echo "Validation passed, but failure expected" exit 1 fi filename=valid_empty_paths.md -if ! go run validate_readme_spec.go -alsologtostderr testdata/"${filename}"; then +if ! validate_readme_spec -alsologtostderr testdata/"${filename}"; then echo "Validation failed, but pass expected" exit 1 fi From 2ef8bf6c3b9c6b911b97997559b21c3e1054e9a5 Mon Sep 17 00:00:00 2001 From: Wen Bo Li <50884368+wenovus@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:16:45 -0700 Subject: [PATCH 76/97] Add `path_presence_test` tag in metadata.proto. (#2676) * Add `path_presence_test` tag in metadata.proto. This will mark tests that only test for path existence/validity such as https://github.com/openconfig/featureprofiles/tree/main/feature/gnmi/otg_tests/telemetry_basic_check_test so that tools (e.g. coverage tools) can have better insight on what the coverage means. * update metadata.pb.go --- .../metadata.textproto | 1 + proto/metadata.proto | 4 + proto/metadata_go_proto/metadata.pb.go | 1499 +++++++++-------- 3 files changed, 761 insertions(+), 743 deletions(-) diff --git a/feature/gnmi/otg_tests/telemetry_basic_check_test/metadata.textproto b/feature/gnmi/otg_tests/telemetry_basic_check_test/metadata.textproto index e122fbd26b8..7e0b5875853 100644 --- a/feature/gnmi/otg_tests/telemetry_basic_check_test/metadata.textproto +++ b/feature/gnmi/otg_tests/telemetry_basic_check_test/metadata.textproto @@ -67,3 +67,4 @@ platform_exceptions: { os_component_parent_is_chassis: true } } +path_presence_test: true diff --git a/proto/metadata.proto b/proto/metadata.proto index d7492900a0b..d2f8705fd8d 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -499,5 +499,9 @@ message Metadata { // The `tags` used to identify the area(s) testcase applies to. An empty tag // is the default implying it applies to all areas. repeated Tags tags = 6; + + // Whether this test only checks paths for presence rather than semantic + // checks. + bool path_presence_test = 7; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 974d864f1e0..55e37dad419 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -179,6 +179,9 @@ type Metadata struct { // The `tags` used to identify the area(s) testcase applies to. An empty tag // is the default implying it applies to all areas. Tags []Metadata_Tags `protobuf:"varint,6,rep,packed,name=tags,proto3,enum=openconfig.testing.Metadata_Tags" json:"tags,omitempty"` + // Whether this test only checks paths for presence rather than semantic + // checks. + PathPresenceTest bool `protobuf:"varint,7,opt,name=path_presence_test,json=pathPresenceTest,proto3" json:"path_presence_test,omitempty"` } func (x *Metadata) Reset() { @@ -255,6 +258,13 @@ func (x *Metadata) GetTags() []Metadata_Tags { return nil } +func (x *Metadata) GetPathPresenceTest() bool { + if x != nil { + return x.PathPresenceTest + } + return false +} + type Metadata_Platform struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1907,7 +1917,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x5f, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x5f, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1926,749 +1936,752 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0xb8, 0x01, 0x0a, - 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2e, 0x0a, 0x06, 0x76, 0x65, 0x6e, - 0x64, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6f, 0x6e, 0x64, 0x61, - 0x74, 0x72, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, - 0x72, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x61, 0x72, - 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x67, 0x65, - 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x16, 0x73, - 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, - 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, - 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, - 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x84, 0x57, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x18, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x5f, 0x6c, 0x34, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x75, 0x64, - 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x4c, 0x34, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x55, 0x64, 0x70, - 0x12, 0x3a, 0x0a, 0x19, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x72, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x17, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x28, - 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, - 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x25, - 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x57, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6c, 0x65, - 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x1f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x75, - 0x6c, 0x74, 0x69, 0x5f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, - 0x69, 0x73, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, - 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x26, - 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x31, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x69, 0x73, - 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x31, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, - 0x12, 0x41, 0x0a, 0x1d, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, - 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x69, 0x73, 0x69, 0x73, 0x53, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, 0x69, - 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x26, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x49, 0x73, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, - 0x69, 0x53, 0x61, 0x66, 0x69, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x54, 0x0a, 0x27, 0x69, - 0x73, 0x69, 0x73, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, - 0x69, 0x73, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x12, 0x58, 0x0a, 0x29, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, - 0x69, 0x74, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x69, 0x73, 0x69, 0x73, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, - 0x69, 0x74, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x21, 0x69, - 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x75, 0x70, 0x70, - 0x72, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x70, 0x5f, 0x6e, 0x65, 0x69, - 0x67, 0x68, 0x62, 0x6f, 0x72, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x70, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x4d, - 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x13, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x10, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x12, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, - 0x6f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x37, 0x0a, 0x18, 0x6f, 0x73, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, - 0x5f, 0x72, 0x70, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x6f, 0x73, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6c, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, 0x52, 0x70, - 0x12, 0x50, 0x0a, 0x25, 0x6c, 0x6c, 0x64, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, - 0x64, 0x65, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x21, 0x6c, 0x6c, 0x64, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x12, 0x55, 0x0a, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x67, - 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x15, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x42, 0x67, 0x70, - 0x4c, 0x61, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x47, 0x0a, 0x20, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x16, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x66, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x1d, 0x69, 0x70, 0x76, 0x36, - 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x67, 0x72, 0x69, 0x62, - 0x69, 0x5f, 0x6e, 0x68, 0x5f, 0x64, 0x6d, 0x61, 0x63, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x18, 0x69, 0x70, 0x76, 0x36, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x47, 0x72, - 0x69, 0x62, 0x69, 0x4e, 0x68, 0x44, 0x6d, 0x61, 0x63, 0x12, 0x45, 0x0a, 0x1f, 0x65, 0x63, 0x6e, - 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1c, 0x65, 0x63, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x45, 0x0a, 0x1f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, - 0x65, 0x64, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, 0x70, 0x76, 0x36, 0x44, - 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x50, 0x6b, 0x74, 0x73, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x64, 0x72, 0x6f, 0x70, 0x5f, - 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1b, 0x64, 0x72, 0x6f, 0x70, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, - 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x1c, - 0x63, 0x6c, 0x69, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, - 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x6f, 0x63, 0x18, 0x1d, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x18, 0x63, 0x6c, 0x69, 0x54, 0x61, 0x6b, 0x65, 0x73, 0x50, 0x72, 0x65, 0x63, - 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x4f, 0x63, 0x12, 0x3f, 0x0a, 0x1c, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, - 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x1e, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x19, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x49, 0x6e, 0x70, - 0x75, 0x74, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x3b, 0x0a, - 0x1a, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x69, 0x64, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x17, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x43, 0x68, 0x69, 0x70, 0x49, 0x64, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x25, 0x62, 0x61, - 0x63, 0x6b, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, - 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, - 0x74, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, - 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x2b, 0x6e, 0x6f, 0x5f, 0x6d, - 0x69, 0x78, 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x61, 0x6e, 0x64, - 0x5f, 0x75, 0x6e, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x6e, - 0x6f, 0x4d, 0x69, 0x78, 0x4f, 0x66, 0x54, 0x61, 0x67, 0x67, 0x65, 0x64, 0x41, 0x6e, 0x64, 0x55, - 0x6e, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, - 0x5f, 0x70, 0x34, 0x72, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x23, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x65, 0x78, 0x70, 0x6c, - 0x69, 0x63, 0x69, 0x74, 0x50, 0x34, 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x3e, 0x0a, 0x1c, 0x75, 0x73, 0x65, 0x5f, 0x76, 0x65, 0x6e, - 0x64, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x24, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x75, 0x73, 0x65, - 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41, 0x63, 0x6c, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x77, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, - 0x25, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x73, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x21, 0x65, - 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x26, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x44, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x1d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x27, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x65, 0x78, - 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x75, 0x6e, 0x64, - 0x65, 0x72, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x65, 0x78, 0x70, 0x6c, 0x69, - 0x63, 0x69, 0x74, 0x47, 0x72, 0x69, 0x62, 0x69, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x4e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, - 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x70, - 0x65, 0x65, 0x64, 0x18, 0x29, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x65, 0x78, 0x70, 0x6c, 0x69, - 0x63, 0x69, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, - 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, - 0x66, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, - 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x44, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x56, 0x72, 0x66, 0x12, 0x2c, 0x0a, 0x12, 0x71, 0x6f, 0x73, 0x5f, 0x64, 0x72, - 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x2b, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x71, 0x6f, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4f, 0x63, - 0x74, 0x65, 0x74, 0x73, 0x12, 0x4f, 0x0a, 0x24, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x2c, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x21, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x4d, 0x69, - 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x22, 0x67, 0x72, - 0x69, 0x62, 0x69, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x72, 0x70, - 0x18, 0x2e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x67, 0x72, 0x69, 0x62, 0x69, 0x4d, 0x61, 0x63, - 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x72, 0x70, 0x12, 0x4a, 0x0a, 0x22, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x66, 0x69, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x2f, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x6e, - 0x64, 0x65, 0x72, 0x41, 0x66, 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x56, 0x0a, 0x28, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, - 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x62, 0x6f, 0x6f, - 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x30, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x24, 0x67, 0x6e, 0x6f, 0x69, 0x46, 0x61, 0x62, 0x72, 0x69, 0x63, 0x43, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x55, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x6e, 0x74, 0x70, - 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x31, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1b, 0x6e, 0x74, 0x70, 0x4e, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x56, 0x72, 0x66, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x1e, 0x0a, 0x0b, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x6c, 0x32, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0x32, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6f, 0x6d, 0x69, 0x74, 0x4c, 0x32, 0x4d, 0x74, 0x75, 0x12, - 0x46, 0x0a, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x18, 0x33, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, - 0x65, 0x72, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x6e, 0x6e, 0x65, - 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x18, 0x3c, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x13, 0x62, 0x67, 0x70, 0x5f, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x11, 0x62, 0x67, 0x70, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x4d, 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x61, 0x6c, 0x5f, - 0x77, 0x61, 0x69, 0x74, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1f, 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x61, 0x6c, 0x57, 0x61, 0x69, 0x74, 0x41, 0x66, - 0x74, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x18, 0x3f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x67, 0x6e, 0x6f, 0x69, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x56, 0x0a, 0x28, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x18, 0x40, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x33, - 0x0a, 0x16, 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x64, 0x35, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, 0x18, 0x41, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, - 0x62, 0x67, 0x70, 0x4d, 0x64, 0x35, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x65, 0x74, 0x12, 0x4b, 0x0a, 0x23, 0x64, 0x65, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, - 0x64, 0x5f, 0x61, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x42, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1e, 0x64, 0x65, 0x71, 0x75, 0x65, 0x75, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, - 0x6f, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x41, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x73, - 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x72, 0x69, 0x62, 0x61, 0x63, 0x6b, - 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x43, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x67, 0x72, 0x69, - 0x62, 0x69, 0x52, 0x69, 0x62, 0x61, 0x63, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x36, 0x0a, 0x17, - 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, - 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x44, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x61, - 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x73, 0x18, 0x45, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x73, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x12, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x75, 0x62, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x47, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x14, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4c, 0x0a, 0x23, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x72, - 0x66, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x48, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x72, 0x66, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x72, 0x65, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x76, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x49, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x56, - 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x58, 0x0a, 0x2a, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x6d, - 0x61, 0x63, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x5f, 0x61, 0x72, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x67, 0x72, 0x69, 0x62, 0x69, - 0x4d, 0x61, 0x63, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x41, 0x72, 0x70, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, - 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x18, 0x4b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x71, 0x6f, 0x73, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x71, 0x6f, 0x73, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, - 0x70, 0x75, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x18, 0x4d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x70, 0x75, 0x4d, 0x69, - 0x73, 0x73, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x12, 0x41, 0x0a, - 0x1d, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x5f, - 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x30, 0x18, 0x4e, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x30, - 0x12, 0x5f, 0x0a, 0x2d, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x6f, - 0x76, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x4f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x77, 0x69, - 0x74, 0x63, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x4d, 0x69, 0x73, - 0x73, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, - 0x64, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x50, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x24, 0x70, - 0x34, 0x72, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x18, 0x51, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x70, 0x34, 0x72, 0x74, 0x55, - 0x6e, 0x73, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, - 0x62, 0x6b, 0x75, 0x70, 0x5f, 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x72, 0x65, 0x73, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x52, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x17, 0x62, 0x6b, 0x75, 0x70, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x49, 0x0a, 0x22, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x5f, 0x6e, 0x68, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, - 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x18, - 0x53, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4e, 0x68, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x56, 0x72, 0x66, 0x57, 0x69, 0x74, 0x68, 0x44, - 0x65, 0x63, 0x61, 0x70, 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x55, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, - 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, 0x69, 0x55, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x23, 0x70, 0x34, 0x72, - 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x18, 0x56, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x70, 0x34, 0x72, 0x74, 0x4d, 0x6f, 0x64, 0x69, - 0x66, 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5e, 0x0a, 0x2d, 0x6f, 0x73, 0x5f, 0x63, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, - 0x73, 0x5f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x5f, 0x6f, 0x72, 0x5f, - 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x18, 0x57, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, - 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x49, 0x73, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x4f, 0x72, 0x4c, - 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x12, 0x42, 0x0a, 0x1e, 0x6f, 0x73, 0x5f, 0x63, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, - 0x73, 0x5f, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1a, 0x6f, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x49, 0x73, 0x43, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x12, 0x57, 0x0a, 0x2a, 0x69, - 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x65, - 0x5f, 0x6c, 0x31, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, - 0x6c, 0x32, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x23, 0x69, 0x73, 0x69, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x65, - 0x4c, 0x31, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x32, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x12, 0x57, 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, - 0x6d, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x65, 0x71, 0x75, - 0x61, 0x6c, 0x5f, 0x6f, 0x73, 0x70, 0x66, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x62, 0x67, 0x70, 0x53, 0x65, 0x74, - 0x4d, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x45, 0x71, 0x75, 0x61, 0x6c, - 0x4f, 0x73, 0x70, 0x66, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x4e, 0x0a, - 0x24, 0x70, 0x34, 0x72, 0x74, 0x5f, 0x67, 0x64, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x73, 0x5f, 0x64, 0x6f, 0x74, 0x31, 0x71, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x34, 0x72, - 0x74, 0x47, 0x64, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x44, 0x6f, 0x74, 0x31, - 0x71, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x59, 0x0a, - 0x2a, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x5e, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x25, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x74, 0x5f, - 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x5f, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0d, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x55, 0x73, 0x65, 0x72, - 0x12, 0x73, 0x0a, 0x38, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6c, 0x69, 0x66, - 0x65, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x60, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x31, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4c, 0x69, 0x66, 0x65, 0x74, - 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x73, 0x4c, 0x73, 0x70, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x4f, 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, - 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x62, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x21, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, - 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x53, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x18, 0x63, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x2b, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, - 0x70, 0x75, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, - 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x61, 0x62, - 0x72, 0x69, 0x63, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x65, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1c, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x55, 0x0a, 0x27, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x71, 0x6f, 0x73, 0x5f, 0x76, - 0x6f, 0x71, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1c, 0x71, 0x6f, 0x73, 0x56, 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x65, 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x44, 0x0a, 0x1f, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, - 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0x68, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, - 0x36, 0x46, 0x6c, 0x6f, 0x77, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x72, 0x73, 0x5f, 0x63, 0x73, 0x6e, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x69, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, - 0x43, 0x73, 0x6e, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, 0x37, 0x69, 0x73, 0x69, 0x73, 0x5f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x72, 0x6f, 0x6d, - 0x5f, 0x61, 0x72, 0x65, 0x61, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x30, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x72, 0x65, 0x61, 0x73, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, - 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x5f, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0x6b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x22, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0x6c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x67, 0x6e, 0x6d, 0x69, 0x18, 0x6d, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, - 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x61, 0x77, 0x47, 0x6e, - 0x6d, 0x69, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x74, 0x63, 0x70, 0x5f, 0x6e, - 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x73, 0x73, 0x5f, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x6b, 0x69, 0x70, 0x54, - 0x63, 0x70, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x73, 0x73, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x12, 0x4c, 0x0a, 0x23, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, - 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x73, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6f, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1f, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x4c, 0x65, 0x61, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x31, 0x0a, 0x15, 0x71, 0x6f, 0x73, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x70, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x12, 0x71, 0x6f, 0x73, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x73, 0x49, 0x64, 0x12, 0x55, 0x0a, 0x28, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x66, 0x69, - 0x62, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, - 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x18, 0x71, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x69, 0x62, - 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x46, 0x6f, 0x72, - 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x50, 0x0a, 0x25, - 0x71, 0x6f, 0x73, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x72, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x71, 0x6f, 0x73, - 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x66, - 0x0a, 0x31, 0x62, 0x67, 0x70, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x65, - 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0x73, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, 0x62, 0x67, 0x70, 0x47, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x4e, 0x65, 0x78, 0x74, - 0x48, 0x6f, 0x70, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x15, 0x62, 0x67, 0x70, 0x5f, 0x6c, 0x6c, - 0x67, 0x72, 0x5f, 0x6f, 0x63, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x18, - 0x74, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x62, 0x67, 0x70, 0x4c, 0x6c, 0x67, 0x72, 0x4f, 0x63, - 0x55, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x74, 0x75, 0x6e, - 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x75, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1a, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, - 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, - 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x76, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x51, 0x0a, 0x26, 0x65, 0x63, 0x6e, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6d, 0x69, - 0x6e, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x77, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x21, 0x65, 0x63, 0x6e, 0x53, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x4d, 0x61, 0x78, - 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x71, 0x6f, 0x73, 0x5f, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x78, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, - 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x71, 0x6f, 0x73, 0x5f, 0x73, - 0x65, 0x74, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x79, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1d, 0x71, 0x6f, 0x73, 0x53, 0x65, 0x74, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x42, 0x0a, 0x1e, 0x71, 0x6f, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0x7a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x65, - 0x76, 0x65, 0x6c, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x7b, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x10, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x7c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x49, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x47, 0x0a, - 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x6f, 0x6f, - 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x18, 0x7d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, - 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4d, 0x0a, 0x24, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, - 0x6c, 0x71, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x65, - 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x7e, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x6c, 0x71, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x4a, 0x0a, 0x22, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x70, - 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x7f, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1e, 0x62, 0x67, 0x70, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x50, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, - 0x64, 0x12, 0x58, 0x0a, 0x29, 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, - 0x5f, 0x6f, 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x80, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x4f, 0x63, 0x4d, 0x61, 0x78, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x26, 0x73, - 0x6b, 0x69, 0x70, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x5f, 0x61, 0x66, - 0x69, 0x73, 0x61, 0x66, 0x69, 0x18, 0x81, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x73, 0x6b, - 0x69, 0x70, 0x42, 0x67, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x57, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x41, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, 0x12, - 0x62, 0x0a, 0x2e, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x68, 0x61, - 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x18, 0x82, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x64, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x68, - 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, - 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x83, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x2c, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5d, 0x0a, - 0x2b, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, - 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x84, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x27, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, - 0x85, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x6e, 0x42, - 0x67, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x12, 0x55, 0x0a, 0x27, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x86, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x53, 0x74, 0x79, 0x6c, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x55, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, - 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x87, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x29, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x66, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3a, - 0x0a, 0x19, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6e, 0x65, - 0x78, 0x74, 0x68, 0x6f, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x88, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x16, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4e, 0x65, - 0x78, 0x74, 0x68, 0x6f, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x66, 0x6c, - 0x61, 0x67, 0x18, 0x89, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x46, 0x6c, 0x6f, 0x77, 0x63, 0x74, 0x72, 0x6c, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x5f, 0x0a, - 0x2c, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x76, - 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8a, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x69, 0x70, 0x76, 0x36, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x41, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5d, - 0x0a, 0x2b, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, - 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8b, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4c, 0x69, 0x6d, 0x69, - 0x74, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, - 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, - 0x1e, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x61, 0x73, 0x18, - 0x8c, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, - 0x41, 0x73, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x62, 0x66, 0x5f, 0x77, - 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x5f, 0x65, 0x6e, 0x63, 0x61, 0x70, 0x5f, - 0x76, 0x72, 0x66, 0x18, 0x8d, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, - 0x50, 0x62, 0x66, 0x57, 0x69, 0x74, 0x68, 0x44, 0x65, 0x63, 0x61, 0x70, 0x45, 0x6e, 0x63, 0x61, - 0x70, 0x56, 0x72, 0x66, 0x12, 0x31, 0x0a, 0x14, 0x74, 0x74, 0x6c, 0x5f, 0x63, 0x6f, 0x70, 0x79, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8e, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x12, 0x74, 0x74, 0x6c, 0x43, 0x6f, 0x70, 0x79, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x67, 0x72, 0x69, 0x62, 0x69, - 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x65, - 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8f, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x67, 0x72, 0x69, 0x62, 0x69, 0x44, 0x65, 0x63, 0x61, 0x70, - 0x4d, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6c, 0x65, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, - 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x90, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x49, 0x73, 0x69, 0x73, 0x53, 0x65, 0x74, 0x4c, - 0x65, 0x76, 0x65, 0x6c, 0x12, 0x44, 0x0a, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, - 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x79, - 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x91, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, - 0x73, 0x6b, 0x69, 0x70, 0x49, 0x73, 0x69, 0x73, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, - 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, - 0x73, 0x65, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x52, 0x70, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x53, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x27, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x70, - 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x93, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, - 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x62, 0x0a, 0x2e, 0x62, 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, - 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x94, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x62, 0x67, - 0x70, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x70, 0x66, 0x5f, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x95, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x19, 0x70, 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x44, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x67, 0x0a, 0x31, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x6f, 0x70, - 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, - 0x96, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x50, - 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, - 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x18, 0x97, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x70, - 0x12, 0x51, 0x0a, 0x25, 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x6c, 0x6c, - 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, - 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x74, 0x79, 0x18, 0x98, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x21, 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x46, 0x6f, - 0x72, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, - 0x6c, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x1f, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, - 0x69, 0x61, 0x5f, 0x63, 0x6c, 0x69, 0x18, 0x99, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x61, - 0x64, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x42, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x56, 0x69, 0x61, 0x43, 0x6c, 0x69, 0x12, 0x33, 0x0a, 0x15, 0x73, 0x6b, 0x69, - 0x70, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x18, 0x9a, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x4d, - 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x3d, - 0x0a, 0x1b, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x69, 0x62, 0x5f, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x74, - 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x9b, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, 0x67, 0x70, 0x52, 0x69, 0x62, 0x4f, 0x63, 0x50, 0x61, - 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, - 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x74, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x9c, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, - 0x69, 0x70, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, - 0x38, 0x0a, 0x18, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x61, 0x73, - 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x9d, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x15, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x73, 0x50, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x38, 0x69, 0x70, 0x76, - 0x36, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, - 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, - 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x9e, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2f, 0x69, 0x70, - 0x76, 0x36, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, - 0x68, 0x49, 0x70, 0x76, 0x34, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, 0x12, 0x50, 0x0a, - 0x25, 0x70, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x65, 0x71, 0x75, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x72, - 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x9f, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, - 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x62, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, - 0x61, 0x0a, 0x2e, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x61, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2c, 0x0a, 0x12, + 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x65, + 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x70, 0x61, 0x74, 0x68, 0x50, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x73, 0x74, 0x1a, 0xb8, 0x01, 0x0a, 0x08, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2e, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, + 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x52, + 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x61, 0x72, 0x64, 0x77, + 0x61, 0x72, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x6f, 0x66, + 0x74, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, + 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, + 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x84, 0x57, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x18, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, + 0x6c, 0x34, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x75, 0x64, 0x70, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x4c, 0x34, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x55, 0x64, 0x70, 0x12, 0x3a, + 0x0a, 0x19, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x72, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x17, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x28, 0x68, 0x69, + 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6c, + 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x25, 0x68, 0x69, + 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, + 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x1f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, + 0x69, 0x5f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, 0x73, + 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x55, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x26, 0x69, 0x73, + 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x31, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x69, 0x73, 0x69, 0x73, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x31, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x41, + 0x0a, 0x1d, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x74, 0x6f, + 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x69, 0x73, 0x69, 0x73, 0x53, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, 0x69, 0x73, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x26, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x49, + 0x73, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, 0x69, 0x53, + 0x61, 0x66, 0x69, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x54, 0x0a, 0x27, 0x69, 0x73, 0x69, + 0x73, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, 0x73, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, + 0x58, 0x0a, 0x29, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, + 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x25, 0x69, 0x73, 0x69, 0x73, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x21, 0x69, 0x73, 0x69, + 0x73, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x53, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x70, 0x5f, 0x6e, 0x65, 0x69, 0x67, 0x68, + 0x62, 0x6f, 0x72, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x11, 0x69, 0x70, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x4d, 0x69, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x13, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x12, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x72, + 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x37, 0x0a, 0x18, 0x6f, 0x73, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, 0x5f, 0x72, + 0x70, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x6f, 0x73, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, 0x52, 0x70, 0x12, 0x50, + 0x0a, 0x25, 0x6c, 0x6c, 0x64, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, + 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6c, + 0x6c, 0x64, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x12, 0x55, 0x0a, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x67, 0x70, 0x5f, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x23, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x42, 0x67, 0x70, 0x4c, 0x61, + 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x47, 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x34, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x1d, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, + 0x6e, 0x68, 0x5f, 0x64, 0x6d, 0x61, 0x63, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x69, + 0x70, 0x76, 0x36, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x47, 0x72, 0x69, 0x62, + 0x69, 0x4e, 0x68, 0x44, 0x6d, 0x61, 0x63, 0x12, 0x45, 0x0a, 0x1f, 0x65, 0x63, 0x6e, 0x5f, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1c, 0x65, 0x63, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, + 0x0a, 0x1f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, + 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, 0x70, 0x76, 0x36, 0x44, 0x69, 0x73, + 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x50, 0x6b, 0x74, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x64, + 0x72, 0x6f, 0x70, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x55, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x1c, 0x63, 0x6c, + 0x69, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, 0x6e, + 0x63, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x6f, 0x63, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x18, 0x63, 0x6c, 0x69, 0x54, 0x61, 0x6b, 0x65, 0x73, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, + 0x65, 0x6e, 0x63, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x4f, 0x63, 0x12, 0x3f, 0x0a, 0x1c, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x19, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x3b, 0x0a, 0x1a, 0x73, + 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x69, 0x64, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x17, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x43, 0x68, 0x69, 0x70, 0x49, 0x64, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x25, 0x62, 0x61, 0x63, 0x6b, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x61, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x46, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x21, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x2b, 0x6e, 0x6f, 0x5f, 0x6d, 0x69, 0x78, + 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x75, + 0x6e, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x6e, 0x6f, 0x4d, + 0x69, 0x78, 0x4f, 0x66, 0x54, 0x61, 0x67, 0x67, 0x65, 0x64, 0x41, 0x6e, 0x64, 0x55, 0x6e, 0x74, + 0x61, 0x67, 0x67, 0x65, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x70, + 0x34, 0x72, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x18, 0x23, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, + 0x69, 0x74, 0x50, 0x34, 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x12, 0x3e, 0x0a, 0x1c, 0x75, 0x73, 0x65, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, + 0x72, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x24, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x75, 0x73, 0x65, 0x56, 0x65, + 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41, 0x63, 0x6c, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x77, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x25, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x14, 0x73, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x21, 0x65, 0x78, 0x70, + 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, + 0x72, 0x65, 0x66, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x26, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x1d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x27, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x65, 0x78, 0x70, 0x6c, + 0x69, 0x63, 0x69, 0x74, 0x5f, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x47, 0x72, 0x69, 0x62, 0x69, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x78, + 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x65, + 0x64, 0x18, 0x29, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x65, 0x78, + 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x18, + 0x2a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x56, 0x72, 0x66, 0x12, 0x2c, 0x0a, 0x12, 0x71, 0x6f, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, + 0x70, 0x65, 0x64, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x10, 0x71, 0x6f, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4f, 0x63, 0x74, 0x65, + 0x74, 0x73, 0x12, 0x4f, 0x0a, 0x24, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x73, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x21, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x50, 0x61, + 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x4d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, + 0x65, 0x74, 0x72, 0x79, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x22, 0x67, 0x72, 0x69, 0x62, + 0x69, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x77, + 0x69, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x2e, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x67, 0x72, 0x69, 0x62, 0x69, 0x4d, 0x61, 0x63, 0x4f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x41, 0x72, 0x70, 0x12, 0x4a, 0x0a, 0x22, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x6e, 0x64, 0x65, + 0x72, 0x41, 0x66, 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, + 0x56, 0x0a, 0x28, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x30, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x24, 0x67, 0x6e, 0x6f, 0x69, 0x46, 0x61, 0x62, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x6e, 0x74, 0x70, 0x5f, 0x6e, + 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x31, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1b, 0x6e, 0x74, 0x70, 0x4e, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, + 0x72, 0x66, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1e, 0x0a, + 0x0b, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x6c, 0x32, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0x32, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x6f, 0x6d, 0x69, 0x74, 0x4c, 0x32, 0x4d, 0x74, 0x75, 0x12, 0x46, 0x0a, + 0x20, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x18, 0x33, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, + 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x5f, + 0x64, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, + 0x12, 0x2e, 0x0a, 0x13, 0x62, 0x67, 0x70, 0x5f, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x62, + 0x67, 0x70, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x4d, 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x61, 0x6c, 0x5f, 0x77, 0x61, + 0x69, 0x74, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, + 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x61, 0x6c, 0x57, 0x61, 0x69, 0x74, 0x41, 0x66, 0x74, 0x65, + 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, + 0x43, 0x0a, 0x1e, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x18, 0x3f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x56, 0x0a, 0x28, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x18, 0x40, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x16, + 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x64, 0x35, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, 0x18, 0x41, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x62, 0x67, + 0x70, 0x4d, 0x64, 0x35, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x65, + 0x74, 0x12, 0x4b, 0x0a, 0x23, 0x64, 0x65, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x5f, + 0x61, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x42, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, + 0x64, 0x65, 0x71, 0x75, 0x65, 0x75, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x74, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x41, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x73, 0x12, 0x2a, + 0x0a, 0x11, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x72, 0x69, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6f, + 0x6e, 0x6c, 0x79, 0x18, 0x43, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x67, 0x72, 0x69, 0x62, 0x69, + 0x52, 0x69, 0x62, 0x61, 0x63, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x61, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x44, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x45, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, + 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x34, 0x0a, 0x16, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x47, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4c, 0x0a, 0x23, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x72, 0x66, 0x5f, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x48, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x72, 0x66, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x76, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x49, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x10, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x56, 0x6c, 0x61, + 0x6e, 0x49, 0x64, 0x12, 0x58, 0x0a, 0x2a, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x6d, 0x61, 0x63, + 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x5f, 0x61, 0x72, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x67, 0x72, 0x69, 0x62, 0x69, 0x4d, 0x61, + 0x63, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x72, 0x70, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x0a, + 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x4b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x6f, + 0x73, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x71, 0x6f, 0x73, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x70, 0x75, + 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x18, 0x4d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x70, 0x75, 0x4d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x1d, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, + 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x30, 0x18, 0x4e, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x64, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x30, 0x12, 0x5f, + 0x0a, 0x2d, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x4f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x77, 0x69, 0x74, 0x63, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x12, + 0x38, 0x0a, 0x18, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x50, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x24, 0x70, 0x34, 0x72, + 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, + 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x18, 0x51, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x70, 0x34, 0x72, 0x74, 0x55, 0x6e, 0x73, + 0x65, 0x74, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x62, 0x6b, + 0x75, 0x70, 0x5f, 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, + 0x65, 0x73, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x52, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, + 0x62, 0x6b, 0x75, 0x70, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x49, 0x0a, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x5f, 0x6e, 0x68, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x76, + 0x72, 0x66, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x18, 0x53, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x1d, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4e, 0x68, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x56, 0x72, 0x66, 0x57, 0x69, 0x74, 0x68, 0x44, 0x65, 0x63, + 0x61, 0x70, 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x18, 0x55, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, 0x69, 0x73, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, 0x69, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x23, 0x70, 0x34, 0x72, 0x74, 0x5f, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65, 0x6e, 0x74, + 0x72, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x56, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x70, 0x34, 0x72, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5e, 0x0a, 0x2d, 0x6f, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x73, 0x5f, + 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x5f, 0x6f, 0x72, 0x5f, 0x6c, 0x69, + 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x18, 0x57, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x6f, 0x73, + 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, + 0x73, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x4f, 0x72, 0x4c, 0x69, 0x6e, + 0x65, 0x63, 0x61, 0x72, 0x64, 0x12, 0x42, 0x0a, 0x1e, 0x6f, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x73, 0x5f, + 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x6f, + 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x49, 0x73, 0x43, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x12, 0x57, 0x0a, 0x2a, 0x69, 0x73, 0x69, + 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6c, + 0x31, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6c, 0x32, + 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, + 0x73, 0x69, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x65, 0x4c, 0x31, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x32, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x12, 0x57, 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, + 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, + 0x5f, 0x6f, 0x73, 0x70, 0x66, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x18, 0x5c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x62, 0x67, 0x70, 0x53, 0x65, 0x74, 0x4d, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x4f, 0x73, + 0x70, 0x66, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x4e, 0x0a, 0x24, 0x70, + 0x34, 0x72, 0x74, 0x5f, 0x67, 0x64, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, + 0x5f, 0x64, 0x6f, 0x74, 0x31, 0x71, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x34, 0x72, 0x74, 0x47, + 0x64, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x44, 0x6f, 0x74, 0x31, 0x71, 0x53, + 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x2a, 0x61, + 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x5e, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x25, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x73, + 0x0a, 0x38, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6c, 0x69, 0x66, 0x65, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x60, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x31, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, + 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x73, 0x4c, 0x73, 0x70, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x12, 0x4f, 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, + 0x63, 0x70, 0x75, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x62, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x21, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, + 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x53, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x63, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x2b, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, + 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x43, 0x70, + 0x75, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x61, 0x62, 0x72, 0x69, + 0x63, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1c, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, + 0x0a, 0x27, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, + 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x71, 0x6f, 0x73, 0x5f, 0x76, 0x6f, 0x71, + 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1c, 0x71, 0x6f, 0x73, 0x56, 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x65, 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, + 0x1f, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x18, 0x68, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, 0x36, 0x46, + 0x6c, 0x6f, 0x77, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x72, 0x73, 0x5f, 0x63, 0x73, 0x6e, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x69, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x43, 0x73, + 0x6e, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, 0x37, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, + 0x72, 0x65, 0x61, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x18, 0x6a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x30, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x44, 0x72, 0x6f, 0x70, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x72, 0x65, 0x61, 0x73, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0x6b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x55, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x22, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, + 0x6f, 0x6c, 0x64, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x18, 0x6c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x67, 0x6e, 0x6d, 0x69, 0x18, 0x6d, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x6f, 0x6f, + 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x61, 0x77, 0x47, 0x6e, 0x6d, 0x69, + 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x74, 0x63, 0x70, 0x5f, 0x6e, 0x65, 0x67, + 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x6b, 0x69, 0x70, 0x54, 0x63, 0x70, + 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x73, 0x73, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x12, 0x4c, 0x0a, 0x23, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x73, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6f, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1f, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x4c, 0x65, 0x61, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x31, 0x0a, 0x15, 0x71, 0x6f, 0x73, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x70, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x12, 0x71, 0x6f, 0x73, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x73, 0x49, 0x64, 0x12, 0x55, 0x0a, 0x28, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x66, 0x69, 0x62, 0x5f, + 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x66, + 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, + 0x71, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x69, 0x62, 0x46, 0x61, + 0x69, 0x6c, 0x65, 0x64, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x46, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x50, 0x0a, 0x25, 0x71, 0x6f, + 0x73, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x18, 0x72, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x71, 0x6f, 0x73, 0x42, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x66, 0x0a, 0x31, + 0x62, 0x67, 0x70, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x64, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0x73, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, 0x62, 0x67, 0x70, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, + 0x70, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x15, 0x62, 0x67, 0x70, 0x5f, 0x6c, 0x6c, 0x67, 0x72, + 0x5f, 0x6f, 0x63, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x74, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x12, 0x62, 0x67, 0x70, 0x4c, 0x6c, 0x67, 0x72, 0x4f, 0x63, 0x55, 0x6e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x74, 0x75, 0x6e, 0x6e, 0x65, + 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x75, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, + 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x76, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1b, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, + 0x51, 0x0a, 0x26, 0x65, 0x63, 0x6e, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, + 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x77, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x21, 0x65, 0x63, 0x6e, 0x53, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x4d, 0x61, 0x78, 0x54, 0x68, + 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x71, 0x6f, 0x73, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x18, 0x78, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x71, 0x6f, 0x73, 0x5f, 0x73, 0x65, 0x74, + 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x79, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1d, 0x71, 0x6f, 0x73, 0x53, 0x65, 0x74, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, + 0x42, 0x0a, 0x1e, 0x71, 0x6f, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0x7a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x65, 0x76, 0x65, + 0x6c, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x7b, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x10, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x12, 0x48, 0x0a, 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, + 0x65, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x5f, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x7c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x49, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x47, 0x0a, 0x20, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, + 0x61, 0x63, 0x6b, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0x7d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x6e, + 0x6b, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x4d, 0x0a, 0x24, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x6c, 0x71, + 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x7e, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x6c, 0x71, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x12, 0x4a, 0x0a, 0x22, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, + 0x63, 0x69, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x7f, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1e, 0x62, 0x67, 0x70, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, + 0x58, 0x0a, 0x29, 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x6f, + 0x63, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x80, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4f, + 0x63, 0x4d, 0x61, 0x78, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x26, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x5f, 0x61, 0x66, 0x69, 0x73, + 0x61, 0x66, 0x69, 0x18, 0x81, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x73, 0x6b, 0x69, 0x70, + 0x42, 0x67, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x57, + 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x41, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, 0x12, 0x62, 0x0a, + 0x2e, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x72, 0x64, + 0x77, 0x61, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, + 0x82, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x64, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x12, 0x68, 0x0a, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x72, + 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x83, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2c, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x42, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5d, 0x0a, 0x2b, 0x67, + 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x5f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x84, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x27, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x73, 0x6b, + 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x85, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x6e, 0x42, 0x67, 0x70, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x12, 0x55, 0x0a, 0x27, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x86, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x74, + 0x79, 0x6c, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, - 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x18, 0xa0, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, - 0x48, 0x6f, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, - 0x72, 0x79, 0x12, 0x58, 0x0a, 0x29, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, - 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x18, - 0xa1, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, - 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x2c, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, - 0x6f, 0x70, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa2, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x26, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x65, 0x78, 0x74, 0x48, - 0x6f, 0x70, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x73, 0x0a, 0x37, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x7a, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x63, 0x61, - 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x74, 0x75, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x74, 0x65, 0x6c, - 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa3, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5a, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x12, 0x46, 0x0a, 0x1f, 0x70, 0x6c, 0x71, 0x5f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0xa4, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x70, 0x6c, 0x71, 0x52, - 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0xa5, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, - 0x61, 0x78, 0x4d, 0x74, 0x75, 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x70, 0x73, 0x18, 0xa6, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x50, - 0x70, 0x73, 0x12, 0x57, 0x0a, 0x28, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, - 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa7, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, - 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x62, - 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, - 0x5f, 0x72, 0x65, 0x66, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x18, 0xa8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, - 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, - 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, - 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, - 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, - 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, - 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, - 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, - 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, - 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, - 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, - 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, - 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, - 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, - 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, - 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, - 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x87, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x29, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, + 0x78, 0x74, 0x48, 0x6f, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x66, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x19, + 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6e, 0x65, 0x78, 0x74, + 0x68, 0x6f, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x88, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x16, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4e, 0x65, 0x78, 0x74, + 0x68, 0x6f, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x66, 0x6c, 0x61, 0x67, + 0x18, 0x89, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, + 0x6c, 0x6f, 0x77, 0x63, 0x74, 0x72, 0x6c, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x5f, 0x0a, 0x2c, 0x69, + 0x70, 0x76, 0x36, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x76, 0x65, 0x72, + 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8a, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x28, 0x69, 0x70, 0x76, 0x36, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x41, 0x64, + 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5d, 0x0a, 0x2b, + 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x63, + 0x65, 0x65, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8b, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x27, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, + 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x61, 0x73, 0x18, 0x8c, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x41, 0x73, + 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x62, 0x66, 0x5f, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x5f, 0x65, 0x6e, 0x63, 0x61, 0x70, 0x5f, 0x76, 0x72, + 0x66, 0x18, 0x8d, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x62, + 0x66, 0x57, 0x69, 0x74, 0x68, 0x44, 0x65, 0x63, 0x61, 0x70, 0x45, 0x6e, 0x63, 0x61, 0x70, 0x56, + 0x72, 0x66, 0x12, 0x31, 0x0a, 0x14, 0x74, 0x74, 0x6c, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8e, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x12, 0x74, 0x74, 0x6c, 0x43, 0x6f, 0x70, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x64, + 0x65, 0x63, 0x61, 0x70, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x65, 0x6e, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8f, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1e, 0x67, 0x72, 0x69, 0x62, 0x69, 0x44, 0x65, 0x63, 0x61, 0x70, 0x4d, 0x69, + 0x78, 0x65, 0x64, 0x50, 0x6c, 0x65, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, + 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x90, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x49, 0x73, 0x69, 0x73, 0x53, 0x65, 0x74, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x12, 0x44, 0x0a, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, + 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x91, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, + 0x69, 0x70, 0x49, 0x73, 0x69, 0x73, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, + 0x74, 0x79, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x65, + 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x52, 0x70, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x53, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x27, 0x73, 0x6b, + 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x61, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x93, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x73, 0x6b, + 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x62, 0x0a, 0x2e, 0x62, 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, + 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x18, 0x94, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x62, 0x67, 0x70, 0x43, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, + 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x70, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x95, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x70, + 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x67, 0x0a, 0x31, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x96, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, + 0x74, 0x54, 0x6f, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x18, 0x97, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, + 0x6b, 0x69, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x70, 0x12, 0x51, + 0x0a, 0x25, 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x5f, + 0x66, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x69, 0x6c, 0x74, 0x79, 0x18, 0x98, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, + 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x46, 0x6f, 0x72, 0x56, + 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x74, + 0x79, 0x12, 0x44, 0x0a, 0x1f, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x69, 0x61, + 0x5f, 0x63, 0x6c, 0x69, 0x18, 0x99, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x61, 0x64, 0x64, + 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x42, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x56, 0x69, 0x61, 0x43, 0x6c, 0x69, 0x12, 0x33, 0x0a, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x5f, + 0x6d, 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x18, 0x9a, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x4d, 0x61, 0x63, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x3d, 0x0a, 0x1b, + 0x62, 0x67, 0x70, 0x5f, 0x72, 0x69, 0x62, 0x5f, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x9b, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x17, 0x62, 0x67, 0x70, 0x52, 0x69, 0x62, 0x4f, 0x63, 0x50, 0x61, 0x74, 0x68, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x9c, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, 0x69, 0x70, + 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x38, 0x0a, + 0x18, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x61, 0x73, 0x5f, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x9d, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x15, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x73, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x38, 0x69, 0x70, 0x76, 0x36, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, + 0x61, 0x72, 0x70, 0x18, 0x9e, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2f, 0x69, 0x70, 0x76, 0x36, + 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, + 0x70, 0x76, 0x34, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, 0x12, 0x50, 0x0a, 0x25, 0x70, + 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x72, 0x5f, 0x72, + 0x75, 0x6c, 0x65, 0x73, 0x18, 0x9f, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x66, 0x52, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x62, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x61, 0x0a, + 0x2e, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, + 0xa0, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, + 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, + 0x12, 0x58, 0x0a, 0x29, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x18, 0xa1, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, + 0x48, 0x6f, 0x70, 0x52, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x2c, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, + 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa2, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x26, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, + 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x73, 0x0a, 0x37, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x7a, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, + 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x74, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, + 0x65, 0x74, 0x72, 0x79, 0x18, 0xa3, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x5a, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x46, + 0x0a, 0x1f, 0x70, 0x6c, 0x71, 0x5f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0xa4, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x70, 0x6c, 0x71, 0x52, 0x65, 0x66, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0xa5, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, + 0x4d, 0x74, 0x75, 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x70, 0x73, 0x18, 0xa6, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x50, 0x70, 0x73, + 0x12, 0x57, 0x0a, 0x28, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa7, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, + 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x62, 0x67, 0x70, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, + 0x65, 0x66, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0xa8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, + 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, + 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, + 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, + 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, + 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, + 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, + 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, + 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, + 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, + 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, + 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, + 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, + 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, + 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, + 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( From e6f8961af7c5e22c3f08060e36cc980cff4bf7fa Mon Sep 17 00:00:00 2001 From: arvbaska1 <123760606+arvbaska1@users.noreply.github.com> Date: Thu, 11 Apr 2024 23:57:55 -0400 Subject: [PATCH 77/97] parent type change to use lookup (#2808) --- .../telemetry_inventory_test/telemetry_inventory_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go b/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go index 7cb2a4c6a2e..0e6ef43e82f 100644 --- a/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go +++ b/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go @@ -745,8 +745,9 @@ func ValidateComponentState(t *testing.T, dut *ondatra.DUTDevice, cards []*oc.Co t.Errorf("Component %s Parent: Chassis component NOT found in the hierarchy tree of component", cName) break } - parentType := gnmi.Get(t, dut, gnmi.OC().Component(parent).Type().State()) - if parentType == componentType["Chassis"] { + pLoookup := gnmi.Lookup(t, dut, gnmi.OC().Component(parent).Type().State()) + parentType, present := pLoookup.Val() + if present && parentType == componentType["Chassis"] { t.Logf("Component %s Parent: Found chassis component in the hierarchy tree of component", cName) break } From 6a94a90ddfe9698eea865ec317f7a649e4c25eb1 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Fri, 12 Apr 2024 12:49:16 -0700 Subject: [PATCH 78/97] Remove AGGREGATION tag (#2895) --- .../management/otg_tests/management_ha_test/metadata.textproto | 1 - 1 file changed, 1 deletion(-) diff --git a/feature/system/management/otg_tests/management_ha_test/metadata.textproto b/feature/system/management/otg_tests/management_ha_test/metadata.textproto index 247f7f2735d..fd2ab3d9568 100644 --- a/feature/system/management/otg_tests/management_ha_test/metadata.textproto +++ b/feature/system/management/otg_tests/management_ha_test/metadata.textproto @@ -20,6 +20,5 @@ platform_exceptions: { set_metric_as_preference: true } } -tags: TAGS_AGGREGATION tags: TAGS_TRANSIT tags: TAGS_DATACENTER_EDGE From acabfe15befe088e0ce38f0b8f506c1b123c228d Mon Sep 17 00:00:00 2001 From: Girish Subramanian <103155016+sgirishj@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:30:36 -0700 Subject: [PATCH 79/97] Configure default network instance (#2641) --- feature/sflow/otg_tests/sflow_base_test/sflow_base_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/feature/sflow/otg_tests/sflow_base_test/sflow_base_test.go b/feature/sflow/otg_tests/sflow_base_test/sflow_base_test.go index 0d780bc4302..a305c3e1035 100644 --- a/feature/sflow/otg_tests/sflow_base_test/sflow_base_test.go +++ b/feature/sflow/otg_tests/sflow_base_test/sflow_base_test.go @@ -124,6 +124,7 @@ func TestSFlowTraffic(t *testing.T) { configureDUTBaseline(t, dut) srBatch := &gnmi.SetBatch{} + fptest.ConfigureDefaultNetworkInstance(t, dut) cfgplugins.NewStaticRouteCfg(srBatch, staticRoute, dut) srBatch.Set(t, dut) From 129ac0a4eff8a5bfd3bea777ccdb2c5421ccd5e6 Mon Sep 17 00:00:00 2001 From: prakashbadri-arista <127355794+prakashbadri-arista@users.noreply.github.com> Date: Tue, 16 Apr 2024 20:30:39 -0700 Subject: [PATCH 80/97] Fix static configuration and vrf selection policy configuration (#2901) failure in TE-17.1 VRF selection policy driven TE --- .../otg_tests/vrf_policy_driven_te/metadata.textproto | 1 + .../vrf_policy_driven_te/vrf_policy_driven_te_test.go | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto index 43a1c1cbbd9..72bd2337297 100644 --- a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto +++ b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto @@ -43,6 +43,7 @@ platform_exceptions: { gnoi_subcomponent_path: true deprecated_vlan_id: true interface_enabled: true + static_protocol_name: "STATIC" default_network_instance: "default" gribi_mac_override_static_arp_static_route: true missing_isis_interface_afi_safi_enable: true diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go index a5ff20c5534..3553efafb3b 100644 --- a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go +++ b/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go @@ -366,11 +366,6 @@ func configureVrfSelectionPolicyW(t *testing.T, dut *ondatra.DUTDevice) { gnmi.Replace(t, dut, dutPolFwdPath.Config(), niP) } -func deleteVrfSelectionPolicy(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - gnmi.Delete(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Config()) -} - func configureVrfSelectionPolicyC(t *testing.T, dut *ondatra.DUTDevice) { t.Helper() d := &oc.Root{} @@ -2075,7 +2070,6 @@ func TestGribiDecap(t *testing.T) { }) t.Log("Delete vrf selection policy W and Apply vrf selectioin policy C.") - deleteVrfSelectionPolicy(t, dut) configureVrfSelectionPolicyC(t, dut) t.Run("Test-4: Tunneled traffic with no decap", func(t *testing.T) { @@ -2083,7 +2077,6 @@ func TestGribiDecap(t *testing.T) { }) t.Log("Delete vrf selection policy C and Apply vrf selectioin policy W.") - deleteVrfSelectionPolicy(t, dut) configureVrfSelectionPolicyW(t, dut) t.Run("Test-5: Match on default term and send to default VRF", func(t *testing.T) { From 56dc0309612d6024491958425cc6af339579191b Mon Sep 17 00:00:00 2001 From: Tushar Rathod <111466464+trathod1@users.noreply.github.com> Date: Wed, 17 Apr 2024 20:36:10 -0400 Subject: [PATCH 81/97] RT-1.27: Static route to BGP redistribution (#2900) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * RT-1.27: Static route to BGP redistribution Following changes are in this PR - 1. Adding script static_route_bgp_redistribuon_test.go 2. Following new deviations are added - - skip_bgp_send_community_type - use_vendor_native_tag_set_config - unsupported_table_connection_redistribution “This code is a Contribution to the OpenConfig Feature Profiles project (“Work”) made under the Google Software Grant and Corporate Contributor License Agreement (“CLA”) and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia’s intellectual property are granted for any other purpose. This code is provided on an “as is” basis without any warranties of any kind.” Co-Authored-By: cm-nokia * Updating deviation name for table-connection unsupport to match with PR-2898. “This code is a Contribution to the OpenConfig Feature Profiles project (“Work”) made under the Google Software Grant and Corporate Contributor License Agreement (“CLA”) and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia’s intellectual property are granted for any other purpose. This code is provided on an “as is” basis without any warranties of any kind.” * Fixing plan_id in metadata.proto * - Moved files from "feature/bgp/static_route_bgp_redistribution/" to "feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/" - Updated UUID. - Updated "featureprofiles/testregistry.textproto" “This code is a Contribution to the OpenConfig Feature Profiles project (“Work”) made under the Google Software Grant and Corporate Contributor License Agreement (“CLA”) and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia’s intellectual property are granted for any other purpose. This code is provided on an “as is” basis without any warranties of any kind.” * Updating - to _ in the url path --------- Co-authored-by: cm-nokia --- .../README.md | 0 .../metadata.textproto | 24 + .../static_route_bgp_redistribution_test.go | 1967 +++++++++++++++++ internal/deviations/deviations.go | 15 + proto/metadata.proto | 6 + proto/metadata_go_proto/metadata.pb.go | 124 +- testregistry.textproto | 2 +- 7 files changed, 2095 insertions(+), 43 deletions(-) rename feature/bgp/static_route_bgp_redistribution/{ => otg_tests/static_route_bgp_redistribution_test}/README.md (100%) create mode 100644 feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/metadata.textproto create mode 100644 feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/static_route_bgp_redistribution_test.go diff --git a/feature/bgp/static_route_bgp_redistribution/README.md b/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/README.md similarity index 100% rename from feature/bgp/static_route_bgp_redistribution/README.md rename to feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/README.md diff --git a/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/metadata.textproto b/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/metadata.textproto new file mode 100644 index 00000000000..b128bfe709d --- /dev/null +++ b/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/metadata.textproto @@ -0,0 +1,24 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "eb7e7ab2-5f58-4039-b862-13ad55459074" +plan_id: "RT-1.27" +description: "Static route to BGP redistribution" +testbed: TESTBED_DUT_ATE_4LINKS +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_port_speed: true + explicit_interface_in_default_vrf: true + aggregate_atomic_update: true + static_protocol_name: "static" + interface_enabled: true + skip_set_rp_match_set_options: true + skip_prefix_set_mode: true + table_connections_unsupported: true + use_vendor_native_tag_set_config: true + skip_bgp_send_community_type: true + } +} diff --git a/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/static_route_bgp_redistribution_test.go b/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/static_route_bgp_redistribution_test.go new file mode 100644 index 00000000000..846fd69d32d --- /dev/null +++ b/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/static_route_bgp_redistribution_test.go @@ -0,0 +1,1967 @@ +// Copyright 2023 Nokia, 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. +// +// This code is a Contribution to OpenConfig Feature Profiles project ("Work") +// made under the Google Software Grant and Corporate Contributor License +// Agreement ("CLA") and governed by the Apache License 2.0. No other rights +// or licenses in or to any of Nokia's intellectual property are granted for +// any other purpose. This code is provided on an "as is" basis without +// any warranties of any kind. +// +// SPDX-License-Identifier: Apache-2.0 + +package static_route_bgp_redistribution_test + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "testing" + "time" + + "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" + gpb "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +const ( + ipv4PrefixLen = 30 + ipv6PrefixLen = 126 + subInterfaceIndex = 0 + mtu = 1500 + peerGroupName = "PEER-GROUP" + dutAsn = 64512 + atePeer1Asn = 64511 + atePeer2Asn = 64512 + acceptRoute = true + metricPropagate = true + policyResultNext = true + isV4 = true + shouldBePresent = true + replace = true + redistributeStaticPolicyNameV4 = "route-policy-v4" + redistributeStaticPolicyNameV6 = "route-policy-v6" + policyStatementNameV4 = "statement-v4" + policyStatementNameV6 = "statement-v6" + trafficDuration = 30 * time.Second + tolerancePct = 2 + medZero = 0 + medNonZero = 1000 + medIPv4 = 104 + medIPv6 = 106 + localPreference = 100 +) + +var ( + dutPort1 = &attrs.Attributes{ + Name: "dutPort1", + MAC: "00:12:01:01:01:01", + IPv4: "192.168.1.1", + IPv6: "2001:db8::1", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + MTU: mtu, + } + + dutPort2 = &attrs.Attributes{ + Name: "dutPort2", + MAC: "00:12:02:01:01:01", + IPv4: "192.168.1.5", + IPv6: "2001:db8::5", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + MTU: mtu, + } + + dutPort3 = &attrs.Attributes{ + Name: "dutPort3", + MAC: "00:12:03:01:01:01", + IPv4: "192.168.1.9", + IPv6: "2001:db8::9", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + MTU: mtu, + } + + atePort1 = &attrs.Attributes{ + Name: "atePort1", + MAC: "02:00:01:01:01:01", + IPv4: "192.168.1.2", + IPv6: "2001:db8::2", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + MTU: mtu, + } + + atePort2 = &attrs.Attributes{ + Name: "atePort2", + MAC: "02:00:02:01:01:01", + IPv4: "192.168.1.6", + IPv6: "2001:db8::6", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + MTU: mtu, + } + + atePort3 = &attrs.Attributes{ + Name: "atePort3", + MAC: "02:00:03:01:01:01", + IPv4: "192.168.1.10", + IPv6: "2001:db8::a", + IPv4Len: ipv4PrefixLen, + IPv6Len: ipv6PrefixLen, + MTU: mtu, + } + + dutPorts = map[string]*attrs.Attributes{ + "port1": dutPort1, + "port2": dutPort2, + "port3": dutPort3, + } +) + +func configureDUTPort( + t *testing.T, + dut *ondatra.DUTDevice, + port *ondatra.Port, + portAttrs *attrs.Attributes, +) { + t.Helper() + + gnmi.Replace( + t, + dut, + gnmi.OC().Interface(port.Name()).Config(), + portAttrs.NewOCInterface(port.Name(), dut), + ) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, port) + } + + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, port.Name(), deviations.DefaultNetworkInstance(dut), subInterfaceIndex) + } +} + +func configureDUTStatic( + t *testing.T, + dut *ondatra.DUTDevice, +) { + t.Helper() + + staticPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) + gnmi.Delete(t, dut, staticPath.Config()) + + dutOcRoot := &oc.Root{} + networkInstance := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + networkInstanceProtocolStatic := networkInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, "static") + networkInstanceProtocolStatic.SetEnabled(true) + + ipv4StaticRoute := networkInstanceProtocolStatic.GetOrCreateStatic("192.168.10.0/24") + // TODO - we dont support, guessing table connection related? + if !deviations.UseVendorNativeTagSetConfig(dut) { + ipv4StaticRoute.SetSetTag(oc.UnionString("40")) + } else { + configureStaticRouteTagSet(t, dut) + attachTagSetToStaticRoute(t, dut, "192.168.10.0/24", "tag-static-v4") + } + + ipv4StaticRouteNextHop := ipv4StaticRoute.GetOrCreateNextHop("0") + ipv4StaticRouteNextHop.SetMetric(104) + ipv4StaticRouteNextHop.SetNextHop(oc.UnionString("192.168.1.6")) + + ipv6StaticRoute := networkInstanceProtocolStatic.GetOrCreateStatic("2024:db8:128:128::/64") + if !deviations.UseVendorNativeTagSetConfig(dut) { + ipv6StaticRoute.SetSetTag(oc.UnionString("60")) + } else { + attachTagSetToStaticRoute(t, dut, "2024:db8:128:128::/64", "tag-static-v6") + } + + ipv6StaticRouteNextHop := ipv6StaticRoute.GetOrCreateNextHop("0") + ipv6StaticRouteNextHop.SetMetric(106) + ipv6StaticRouteNextHop.SetNextHop(oc.UnionString("2001:DB8::6")) + + gnmi.Replace(t, dut, staticPath.Config(), networkInstanceProtocolStatic) +} + +func configureDUTRoutingPolicy( + t *testing.T, + dut *ondatra.DUTDevice, +) { + t.Helper() + + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition("import-dut-port2-connected-subnet") + + dutOcRoot := &oc.Root{} + connectedPolicy := dutOcRoot.GetOrCreateRoutingPolicy() + connectedPolicyDefinition := connectedPolicy.GetOrCreatePolicyDefinition("import-dut-port2-connected-subnet") + + // v4 + v4PrefixSet := connectedPolicy.GetOrCreateDefinedSets().GetOrCreatePrefixSet("fp-ipv4-prefix") + v4PrefixSet.GetOrCreatePrefix("192.168.1.4/30", "30..32") + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet("fp-ipv4-prefix").Config(), v4PrefixSet) + + ipv4PrefixPolicyStatement, err := connectedPolicyDefinition.AppendNewStatement("fp-ipv4-prefix") + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + ipv4PrefixPolicyStatementAction := ipv4PrefixPolicyStatement.GetOrCreateActions() + ipv4PrefixPolicyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + ipv4PrefixPolicyStatementConditionsPrefixes := ipv4PrefixPolicyStatement.GetOrCreateConditions().GetOrCreateMatchPrefixSet() + ipv4PrefixPolicyStatementConditionsPrefixes.SetPrefixSet("fp-ipv4-prefix") + + // v6 + v6PrefixSet := connectedPolicy.GetOrCreateDefinedSets().GetOrCreatePrefixSet("fp-ipv6-prefix") + v6PrefixSet.GetOrCreatePrefix("2001:db8::4/126", "126..128") + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet("fp-ipv6-prefix").Config(), v6PrefixSet) + + ipv6PrefixPolicyStatement, err := connectedPolicyDefinition.AppendNewStatement("fp-ipv6-prefix") + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + ipv6PrefixPolicyStatementAction := ipv6PrefixPolicyStatement.GetOrCreateActions() + ipv6PrefixPolicyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + ipv6PrefixPolicyStatementConditionsPrefixes := ipv6PrefixPolicyStatement.GetOrCreateConditions().GetOrCreateMatchPrefixSet() + ipv6PrefixPolicyStatementConditionsPrefixes.SetPrefixSet("fp-ipv6-prefix") + + gnmi.Replace(t, dut, policyPath.Config(), connectedPolicyDefinition) +} + +func configureDUTBGP( + t *testing.T, + dut *ondatra.DUTDevice, +) { + t.Helper() + + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + + dutOcRoot := &oc.Root{} + networkInstance := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + networkInstanceProtocolBgp := networkInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := networkInstanceProtocolBgp.GetOrCreateBgp() + + bgpGlobal := bgp.GetOrCreateGlobal() + bgpGlobal.RouterId = ygot.String(dutPort1.IPv4) + bgpGlobal.As = ygot.Uint32(dutAsn) + + bgpGlobalIPv4AF := bgpGlobal.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + bgpGlobalIPv4AF.SetEnabled(true) + + bgpGlobalIPv6AF := bgpGlobal.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + bgpGlobalIPv6AF.SetEnabled(true) + + if !deviations.SkipBgpSendCommunityType(dut) { + bgpGlobalIPv6AF.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_STANDARD}) + bgpGlobalIPv4AF.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_STANDARD}) + } + + bgpPeerGroup := bgp.GetOrCreatePeerGroup(peerGroupName) + bgpPeerGroup.SetPeerAs(dutAsn) + + // dutPort1 -> atePort1 peer (ebgp session) + ateEBGPNeighborOne := bgp.GetOrCreateNeighbor(atePort1.IPv4) + ateEBGPNeighborOne.PeerGroup = ygot.String(peerGroupName) + ateEBGPNeighborOne.PeerAs = ygot.Uint32(atePeer1Asn) + ateEBGPNeighborOne.Enabled = ygot.Bool(true) + + ateEBGPNeighborIPv4AF := ateEBGPNeighborOne.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + ateEBGPNeighborIPv4AF.SetEnabled(true) + ateEBGPNeighborIPv4AFPolicy := ateEBGPNeighborIPv4AF.GetOrCreateApplyPolicy() + ateEBGPNeighborIPv4AFPolicy.SetImportPolicy([]string{"import-dut-port2-connected-subnet"}) + ateEBGPNeighborIPv4AFPolicy.SetExportPolicy([]string{"import-dut-port2-connected-subnet"}) + + ateEBGPNeighborTwo := bgp.GetOrCreateNeighbor(atePort1.IPv6) + ateEBGPNeighborTwo.PeerGroup = ygot.String(peerGroupName) + ateEBGPNeighborTwo.PeerAs = ygot.Uint32(atePeer1Asn) + ateEBGPNeighborTwo.Enabled = ygot.Bool(true) + ateEBGPNeighborIPv6AF := ateEBGPNeighborTwo.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + ateEBGPNeighborIPv6AF.SetEnabled(true) + ateEBGPNeighborIPv6AFPolicy := ateEBGPNeighborIPv6AF.GetOrCreateApplyPolicy() + ateEBGPNeighborIPv6AFPolicy.SetImportPolicy([]string{"import-dut-port2-connected-subnet"}) + ateEBGPNeighborIPv6AFPolicy.SetExportPolicy([]string{"import-dut-port2-connected-subnet"}) + + // dutPort3 -> atePort3 peer (ibgp session) + ateIBGPNeighborThree := bgp.GetOrCreateNeighbor(atePort3.IPv4) + ateIBGPNeighborThree.PeerGroup = ygot.String(peerGroupName) + ateIBGPNeighborThree.PeerAs = ygot.Uint32(atePeer2Asn) + ateIBGPNeighborThree.Enabled = ygot.Bool(true) + + ateIBGPNeighborThreeIPv4AF := ateIBGPNeighborThree.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + ateIBGPNeighborThreeIPv4AF.SetEnabled(true) + + ateIBGPNeighborThreeIPv6AF := ateIBGPNeighborThree.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + ateIBGPNeighborThreeIPv6AF.SetEnabled(true) + + ateIBGPNeighborFour := bgp.GetOrCreateNeighbor(atePort3.IPv6) + ateIBGPNeighborFour.PeerGroup = ygot.String(peerGroupName) + ateIBGPNeighborFour.PeerAs = ygot.Uint32(atePeer2Asn) + ateIBGPNeighborFour.Enabled = ygot.Bool(true) + + ateIBGPNeighborFourIPv4AF := ateIBGPNeighborFour.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + ateIBGPNeighborFourIPv4AF.SetEnabled(true) + + ateIBGPNeighborFourIPv6AF := ateIBGPNeighborFour.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + ateIBGPNeighborFourIPv6AF.SetEnabled(true) + + gnmi.Replace(t, dut, bgpPath.Config(), networkInstanceProtocolBgp) +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + for portName, portAttrs := range dutPorts { + port := dut.Port(t, portName) + configureDUTPort(t, dut, port, portAttrs) + } + + configureDUTRoutingPolicy(t, dut) + configureDUTStatic(t, dut) + configureDUTBGP(t, dut) +} + +func awaitBGPEstablished(t *testing.T, dut *ondatra.DUTDevice, neighbors []string) { + for _, neighbor := range neighbors { + gnmi.Await(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). + Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP"). + Bgp(). + Neighbor(neighbor). + SessionState().State(), time.Second*120, oc.Bgp_Neighbor_SessionState_ESTABLISHED) + } +} + +func configureOTG(t *testing.T) gosnappi.Config { + t.Helper() + + otgConfig := gosnappi.NewConfig() + + port1 := otgConfig.Ports().Add().SetName("port1") + port2 := otgConfig.Ports().Add().SetName("port2") + port3 := otgConfig.Ports().Add().SetName("port3") + + // Port3 Configuration. + iDut3Dev := otgConfig.Devices().Add().SetName(atePort3.Name) + iDut3Eth := iDut3Dev.Ethernets().Add().SetName(atePort3.Name + ".Eth").SetMac(atePort3.MAC) + iDut3Eth.Connection().SetPortName(port3.Name()) + iDut3Ipv4 := iDut3Eth.Ipv4Addresses().Add().SetName(atePort3.Name + ".IPv4") + iDut3Ipv4.SetAddress(atePort3.IPv4).SetGateway(dutPort3.IPv4).SetPrefix(uint32(atePort3.IPv4Len)) + iDut3Ipv6 := iDut3Eth.Ipv6Addresses().Add().SetName(atePort3.Name + ".IPv6") + iDut3Ipv6.SetAddress(atePort3.IPv6).SetGateway(dutPort3.IPv6).SetPrefix(uint32(atePort3.IPv6Len)) + + // Port1 Configuration. + iDut1Dev := otgConfig.Devices().Add().SetName(atePort1.Name) + iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1.Name + ".Eth").SetMac(atePort1.MAC) + iDut1Eth.Connection().SetPortName(port1.Name()) + iDut1Ipv4 := iDut1Eth.Ipv4Addresses().Add().SetName(atePort1.Name + ".IPv4") + iDut1Ipv4.SetAddress(atePort1.IPv4).SetGateway(dutPort1.IPv4).SetPrefix(uint32(atePort1.IPv4Len)) + iDut1Ipv6 := iDut1Eth.Ipv6Addresses().Add().SetName(atePort1.Name + ".IPv6") + iDut1Ipv6.SetAddress(atePort1.IPv6).SetGateway(dutPort1.IPv6).SetPrefix(uint32(atePort1.IPv6Len)) + + // Port2 Configuration. + iDut2Dev := otgConfig.Devices().Add().SetName(atePort2.Name) + iDut2Eth := iDut2Dev.Ethernets().Add().SetName(atePort2.Name + ".Eth").SetMac(atePort2.MAC) + iDut2Eth.Connection().SetPortName(port2.Name()) + iDut2Ipv4 := iDut2Eth.Ipv4Addresses().Add().SetName(atePort2.Name + ".IPv4") + iDut2Ipv4.SetAddress(atePort2.IPv4).SetGateway(dutPort2.IPv4).SetPrefix(uint32(atePort2.IPv4Len)) + iDut2Ipv6 := iDut2Eth.Ipv6Addresses().Add().SetName(atePort2.Name + ".IPv6") + iDut2Ipv6.SetAddress(atePort2.IPv6).SetGateway(dutPort2.IPv6).SetPrefix(uint32(atePort2.IPv6Len)) + + // eBGP v4 session on Port1. + iDut1Bgp := iDut1Dev.Bgp().SetRouterId(iDut1Ipv4.Address()) + iDut1Bgp4Peer := iDut1Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut1Ipv4.Name()).Peers().Add().SetName(atePort1.Name + ".BGP4.peer") + iDut1Bgp4Peer.SetPeerAddress(iDut1Ipv4.Gateway()).SetAsNumber(atePeer1Asn).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut1Bgp4Peer.Capability().SetIpv4UnicastAddPath(true) + iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) + // eBGP v6 session on Port1. + iDut1Bgp6Peer := iDut1Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut1Ipv6.Name()).Peers().Add().SetName(atePort1.Name + ".BGP6.peer") + iDut1Bgp6Peer.SetPeerAddress(iDut1Ipv6.Gateway()).SetAsNumber(atePeer1Asn).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + iDut1Bgp6Peer.Capability().SetIpv6UnicastAddPath(true) + iDut1Bgp6Peer.LearnedInformationFilter().SetUnicastIpv6Prefix(true) + + // iBGP v4 session on Port3. + iDut3Bgp := iDut3Dev.Bgp().SetRouterId(iDut3Ipv4.Address()) + iDut3Bgp4Peer := iDut3Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut3Ipv4.Name()).Peers().Add().SetName(atePort3.Name + ".BGP4.peer") + iDut3Bgp4Peer.SetPeerAddress(iDut3Ipv4.Gateway()).SetAsNumber(atePeer2Asn).SetAsType(gosnappi.BgpV4PeerAsType.IBGP) + iDut3Bgp4Peer.Capability().SetIpv4UnicastAddPath(true) + iDut3Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) + // iBGP v6 session on Port3. + iDut3Bgp6Peer := iDut3Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut3Ipv6.Name()).Peers().Add().SetName(atePort3.Name + ".BGP6.peer") + iDut3Bgp6Peer.SetPeerAddress(iDut3Ipv6.Gateway()).SetAsNumber(atePeer2Asn).SetAsType(gosnappi.BgpV6PeerAsType.IBGP) + iDut3Bgp6Peer.Capability().SetIpv6UnicastAddPath(true) + iDut3Bgp6Peer.LearnedInformationFilter().SetUnicastIpv6Prefix(true) + + return otgConfig +} + +// Configure OTG traffic-flow +func configureTrafficFlow(t *testing.T, otgConfig gosnappi.Config, isV4 bool, name, flowSrcEndPoint, flowDstEndPoint, srcMac, srcIp, dstIp string) gosnappi.Config { + t.Helper() + + // ATE Traffic Configuration. + t.Logf("TestBGP:start ate Traffic config: %v", name) + + otgConfig.Flows().Clear() + + flow := otgConfig.Flows().Add().SetName(name) + flow.Metrics().SetEnable(true) + flow.TxRx().Device(). + SetTxNames([]string{flowSrcEndPoint}). + SetRxNames([]string{flowDstEndPoint}) + flow.Size().SetFixed(1500) + flow.Duration().FixedPackets().SetPackets(1000) + e := flow.Packet().Add().Ethernet() + e.Src().SetValue(srcMac) + if isV4 { + v4 := flow.Packet().Add().Ipv4() + v4.Src().SetValue(srcIp) + v4.Dst().SetValue(dstIp) + } else { + v6 := flow.Packet().Add().Ipv6() + v6.Src().SetValue(srcIp) + v6.Dst().SetValue(dstIp) + } + + return otgConfig +} + +// Sending traffic over configured flow for fixed duration +func sendTraffic(t *testing.T, otg *otg.OTG) { + t.Logf("Starting traffic") + otg.StartTraffic(t) + time.Sleep(trafficDuration) + t.Logf("Stop traffic") + otg.StopTraffic(t) +} + +// Validate traffic flow +func verifyTraffic(t *testing.T, ate *ondatra.ATEDevice, conf gosnappi.Config) { + otg := ate.OTG() + otgutils.LogFlowMetrics(t, otg, conf) + for _, flow := range conf.Flows().Items() { + recvMetric := gnmi.Get(t, otg, gnmi.OTG().Flow(flow.Name()).State()) + txPackets := float32(recvMetric.GetCounters().GetOutPkts()) + rxPackets := float32(recvMetric.GetCounters().GetInPkts()) + if txPackets == 0 { + t.Fatalf("TxPkts = 0, want > 0") + } + lostPackets := txPackets - rxPackets + lossPct := lostPackets * 100 / txPackets + if lossPct > tolerancePct { + t.Errorf("Traffic Loss Pct for Flow %s: got %v, want max %v pct failure", flow.Name(), lossPct, tolerancePct) + } else { + t.Logf("Traffic Test Passed! for flow %s", flow.Name()) + } + } +} + +// Configure table-connection with source as static-route and destination as bgp +func configureTableConnection(t *testing.T, dut *ondatra.DUTDevice, isV4, mPropagation bool, importPolicy string, defaultImport oc.E_RoutingPolicy_DefaultPolicyType) { + + t.Helper() + + niPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) + dutOcRoot := &oc.Root{} + networkInstance := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + addressFamily := oc.Types_ADDRESS_FAMILY_IPV4 + if !isV4 { + addressFamily = oc.Types_ADDRESS_FAMILY_IPV6 + } + + tc := networkInstance.GetOrCreateTableConnection( + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, + addressFamily, + ) + + tc.SetDefaultImportPolicy(defaultImport) + if importPolicy != "" { + tc.SetImportPolicy([]string{importPolicy}) + } + tc.SetDisableMetricPropagation(!mPropagation) + gnmi.Update(t, dut, niPath.Config(), networkInstance) +} + +// Populate routing-policy to redistribute static-route +func redistributeStaticRoute(t *testing.T, isV4 bool, mPropagation, policyResultNext bool, routingPolicy *oc.RoutingPolicy) *oc.RoutingPolicy { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := "redistribute-static" + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + } + + apolicy := routingPolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyName) + astmt, err := apolicy.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + astmt.GetOrCreateConditions().SetInstallProtocolEq(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC) + astmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + if policyResultNext { + astmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT + } + astmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetRouteOrigin(oc.E_BgpPolicy_BgpOriginAttrType(oc.BgpPolicy_BgpOriginAttrType_IGP)) + astmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(oc.UnionUint32(medZero)) + if mPropagation { + astmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(oc.E_BgpActions_SetMed(oc.BgpActions_SetMed_IGP)) + } + + return routingPolicy +} + +// Configure routing-policy to redistribute static-route +func configureStaticRedistributionPolicy(t *testing.T, dut *ondatra.DUTDevice, isV4, acceptRoute, mPropagation bool) { + + t.Helper() + + dutOcRoot := &oc.Root{} + rp := dutOcRoot.GetOrCreateRoutingPolicy() + rp = redistributeStaticRoute(t, isV4, mPropagation, !policyResultNext, rp) + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + } + + astmt := rp.GetPolicyDefinition(redistributeStaticPolicyName).GetStatement("redistribute-static") + astmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE + if acceptRoute { + astmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + } + + rpConfPath := gnmi.OC().RoutingPolicy() + gnmi.Replace(t, dut, rpConfPath.PolicyDefinition(redistributeStaticPolicyName).Config(), rp.GetOrCreatePolicyDefinition(redistributeStaticPolicyName)) + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyName}) +} + +// Validate configurations for table-connections and routing-policy +func validateRedistributeStatic(t *testing.T, dut *ondatra.DUTDevice, acceptRoute, isV4, mPropagation bool) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := "redistribute-static" + af := oc.Types_ADDRESS_FAMILY_IPV4 + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy().State() + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + af = oc.Types_ADDRESS_FAMILY_IPV6 + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy().State() + } + + if !deviations.TableConnectionsUnsupported(dut) { + tcState := gnmi.Get(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).TableConnection( + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, + af).State()) + + if tcState.GetSrcProtocol() != oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC { + t.Fatal("source protocol not static for table connection but should be") + } + + if tcState.GetDstProtocol() != oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP { + t.Fatal("destination protocol not bgp for table connection but should be") + } + + if tcState.GetAddressFamily() != af { + t.Fatal("address family not as expected or table connection but should be") + } + + if !mPropagation { + if tcState.GetDisableMetricPropagation() { + t.Fatal("Metric propagation disabled for table connection, expected enabled") + } + } else { + if !tcState.GetDisableMetricPropagation() { + t.Fatal("Metric propagation is enabled for table connection, expected disabled") + } + } + + importPolicies := tcState.GetImportPolicy() + found := false + for _, iPolicy := range importPolicies { + if iPolicy == redistributeStaticPolicyName { + found = true + } + } + + if !found { + t.Fatal("Expected import policy is not configured") + } + + if acceptRoute { + if tcState.GetDefaultImportPolicy() != oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE { + t.Fatal("default import policy is not accept route but it should be") + } + } else { + if tcState.GetDefaultImportPolicy() != oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE { + t.Fatal("default import policy is not reject route but it should be") + } + } + } else { + var foundPDef oc.RoutingPolicy_PolicyDefinition + policyDef := gnmi.GetAll(t, dut, gnmi.OC().RoutingPolicy().PolicyDefinitionAny().State()) + for _, pDef := range policyDef { + if pDef.GetName() == redistributeStaticPolicyName { + foundPDef = *pDef + } + } + + if foundPDef.GetName() != redistributeStaticPolicyName { + t.Fatal("Expected import policy is not configured") + } + + if foundPDef.GetStatement(policyStatementName).GetOrCreateConditions().GetInstallProtocolEq() != oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC { + t.Fatal("Source protocol not static for redistribution policy.Expected static protocol") + } + + if mPropagation { + if foundPDef.GetStatement(policyStatementName).GetActions().GetBgpActions().GetSetMed() != oc.E_BgpActions_SetMed(oc.BgpActions_SetMed_IGP) { + t.Fatal("Expected metric propagation is not configured") + } + } + + found := false + bgpPolicy := gnmi.Get(t, dut, bgpPath) + for _, exPol := range bgpPolicy { + if exPol == redistributeStaticPolicyName { + found = true + t.Logf("bgp associated with routing-policy: %v", exPol) + } + } + if !found { + t.Fatal("BGP not associated with expected policy") + } + } +} + +// Validate prefix-set routing-policy configurations +func validatePrefixSetRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, isV4 bool) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := policyStatementNameV4 + prefixSetName := "prefix-set-v4" + prefixSetMode := oc.PrefixSet_Mode_IPV4 + prefixAddress := "192.168.10.0/24" + prefixMaskLen := "exact" + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + policyStatementName = policyStatementNameV6 + prefixSetName = "prefix-set-v6" + prefixSetMode = oc.PrefixSet_Mode_IPV6 + prefixAddress = "2024:db8:128:128::/64" + } + + var foundPDef oc.RoutingPolicy_PolicyDefinition + policyDef := gnmi.GetAll(t, dut, gnmi.OC().RoutingPolicy().PolicyDefinitionAny().State()) + for _, pDef := range policyDef { + if pDef.GetName() == redistributeStaticPolicyName { + foundPDef = *pDef + } + } + + if foundPDef.GetName() != redistributeStaticPolicyName { + t.Fatal("Expected import policy is not configured") + } + + if foundPDef.GetStatement(policyStatementName).GetActions().GetPolicyResult() != oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE { + t.Fatalf("Routing-policy result unexpectd for statement %v. It is not set to ACCEPT_ROUTE.", policyStatementName) + } + + if foundPDef.GetStatement(policyStatementName).GetConditions().GetMatchPrefixSet().GetPrefixSet() != prefixSetName { + t.Fatal("Routing-policy not associated with expected prefix-set") + } + + if !deviations.SkipSetRpMatchSetOptions(dut) { + if foundPDef.GetStatement(policyStatementName).GetConditions().GetMatchPrefixSet().GetMatchSetOptions() != oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY { + t.Fatal("Routing-policy prefix-set match-set-option not set to ANY") + } + } + + var foundPSet oc.RoutingPolicy_DefinedSets_PrefixSet + prefixSet := gnmi.GetAll(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSetAny().State()) + for _, pSet := range prefixSet { + if pSet.GetName() == prefixSetName { + foundPSet = *pSet + } + } + + if foundPSet.GetName() != prefixSetName { + t.Fatal("Expected prefix-set is not configured") + } + + if !deviations.SkipPrefixSetMode(dut) { + if foundPSet.GetMode() != prefixSetMode { + t.Fatal("Expected prefix-set mode is not configured") + } + } + + if foundPSet.GetPrefix(prefixAddress, prefixMaskLen).GetIpPrefix() != prefixAddress { + t.Fatal("Expected prefix not configured in prefix-set") + } +} + +// 1.27.1 setup function +func redistributeIPv4Static(t *testing.T, dut *ondatra.DUTDevice) { + if deviations.TableConnectionsUnsupported(dut) { + configureStaticRedistributionPolicy(t, dut, isV4, acceptRoute, !metricPropagate) + } else { + configureTableConnection(t, dut, isV4, !metricPropagate, "", oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.1 validation function +func validateRedistributeIPv4Static(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + validateRedistributeStatic(t, dut, acceptRoute, isV4, !metricPropagate) + validateLearnedIPv4Prefix(t, ate, atePort1.Name+".BGP4.peer", "192.168.10.0", medZero, shouldBePresent) +} + +// 1.27.2 setup function +func redistributeIPv4StaticWithMetricPropagation(t *testing.T, dut *ondatra.DUTDevice) { + if deviations.TableConnectionsUnsupported(dut) { + configureStaticRedistributionPolicy(t, dut, isV4, acceptRoute, metricPropagate) + } else { + configureTableConnection(t, dut, isV4, metricPropagate, "", oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.2 validation function +func validateRedistributeIPv4StaticWithMetricPropagation(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + validateRedistributeStatic(t, dut, acceptRoute, isV4, metricPropagate) + validateLearnedIPv4Prefix(t, ate, atePort1.Name+".BGP4.peer", "192.168.10.0", medIPv4, shouldBePresent) +} + +// 1.27.3 setup function +func redistributeIPv6Static(t *testing.T, dut *ondatra.DUTDevice) { + if deviations.TableConnectionsUnsupported(dut) { + configureStaticRedistributionPolicy(t, dut, !isV4, acceptRoute, !metricPropagate) + } else { + configureTableConnection(t, dut, !isV4, !metricPropagate, "", oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.3 validation function +func validateRedistributeIPv6Static(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + validateRedistributeStatic(t, dut, acceptRoute, !isV4, !metricPropagate) + validateLearnedIPv6Prefix(t, ate, atePort1.Name+".BGP6.peer", "2024:db8:128:128::", medZero, shouldBePresent) +} + +// 1.27.4 setup function +func redistributeIPv6StaticWithMetricPropagation(t *testing.T, dut *ondatra.DUTDevice) { + if deviations.TableConnectionsUnsupported(dut) { + configureStaticRedistributionPolicy(t, dut, !isV4, acceptRoute, metricPropagate) + } else { + configureTableConnection(t, dut, !isV4, metricPropagate, "", oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.4 validation function +func validateRedistributeIPv6StaticWithMetricPropagation(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + validateRedistributeStatic(t, dut, acceptRoute, !isV4, metricPropagate) + validateLearnedIPv6Prefix(t, ate, atePort1.Name+".BGP6.peer", "2024:db8:128:128::", medIPv6, shouldBePresent) +} + +// 1.27.5 setup function +func redistributeIPv4IPv6StaticDefaultRejectPolicy(t *testing.T, dut *ondatra.DUTDevice) { + if deviations.TableConnectionsUnsupported(dut) { + configureStaticRedistributionPolicy(t, dut, isV4, !acceptRoute, !metricPropagate) + configureStaticRedistributionPolicy(t, dut, !isV4, !acceptRoute, !metricPropagate) + } else { + configureTableConnection(t, dut, isV4, !metricPropagate, "", oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + configureTableConnection(t, dut, !isV4, !metricPropagate, "", oc.RoutingPolicy_DefaultPolicyType_REJECT_ROUTE) + } +} + +// 1.27.5 validation function +func validateRedistributeIPv4IPv6DefaultRejectPolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + validateRedistributeStatic(t, dut, !acceptRoute, isV4, !metricPropagate) + validateRedistributeStatic(t, dut, !acceptRoute, !isV4, !metricPropagate) + validateLearnedIPv4Prefix(t, ate, atePort1.Name+".BGP4.peer", "192.168.10.0", medZero, !shouldBePresent) + validateLearnedIPv6Prefix(t, ate, atePort1.Name+".BGP6.peer", "2024:db8:128:128::", medZero, !shouldBePresent) +} + +// 1.27.6 setup function +func redistributeIPv4PrefixRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyNameV4) + + otgConfig := configureOTG(t) + otgConfig = configureTrafficFlow(t, otgConfig, isV4, "StaticRoutesV4Flow", atePort1.Name+".IPv4", atePort2.Name+".IPv4", atePort1.MAC, atePort1.IPv4, "192.168.10.0") + ate.OTG().PushConfig(t, otgConfig) + ate.OTG().StartProtocols(t) + + dutOcRoot := &oc.Root{} + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + if deviations.TableConnectionsUnsupported(dut) { + redistributePolicy = redistributeStaticRoute(t, isV4, metricPropagate, policyResultNext, redistributePolicy) + } + + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyNameV4) + + v4PrefixSet := redistributePolicy.GetOrCreateDefinedSets().GetOrCreatePrefixSet("prefix-set-v4") + v4PrefixSet.GetOrCreatePrefix("192.168.10.0/24", "exact") + if !deviations.SkipPrefixSetMode(dut) { + v4PrefixSet.SetMode(oc.PrefixSet_Mode_IPV4) + } + + v4PrefixSet.GetOrCreatePrefix("192.168.20.0/24", "exact") + if !deviations.SkipPrefixSetMode(dut) { + v4PrefixSet.SetMode(oc.PrefixSet_Mode_IPV4) + } + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet("prefix-set-v4").Config(), v4PrefixSet) + + ipv4PrefixPolicyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementNameV4) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + ipv4PrefixPolicyStatementAction := ipv4PrefixPolicyStatement.GetOrCreateActions() + ipv4PrefixPolicyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + ipv4PrefixPolicyStatementConditionsPrefixes := ipv4PrefixPolicyStatement.GetOrCreateConditions().GetOrCreateMatchPrefixSet() + ipv4PrefixPolicyStatementConditionsPrefixes.SetPrefixSet("prefix-set-v4") + if !deviations.SkipSetRpMatchSetOptions(dut) { + ipv4PrefixPolicyStatementConditionsPrefixes.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + if deviations.TableConnectionsUnsupported(dut) { + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyNameV4}) + } else { + configureTableConnection(t, dut, isV4, metricPropagate, redistributeStaticPolicyNameV4, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } + + sendTraffic(t, ate.OTG()) + verifyTraffic(t, ate, otgConfig) +} + +// 1.27.6 validation function +func validateRedistributeIPv4PrefixRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + validateRedistributeStatic(t, dut, acceptRoute, isV4, metricPropagate) + validatePrefixSetRoutingPolicy(t, dut, isV4) + validateLearnedIPv4Prefix(t, ate, atePort1.Name+".BGP4.peer", "192.168.10.0", medIPv4, shouldBePresent) +} + +// 1.27.7 and 1.27.16 setup function +func redistributeStaticRoutePolicyWithASN(t *testing.T, dut *ondatra.DUTDevice, isV4 bool) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := policyStatementNameV4 + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + policyStatementName = policyStatementNameV6 + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + } + + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyName) + + dutOcRoot := &oc.Root{} + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + + if deviations.TableConnectionsUnsupported(dut) { + redistributePolicy = redistributeStaticRoute(t, isV4, metricPropagate, policyResultNext, redistributePolicy) + } + + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyName) + policyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + policyStatementAction := policyStatement.GetOrCreateActions() + policyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + policyStatementAction.GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend().Asn = ygot.Uint32(64512) + if isV4 { + policyStatementAction.GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend().Asn = ygot.Uint32(65499) + policyStatementAction.GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend().SetRepeatN(3) + } + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + if deviations.TableConnectionsUnsupported(dut) { + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyName}) + } else { + configureTableConnection(t, dut, isV4, metricPropagate, redistributeStaticPolicyName, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.8 and 1.27.17 setup function +func redistributeStaticRoutePolicyWithMED(t *testing.T, dut *ondatra.DUTDevice, isV4 bool, medValue uint32) { + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := policyStatementNameV4 + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + policyStatementName = policyStatementNameV6 + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + } + + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyName) + + dutOcRoot := &oc.Root{} + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + + if deviations.TableConnectionsUnsupported(dut) { + redistributePolicy = redistributeStaticRoute(t, isV4, metricPropagate, policyResultNext, redistributePolicy) + } + + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyName) + policyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + policyStatementAction := policyStatement.GetOrCreateActions() + policyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + policyStatement.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(oc.UnionUint32(medValue)) + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + if deviations.TableConnectionsUnsupported(dut) { + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyName}) + } else { + configureTableConnection(t, dut, isV4, metricPropagate, redistributeStaticPolicyName, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.9 and 1.27.18 setup function +func redistributeStaticRoutePolicyWithLocalPreference(t *testing.T, dut *ondatra.DUTDevice, isV4 bool, localPreferenceValue uint32) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := policyStatementNameV4 + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort3.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + policyStatementName = policyStatementNameV6 + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort3.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + } + + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyName) + + dutOcRoot := &oc.Root{} + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + + if deviations.TableConnectionsUnsupported(dut) { + redistributePolicy = redistributeStaticRoute(t, isV4, metricPropagate, policyResultNext, redistributePolicy) + } + + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyName) + policyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + policyStatementAction := policyStatement.GetOrCreateActions() + policyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + policyStatement.GetOrCreateActions().GetOrCreateBgpActions().SetLocalPref = ygot.Uint32(localPreferenceValue) + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + if deviations.TableConnectionsUnsupported(dut) { + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyName}) + } else { + configureTableConnection(t, dut, isV4, metricPropagate, redistributeStaticPolicyName, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.10 and 1.27.19 setup function +func redistributeStaticRoutePolicyWithCommunitySet(t *testing.T, dut *ondatra.DUTDevice, isV4 bool) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := policyStatementNameV4 + communitySetName := "community-set-v4" + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort3.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + policyStatementName = policyStatementNameV6 + communitySetName = "community-set-v6" + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort3.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + } + + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyName) + communityPath := gnmi.OC().RoutingPolicy().DefinedSets().BgpDefinedSets().CommunitySet(communitySetName) + + dutOcRoot := &oc.Root{} + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + if deviations.TableConnectionsUnsupported(dut) { + redistributePolicy = redistributeStaticRoute(t, isV4, metricPropagate, policyResultNext, redistributePolicy) + } + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyName) + + communitySet := dutOcRoot.GetOrCreateRoutingPolicy() + communitySetPolicyDefinition := communitySet.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(communitySetName) + communitySetPolicyDefinition.SetCommunityMember([]oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{oc.UnionString("64512:100")}) + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + gnmi.Replace(t, dut, communityPath.Config(), communitySetPolicyDefinition) + + policyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + policyStatementAction := policyStatement.GetOrCreateActions() + policyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + policyStatementAction.GetOrCreateBgpActions().GetOrCreateSetCommunity().SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + policyStatementAction.GetOrCreateBgpActions().GetOrCreateSetCommunity().GetOrCreateReference().SetCommunitySetRef(communitySetName) + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + if deviations.TableConnectionsUnsupported(dut) { + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyName}) + } else { + configureTableConnection(t, dut, isV4, metricPropagate, redistributeStaticPolicyName, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.12, 1.27.13, 1.27.20 and 1.27.21 setup function +func redistributeStaticRoutePolicyWithTagSet(t *testing.T, dut *ondatra.DUTDevice, isV4 bool, tagSetValue uint32) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + tagSetName := "tag-set-v4" + policyStatementName := policyStatementNameV4 + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + tagSetName = "tag-set-v6" + policyStatementName = policyStatementNameV6 + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + } + + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyName) + tagSetPath := gnmi.OC().RoutingPolicy().DefinedSets().TagSet(tagSetName) + + dutOcRoot := &oc.Root{} + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyName) + + if deviations.TableConnectionsUnsupported(dut) { + redistributeStaticRoute(t, isV4, !metricPropagate, policyResultNext, redistributePolicy) + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + configureRoutingPolicyTagSet(t, dut, isV4, tagSetValue) + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyName}) + } else { + tagSet := dutOcRoot.GetOrCreateRoutingPolicy() + tagSetPolicyDefinition := tagSet.GetOrCreateDefinedSets().GetOrCreateTagSet(tagSetName) + tagSetPolicyDefinition.SetTagValue([]oc.RoutingPolicy_DefinedSets_TagSet_TagValue_Union{oc.UnionString(fmt.Sprintf("%v", tagSetValue))}) + gnmi.Replace(t, dut, tagSetPath.Config(), tagSetPolicyDefinition) + + policyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + policyStatementCondition := policyStatement.GetOrCreateConditions() + if !deviations.SkipSetRpMatchSetOptions(dut) { + policyStatementCondition.GetOrCreateMatchTagSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + policyStatementCondition.GetOrCreateMatchTagSet().SetTagSet(tagSetName) + policyStatementAction := policyStatement.GetOrCreateActions() + policyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + configureTableConnection(t, dut, isV4, !metricPropagate, redistributeStaticPolicyName, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } +} + +// 1.27.14 and 1.27.22 setup function +func redistributeNullNextHopStaticRoute(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice, isV4 bool) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + tagSetName := "tag-set-v4" + tagValue := "40" + policyStatementName := policyStatementNameV4 + ipRoute := "192.168.20.0/24" + routeNextHop := "192.168.1.9" + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + tagSetName = "tag-set-v6" + tagValue = "60" + policyStatementName = policyStatementNameV6 + ipRoute = "2024:db8:64:64::/64" + routeNextHop = "2001:DB8::9" + bgpPath = gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + } + + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyName) + staticPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, "static") + + otgConfig := configureOTG(t) + if isV4 { + otgConfig = configureTrafficFlow(t, otgConfig, isV4, "StaticDropRoutesV4Flow", atePort3.Name+".IPv4", atePort2.Name+".IPv4", atePort3.MAC, atePort3.IPv4, "192.168.20.0") + } else { + otgConfig = configureTrafficFlow(t, otgConfig, isV4, "StaticDropRoutesV6Flow", atePort3.Name+".IPv6", atePort2.Name+".IPv6", atePort3.MAC, atePort3.IPv6, "2024:db8:64:64::") + } + ate.OTG().PushConfig(t, otgConfig) + ate.OTG().StartProtocols(t) + + dutOcRoot := &oc.Root{} + networkInstance := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + networkInstanceProtocolStatic := networkInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, "static") + networkInstanceProtocolStatic.SetEnabled(true) + ipStaticRoute := networkInstanceProtocolStatic.GetOrCreateStatic(ipRoute) + if !deviations.UseVendorNativeTagSetConfig(dut) { + ipStaticRoute.SetSetTag(oc.UnionString(tagValue)) + } else { + configureStaticRouteTagSet(t, dut) + attachTagSetToStaticRoute(t, dut, ipRoute, tagSetName) + } + ipStaticRouteNextHop := ipStaticRoute.GetOrCreateNextHop("0") + ipStaticRouteNextHop.SetNextHop(oc.LocalRouting_LOCAL_DEFINED_NEXT_HOP_DROP) + gnmi.Update(t, dut, staticPath.Config(), networkInstanceProtocolStatic) + + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyName) + + if deviations.TableConnectionsUnsupported(dut) { + redistributeStaticRoute(t, isV4, !metricPropagate, policyResultNext, redistributePolicy) + + statement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + statement.GetOrCreateActions().GetOrCreateBgpActions().SetSetNextHop(oc.UnionString(routeNextHop)) + statement.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyName}) + } else { + ipPrefixPolicyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementName) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + ipPrefixPolicyStatementAction := ipPrefixPolicyStatement.GetOrCreateActions() + ipPrefixPolicyStatementAction.GetOrCreateBgpActions().SetSetNextHop(oc.UnionString(routeNextHop)) + ipPrefixPolicyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + configureTableConnection(t, dut, isV4, !metricPropagate, redistributeStaticPolicyName, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } + + // Sending traffic to network via dut having static-route to drop it. + // Traffic must be dropped by the dut irrespective of the bgp advertised-route + // having updated next-hop, considering existing static-route is preferred over bgp. + // Commenting traffic validation for now + /* + sendTraffic(t, ate.OTG()) + verifyTraffic(t, ate, otgConfig) + */ +} + +// 1.27.15 setup function +func redistributeIPv6StaticRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + policyPath := gnmi.OC().RoutingPolicy().PolicyDefinition(redistributeStaticPolicyNameV6) + + otgConfig := configureOTG(t) + otgConfig = configureTrafficFlow(t, otgConfig, !isV4, "StaticRoutesV6Flow", atePort1.Name+".IPv6", atePort2.Name+".IPv6", atePort1.MAC, atePort1.IPv6, "2024:db8:128:128::") + ate.OTG().PushConfig(t, otgConfig) + ate.OTG().StartProtocols(t) + + dutOcRoot := &oc.Root{} + redistributePolicy := dutOcRoot.GetOrCreateRoutingPolicy() + if deviations.TableConnectionsUnsupported(dut) { + redistributePolicy = redistributeStaticRoute(t, !isV4, metricPropagate, policyResultNext, redistributePolicy) + } + redistributePolicyDefinition := redistributePolicy.GetOrCreatePolicyDefinition(redistributeStaticPolicyNameV6) + + v6PrefixSet := redistributePolicy.GetOrCreateDefinedSets().GetOrCreatePrefixSet("prefix-set-v6") + v6PrefixSet.GetOrCreatePrefix("2024:db8:128:128::/64", "exact") + if !deviations.SkipPrefixSetMode(dut) { + v6PrefixSet.SetMode(oc.PrefixSet_Mode_IPV6) + } + + v6PrefixSet.GetOrCreatePrefix("2024:db8:64:64::/64", "exact") + if !deviations.SkipPrefixSetMode(dut) { + v6PrefixSet.SetMode(oc.PrefixSet_Mode_IPV6) + } + + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().DefinedSets().PrefixSet("prefix-set-v6").Config(), v6PrefixSet) + + ipv6PrefixPolicyStatement, err := redistributePolicyDefinition.AppendNewStatement(policyStatementNameV6) + if err != nil { + t.Fatalf("failed creating new policy statement, err: %s", err) + } + + ipv6PrefixPolicyStatementAction := ipv6PrefixPolicyStatement.GetOrCreateActions() + ipv6PrefixPolicyStatementAction.SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + ipv6PrefixPolicyStatementConditionsPrefixes := ipv6PrefixPolicyStatement.GetOrCreateConditions().GetOrCreateMatchPrefixSet() + ipv6PrefixPolicyStatementConditionsPrefixes.SetPrefixSet("prefix-set-v6") + if !deviations.SkipSetRpMatchSetOptions(dut) { + ipv6PrefixPolicyStatementConditionsPrefixes.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY) + } + + gnmi.Replace(t, dut, policyPath.Config(), redistributePolicyDefinition) + + if deviations.TableConnectionsUnsupported(dut) { + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().Neighbor(atePort1.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ExportPolicy() + gnmi.Replace(t, dut, bgpPath.Config(), []string{redistributeStaticPolicyNameV6}) + } else { + configureTableConnection(t, dut, !isV4, metricPropagate, redistributeStaticPolicyNameV6, oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + } + + sendTraffic(t, ate.OTG()) + verifyTraffic(t, ate, otgConfig) +} + +// 1.27.15 validation function +func validateRedistributeIPv6RoutePolicy(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { + validateRedistributeStatic(t, dut, acceptRoute, !isV4, metricPropagate) + validatePrefixSetRoutingPolicy(t, dut, !isV4) + validateLearnedIPv6Prefix(t, ate, atePort1.Name+".BGP6.peer", "2024:db8:128:128::", medIPv6, shouldBePresent) +} + +// 1.27.7 and 1.27.16 validation function +func validatePrefixASN(t *testing.T, ate *ondatra.ATEDevice, isV4 bool, bgpPeerName, subnet string, wantASPath []uint32) { + + foundPrefix := false + + if isV4 { + prefixPath := gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv4PrefixAny() + prefix, ok := gnmi.WatchAll(t, ate.OTG(), prefixPath.State(), 10*time.Second, func(val *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { + prefix, _ := val.Val() + if prefix.GetAddress() == subnet { + foundPrefix = true + gotASPath := prefix.AsPath[len(prefix.AsPath)-1].GetAsNumbers() + t.Logf("Prefix %v learned with ASN : %v", prefix.GetAddress(), gotASPath) + return reflect.DeepEqual(gotASPath, wantASPath) + } + return false + }).Await(t) + if !ok { + pfx, _ := prefix.Val() + t.Fatalf("Prefix not updated with required as-path. Got %v, want %v", pfx.AsPath[len(pfx.AsPath)-1].GetAsNumbers(), wantASPath) + } + } else { + prefixPath := gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv6PrefixAny() + prefix, ok := gnmi.WatchAll(t, ate.OTG(), prefixPath.State(), 10*time.Second, func(val *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv6Prefix]) bool { + prefix, _ := val.Val() + if prefix.GetAddress() == subnet { + foundPrefix = true + gotASPath := prefix.AsPath[len(prefix.AsPath)-1].GetAsNumbers() + t.Logf("Prefix %v learned with ASN : %v", prefix.GetAddress(), gotASPath) + return reflect.DeepEqual(gotASPath, wantASPath) + } + return false + }).Await(t) + if !ok { + pfx, _ := prefix.Val() + t.Fatalf("Prefix not updated with required as-path. Got %v, want %v", pfx.AsPath[len(pfx.AsPath)-1].GetAsNumbers(), wantASPath) + } + } + if !foundPrefix { + t.Fatalf("Prefix %v not present in OTG", subnet) + } +} + +// 1.27.9 and 1.27.18 validation function +func validatePrefixLocalPreference(t *testing.T, ate *ondatra.ATEDevice, isV4 bool, bgpPeerName, subnet string, wantLocalPreference uint32) { + + foundPrefix := false + if isV4 { + prefixPath := gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv4PrefixAny() + prefix, ok := gnmi.WatchAll(t, ate.OTG(), prefixPath.State(), 10*time.Second, func(val *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { + prefix, _ := val.Val() + if prefix.GetAddress() == subnet { + foundPrefix = true + gotLocalPreference := prefix.GetLocalPreference() + t.Logf("Prefix %v learned with localPreference : %v", prefix.GetAddress(), gotLocalPreference) + return gotLocalPreference == wantLocalPreference + } + return false + }).Await(t) + if !ok { + pfx, _ := prefix.Val() + t.Fatalf("Prefix not updated with the local-preference. Got %v, want %v", pfx.GetLocalPreference(), wantLocalPreference) + } + } else { + prefixPath := gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv6PrefixAny() + prefix, ok := gnmi.WatchAll(t, ate.OTG(), prefixPath.State(), 10*time.Second, func(val *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv6Prefix]) bool { + prefix, _ := val.Val() + if prefix.GetAddress() == subnet { + foundPrefix = true + gotLocalPreference := prefix.GetLocalPreference() + t.Logf("Prefix %v learned with localPreference : %v", prefix.GetAddress(), gotLocalPreference) + return gotLocalPreference == wantLocalPreference + } + return false + }).Await(t) + if !ok { + pfx, _ := prefix.Val() + t.Fatalf("Prefix not updated with the local-preference. Got %v, want %v", pfx.GetLocalPreference(), wantLocalPreference) + } + } + if !foundPrefix { + t.Fatalf("Prefix %v not present in OTG", subnet) + } +} + +// 1.27.10 and 1.27.19 validation function +func validatePrefixCommunitySet(t *testing.T, ate *ondatra.ATEDevice, isV4 bool, bgpPeerName, subnet, wantCommunitySet string) { + + foundPrefix := false + if isV4 { + prefixPath := gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv4PrefixAny() + prefix, ok := gnmi.WatchAll(t, ate.OTG(), prefixPath.State(), 10*time.Second, func(val *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { + prefix, _ := val.Val() + if prefix.GetAddress() == subnet { + foundPrefix = true + var gotCommunitySet string + for _, community := range prefix.Community { + gotCommunityNumber := community.GetCustomAsNumber() + gotCommunityValue := community.GetCustomAsValue() + gotCommunitySet = fmt.Sprint(gotCommunityNumber) + ":" + fmt.Sprint(gotCommunityValue) + } + t.Logf("Prefix %v learned with CommunitySet : %v", prefix.GetAddress(), gotCommunitySet) + return gotCommunitySet == wantCommunitySet + } + return false + }).Await(t) + if !ok { + pfx, _ := prefix.Val() + var gotCS string + for _, community := range pfx.Community { + gotCN := community.GetCustomAsNumber() + gotCV := community.GetCustomAsValue() + gotCS = fmt.Sprint(gotCN) + ":" + fmt.Sprint(gotCV) + } + t.Fatalf("Prefix not updated with the community-set. Got %v, want %v", gotCS, wantCommunitySet) + } + } else { + prefixPath := gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv6PrefixAny() + prefix, ok := gnmi.WatchAll(t, ate.OTG(), prefixPath.State(), 10*time.Second, func(val *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv6Prefix]) bool { + prefix, _ := val.Val() + if prefix.GetAddress() == subnet { + foundPrefix = true + var gotCommunitySet string + for _, community := range prefix.Community { + gotCommunityNumber := community.GetCustomAsNumber() + gotCommunityValue := community.GetCustomAsValue() + gotCommunitySet = fmt.Sprint(gotCommunityNumber) + ":" + fmt.Sprint(gotCommunityValue) + } + t.Logf("Prefix %v learned with CommunitySet : %v", prefix.GetAddress(), gotCommunitySet) + return gotCommunitySet == wantCommunitySet + } + return false + }).Await(t) + if !ok { + pfx, _ := prefix.Val() + var gotCS string + for _, community := range pfx.Community { + gotCN := community.GetCustomAsNumber() + gotCV := community.GetCustomAsValue() + gotCS = fmt.Sprint(gotCN) + ":" + fmt.Sprint(gotCV) + } + t.Fatalf("Prefix not updated with the community-set. Got %v, want %v", gotCS, wantCommunitySet) + } + } + + if !foundPrefix { + t.Fatalf("Prefix %v not present in OTG", subnet) + } +} + +// 1.27.12, 1.27.13, 1.27.20 and 1.27.21 validation function +func validateRedistributeRouteWithTagSet(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice, isV4, shouldBePresent bool) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + af := oc.Types_ADDRESS_FAMILY_IPV4 + tagSet := "tag-set-v4" + policyStatementName := policyStatementNameV4 + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + af = oc.Types_ADDRESS_FAMILY_IPV6 + tagSet = "tag-set-v6" + policyStatementName = policyStatementNameV6 + } + + if !deviations.TableConnectionsUnsupported(dut) { + tcState := gnmi.Get(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).TableConnection( + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, + af).State()) + + importPolicies := tcState.GetImportPolicy() + found := false + for _, iPolicy := range importPolicies { + if iPolicy == redistributeStaticPolicyName { + found = true + } + } + + if !found { + t.Fatal("expected import policy is not configured") + } + } + + var foundPDef oc.RoutingPolicy_PolicyDefinition + policyDef := gnmi.GetAll(t, dut, gnmi.OC().RoutingPolicy().PolicyDefinitionAny().State()) + for _, pDef := range policyDef { + if pDef.GetName() == redistributeStaticPolicyName { + foundPDef = *pDef + } + } + + if foundPDef.GetName() != redistributeStaticPolicyName { + t.Fatal("Expected import policy is not configured") + } + if !deviations.UseVendorNativeTagSetConfig(dut) { + if foundPDef.GetStatement(policyStatementName).GetConditions().GetOrCreateMatchTagSet().GetTagSet() != tagSet { + t.Fatal("Expected tag-set is not configured") + } + if foundPDef.GetStatement(policyStatementName).GetConditions().GetOrCreateMatchTagSet().GetMatchSetOptions() != oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY { + t.Fatal("Expected match-set-option for tag-set is not configured") + } + } + + if isV4 { + validateLearnedIPv4Prefix(t, ate, atePort1.Name+".BGP4.peer", "192.168.10.0", medZero, shouldBePresent) + } else { + validateLearnedIPv6Prefix(t, ate, atePort1.Name+".BGP6.peer", "2024:db8:128:128::", medZero, shouldBePresent) + } +} + +// 1.27.14 and 1.27.22 validation function +func validateRedistributeNullNextHopStaticRoute(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice, isV4 bool) { + + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := policyStatementNameV4 + addressFamily := oc.Types_ADDRESS_FAMILY_IPV4 + nextHop := "192.168.1.9" + if !isV4 { + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + policyStatementName = policyStatementNameV6 + addressFamily = oc.Types_ADDRESS_FAMILY_IPV6 + nextHop = "2001:db8::9" + } + + if !deviations.TableConnectionsUnsupported(dut) { + tcState := gnmi.Get(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).TableConnection( + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, + addressFamily).State()) + + importPolicies := tcState.GetImportPolicy() + found := false + for _, iPolicy := range importPolicies { + if iPolicy == redistributeStaticPolicyName { + found = true + } + } + + if !found { + t.Fatal("expected import policy is not configured") + } + } + + var foundPDef oc.RoutingPolicy_PolicyDefinition + policyDef := gnmi.GetAll(t, dut, gnmi.OC().RoutingPolicy().PolicyDefinitionAny().State()) + for _, pDef := range policyDef { + if pDef.GetName() == redistributeStaticPolicyName { + foundPDef = *pDef + } + } + + if foundPDef.GetName() != redistributeStaticPolicyName { + t.Fatal("Expected import policy is not configured") + } + + if foundPDef.GetStatement(policyStatementName).GetActions().GetBgpActions().GetSetNextHop() != oc.UnionString(nextHop) { + t.Fatal("Expected next-hop is not configured") + } + + if isV4 { + validateLearnedIPv4Prefix(t, ate, atePort1.Name+".BGP4.peer", "192.168.20.0", medZero, shouldBePresent) + } else { + validateLearnedIPv6Prefix(t, ate, atePort1.Name+".BGP6.peer", "2024:db8:64:64::", medZero, shouldBePresent) + } +} + +// Used by multiple IPv4 test validations for route presence and MED value +func validateLearnedIPv4Prefix(t *testing.T, ate *ondatra.ATEDevice, bgpPeerName, subnet string, expectedMED uint32, shouldBePresent bool) { + var learnedRedistributedPrefix *otgtelemetry.BgpPeer_UnicastIpv4Prefix + time.Sleep(5 * time.Second) + + _, ok := gnmi.WatchAll(t, + ate.OTG(), + gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv4PrefixAny().State(), + 30*time.Second, + func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { + prefix, present := v.Val() + if present { + return prefix.GetAddress() == subnet + } + return false + }).Await(t) + + found := false + if ok { + prefixes := gnmi.GetAll(t, ate.OTG(), gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv4PrefixAny().State()) + for _, prefix := range prefixes { + if prefix.GetAddress() == subnet { + learnedRedistributedPrefix = prefix + found = true + t.Logf("Prefix learned in otg : %v with next-hop %v and MED %v", prefix.GetAddress(), prefix.GetNextHopIpv4Address(), prefix.GetMultiExitDiscriminator()) + if !shouldBePresent { + t.Fatal("Redistributed IPv4 prefix present in otg but should not be") + } + } + } + } + + if shouldBePresent && !ok && !found { + t.Fatal("Did not see redistributed IPv4 prefix in otg in time") + } + + actualMED := learnedRedistributedPrefix.GetMultiExitDiscriminator() + if actualMED != expectedMED { + t.Fatalf("ate learned redistributed prefix with med set to %d, expected %d", actualMED, expectedMED) + } +} + +// Used by multiple IPv6 test validations for route presence and MED value +func validateLearnedIPv6Prefix(t *testing.T, ate *ondatra.ATEDevice, bgpPeerName, subnet string, expectedMED uint32, shouldBePresent bool) { + + var learnedRedistributedPrefix *otgtelemetry.BgpPeer_UnicastIpv6Prefix + time.Sleep(5 * time.Second) + + _, ok := gnmi.WatchAll(t, + ate.OTG(), + gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv6PrefixAny().State(), + 30*time.Second, + func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv6Prefix]) bool { + prefix, present := v.Val() + if present { + return prefix.GetAddress() == subnet + } + return false + }).Await(t) + + found := false + if ok { + prefixes := gnmi.GetAll(t, ate.OTG(), gnmi.OTG().BgpPeer(bgpPeerName).UnicastIpv6PrefixAny().State()) + for _, prefix := range prefixes { + if prefix.GetAddress() == subnet { + learnedRedistributedPrefix = prefix + found = true + t.Logf("Prefix learned in otg : %v with next-hop %v and MED %v", prefix.GetAddress(), prefix.GetNextHopIpv6Address(), prefix.GetMultiExitDiscriminator()) + if !shouldBePresent { + t.Fatal("Redistributed IPv6 prefix present in otg but should not be") + } + } + } + } + + if shouldBePresent && !ok && !found { + t.Fatal("Did not see redistributed IPv6 prefix in otg in time") + } + + actualMED := learnedRedistributedPrefix.GetMultiExitDiscriminator() + if actualMED != expectedMED { + t.Fatalf("ate learned redistributed prefix %v with med set to %d, expected %d", subnet, actualMED, expectedMED) + } +} + +func TestBGPStaticRouteRedistribution(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + otg := ate.OTG() + + configureDUT(t, dut) + otgConfig := configureOTG(t) + otg.PushConfig(t, otgConfig) + otg.StartProtocols(t) + + awaitBGPEstablished(t, dut, []string{atePort1.IPv4, atePort3.IPv4}) + + type testCase struct { + name string + setup func() + validate func() + } + + testCases := []testCase{ + // 1.27.1 + { + name: "1.27.1 redistribute-ipv4-static-routes-with-metric-propagation-disabled", + setup: func() { redistributeIPv4Static(t, dut) }, + validate: func() { validateRedistributeIPv4Static(t, dut, ate) }, + }, + // 1.27.2 + { + name: "1.27.2 redistribute-ipv4-static-routes-with-metric-propagation-enabled", + setup: func() { redistributeIPv4StaticWithMetricPropagation(t, dut) }, + validate: func() { validateRedistributeIPv4StaticWithMetricPropagation(t, dut, ate) }, + }, + // 1.27.3 + { + name: "1.27.3 redistribute-ipv6-static-routes-with-metric-propagation-disabled", + setup: func() { redistributeIPv6Static(t, dut) }, + validate: func() { validateRedistributeIPv6Static(t, dut, ate) }, + }, + // 1.27.4 + { + name: "1.27.4 redistribute-ipv6-static-routes-with-metric-propagation-enabled", + setup: func() { redistributeIPv6StaticWithMetricPropagation(t, dut) }, + validate: func() { validateRedistributeIPv6StaticWithMetricPropagation(t, dut, ate) }, + }, + // 1.27.5 + { + name: "1.27.5 redistribute-ipv4-ipv6-default-reject-policy", + setup: func() { redistributeIPv4IPv6StaticDefaultRejectPolicy(t, dut) }, + validate: func() { validateRedistributeIPv4IPv6DefaultRejectPolicy(t, dut, ate) }, + }, + // 1.27.6 + { + name: "1.27.6 redistribute-ipv4-prefix-route-policy", + setup: func() { redistributeIPv4PrefixRoutePolicy(t, dut, ate) }, + validate: func() { validateRedistributeIPv4PrefixRoutePolicy(t, dut, ate) }, + }, + // 1.27.7 + { + name: "1.27.7 redistribute-ipv4-route-policy-as-prepend", + setup: func() { redistributeStaticRoutePolicyWithASN(t, dut, isV4) }, + validate: func() { + validatePrefixASN(t, ate, isV4, atePort1.Name+".BGP4.peer", "192.168.10.0", []uint32{64512, 65499, 65499, 65499}) + }, + }, + // 1.27.8 + { + name: "1.27.8 redistribute-ipv4-route-policy-med", + setup: func() { redistributeStaticRoutePolicyWithMED(t, dut, isV4, medNonZero) }, + validate: func() { + validateLearnedIPv4Prefix(t, ate, atePort1.Name+".BGP4.peer", "192.168.10.0", medNonZero, shouldBePresent) + }, + }, + // 1.27.9 + { + name: "1.27.9 redistribute-ipv4-route-policy-local-preference", + setup: func() { redistributeStaticRoutePolicyWithLocalPreference(t, dut, isV4, localPreference) }, + validate: func() { + validatePrefixLocalPreference(t, ate, isV4, atePort3.Name+".BGP4.peer", "192.168.10.0", localPreference) + }, + }, + // 1.27.10 + { + name: "1.27.10 redistribute-ipv4-route-policy-community-set", + setup: func() { redistributeStaticRoutePolicyWithCommunitySet(t, dut, isV4) }, + validate: func() { + validatePrefixCommunitySet(t, ate, isV4, atePort3.Name+".BGP4.peer", "192.168.10.0", "64512:100") + }, + }, + // 1.27.12 + { + name: "1.27.12 redistribute-ipv4-route-policy-unmatched-tag", + setup: func() { redistributeStaticRoutePolicyWithTagSet(t, dut, isV4, 100) }, + validate: func() { validateRedistributeRouteWithTagSet(t, dut, ate, isV4, !shouldBePresent) }, + }, + // 1.27.13 + { + name: "1.27.13 redistribute-ipv4-route-policy-matched-set", + setup: func() { redistributeStaticRoutePolicyWithTagSet(t, dut, isV4, 40) }, + validate: func() { validateRedistributeRouteWithTagSet(t, dut, ate, isV4, shouldBePresent) }, + }, + // 1.27.14 + { + name: "1.27.14 redistribute-ipv4-route-policy-nexthop", + setup: func() { redistributeNullNextHopStaticRoute(t, dut, ate, isV4) }, + validate: func() { validateRedistributeNullNextHopStaticRoute(t, dut, ate, isV4) }, + }, + // 1.27.15 + { + name: "1.27.15 redistribute-ipv6-route-policy", + setup: func() { redistributeIPv6StaticRoutePolicy(t, dut, ate) }, + validate: func() { validateRedistributeIPv6RoutePolicy(t, dut, ate) }, + }, + // 1.27.16 + { + name: "1.27.16 redistribute-ipv6-route-policy-as-prepend", + setup: func() { redistributeStaticRoutePolicyWithASN(t, dut, !isV4) }, + validate: func() { + validatePrefixASN(t, ate, !isV4, atePort1.Name+".BGP6.peer", "2024:db8:128:128::", []uint32{64512, 64512}) + }, + }, + // 1.27.17 + { + name: "1.27.17 redistribute-ipv6-route-policy-med", + setup: func() { redistributeStaticRoutePolicyWithMED(t, dut, !isV4, medNonZero) }, + validate: func() { + validateLearnedIPv6Prefix(t, ate, atePort1.Name+".BGP6.peer", "2024:db8:128:128::", medNonZero, shouldBePresent) + }, + }, + // 1.27.18 + { + name: "1.27.18 redistribute-ipv6-route-policy-local-preference", + setup: func() { redistributeStaticRoutePolicyWithLocalPreference(t, dut, !isV4, localPreference) }, + validate: func() { + validatePrefixLocalPreference(t, ate, !isV4, atePort3.Name+".BGP6.peer", "2024:db8:128:128::", localPreference) + }, + }, + // 1.27.19 + { + name: "1.27.19 redistribute-ipv6-route-policy-community-set", + setup: func() { redistributeStaticRoutePolicyWithCommunitySet(t, dut, !isV4) }, + validate: func() { + validatePrefixCommunitySet(t, ate, !isV4, atePort3.Name+".BGP6.peer", "2024:db8:128:128::", "64512:100") + }, + }, + // 1.27.20 + { + name: "1.27.20 redistribute-ipv6-route-policy-unmatched-tag", + setup: func() { redistributeStaticRoutePolicyWithTagSet(t, dut, !isV4, 100) }, + validate: func() { validateRedistributeRouteWithTagSet(t, dut, ate, !isV4, !shouldBePresent) }, + }, + // 1.27.21 + { + name: "1.27.21 redistribute-ipv6-route-policy-matched-set", + setup: func() { redistributeStaticRoutePolicyWithTagSet(t, dut, !isV4, 60) }, + validate: func() { validateRedistributeRouteWithTagSet(t, dut, ate, !isV4, shouldBePresent) }, + }, + // 1.27.22 + { + name: "1.27.22 redistribute-ipv6-route-policy-nexthop", + setup: func() { redistributeNullNextHopStaticRoute(t, dut, ate, !isV4) }, + validate: func() { validateRedistributeNullNextHopStaticRoute(t, dut, ate, !isV4) }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tc.setup() + tc.validate() + }) + } +} + +// Function using native-yang to attach tag-set to static-route +func attachTagSetToStaticRoute(t *testing.T, dut *ondatra.DUTDevice, prefix, tagPolicy string) { + + tagValue, err := json.Marshal(tagPolicy) + if err != nil { + t.Fatalf("Error with json Marshal: %v", err) + } + + gpbSetRequest := &gpb.SetRequest{ + Prefix: &gpb.Path{ + Origin: "native", + }, + Update: []*gpb.Update{ + { + Path: &gpb.Path{ + Elem: []*gpb.PathElem{ + {Name: "network-instance", Key: map[string]string{"name": "DEFAULT"}}, + {Name: "static-routes"}, + {Name: "route", Key: map[string]string{"prefix": prefix}}, + {Name: "tag-set"}, + }, + }, + Val: &gpb.TypedValue{ + Value: &gpb.TypedValue_JsonIetfVal{ + JsonIetfVal: tagValue, + }, + }, + }, + }, + } + + gnmiClient := dut.RawAPIs().GNMI(t) + if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { + t.Fatalf("Unexpected error updating SRL static-route tag-set: %v", err) + } + +} + +// Function using native-yang to configure tag-set used by static-route +func configureStaticRouteTagSet(t *testing.T, dut *ondatra.DUTDevice) { + + var routingPolicyTagSetValueV4 = []any{ + map[string]any{ + "tag-value": []any{ + 40, + }, + }, + } + tagValueV4, err := json.Marshal(routingPolicyTagSetValueV4) + if err != nil { + t.Fatalf("Error with json Marshal: %v", err) + } + var routingPolicyTagSetValueV6 = []any{ + map[string]any{ + "tag-value": []any{ + 60, + }, + }, + } + tagValueV6, err := json.Marshal(routingPolicyTagSetValueV6) + if err != nil { + t.Fatalf("Error with json Marshal: %v", err) + } + + gpbSetRequest := &gpb.SetRequest{ + Prefix: &gpb.Path{ + Origin: "native", + }, + Update: []*gpb.Update{ + { + Path: &gpb.Path{ + Elem: []*gpb.PathElem{ + {Name: "routing-policy"}, + {Name: "tag-set", Key: map[string]string{"name": "tag-static-v4"}}, + }, + }, + Val: &gpb.TypedValue{ + Value: &gpb.TypedValue_JsonIetfVal{ + JsonIetfVal: tagValueV4, + }, + }, + }, + { + Path: &gpb.Path{ + Elem: []*gpb.PathElem{ + {Name: "routing-policy"}, + {Name: "tag-set", Key: map[string]string{"name": "tag-static-v6"}}, + }, + }, + Val: &gpb.TypedValue{ + Value: &gpb.TypedValue_JsonIetfVal{ + JsonIetfVal: tagValueV6, + }, + }, + }, + }, + } + + gnmiClient := dut.RawAPIs().GNMI(t) + if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { + t.Fatalf("Unexpected error updating SRL routing-policy tag-set for static-route: %v", err) + } +} + +// Function using native-yang to configure tag-set with routing-policy +func configureRoutingPolicyTagSet(t *testing.T, dut *ondatra.DUTDevice, isV4 bool, tValue uint32) { + + tagSetName := "tag-set-v4" + redistributeStaticPolicyName := redistributeStaticPolicyNameV4 + policyStatementName := policyStatementNameV4 + if !isV4 { + tagSetName = "tag-set-v6" + redistributeStaticPolicyName = redistributeStaticPolicyNameV6 + policyStatementName = policyStatementNameV6 + } + + var routingPolicyTagSet = []any{ + map[string]any{ + "match": map[string]any{ + "internal-tags": map[string]any{ + "tag-set": []string{tagSetName}, + }, + }, + "action": map[string]any{ + "policy-result": "accept", + }, + }, + } + tagSetStatement, err := json.Marshal(routingPolicyTagSet) + if err != nil { + t.Fatalf("Error with json Marshal: %v", err) + } + var routingPolicyTagSetValue = []any{ + map[string]any{ + "tag-value": []any{ + tValue, + }, + }, + } + tagValue, err := json.Marshal(routingPolicyTagSetValue) + if err != nil { + t.Fatalf("Error with json Marshal: %v", err) + } + + gpbTagSetReplace := &gpb.SetRequest{ + Prefix: &gpb.Path{ + Origin: "native", + }, + Replace: []*gpb.Update{ + { + Path: &gpb.Path{ + Elem: []*gpb.PathElem{ + {Name: "routing-policy"}, + {Name: "tag-set", Key: map[string]string{"name": tagSetName}}, + }, + }, + Val: &gpb.TypedValue{ + Value: &gpb.TypedValue_JsonIetfVal{ + JsonIetfVal: tagValue, + }, + }, + }, + }, + } + + gpbPolicyUpdate := &gpb.SetRequest{ + Prefix: &gpb.Path{ + Origin: "native", + }, + Update: []*gpb.Update{ + { + Path: &gpb.Path{ + Elem: []*gpb.PathElem{ + {Name: "routing-policy"}, + {Name: "policy", Key: map[string]string{"name": redistributeStaticPolicyName}}, + {Name: "statement", Key: map[string]string{"name": policyStatementName}}, + }, + }, + Val: &gpb.TypedValue{ + Value: &gpb.TypedValue_JsonIetfVal{ + JsonIetfVal: tagSetStatement, + }, + }, + }, + }, + } + + gnmiClient := dut.RawAPIs().GNMI(t) + if _, err := gnmiClient.Set(context.Background(), gpbTagSetReplace); err != nil { + t.Fatalf("Unexpected error updating SRL routing-policy tag-set: %v", err) + } + if _, err := gnmiClient.Set(context.Background(), gpbPolicyUpdate); err != nil { + t.Fatalf("Unexpected error updating SRL routing-policy tag-set: %v", err) + } +} diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index c733fcf1611..8b23ea6aae3 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -906,3 +906,18 @@ func BgpExtendedCommunityIndexUnsupported(dut *ondatra.DUTDevice) bool { func BgpCommunitySetRefsUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetBgpCommunitySetRefsUnsupported() } + +// TableConnectionsUnsupported returns true if Table Connections are unsupported. +func TableConnectionsUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetTableConnectionsUnsupported() +} + +// UseVendorNativeTagSetConfig returns whether a device requires native model to configure tag-set +func UseVendorNativeTagSetConfig(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetUseVendorNativeTagSetConfig() +} + +// SkipBgpSendCommunityType return true if device needs to skip setting BGP send-community-type +func SkipBgpSendCommunityType(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetSkipBgpSendCommunityType() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index d2f8705fd8d..29d9e4bf132 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -475,6 +475,12 @@ message Metadata { bool bgp_extended_community_index_unsupported = 167; // Support for bgp community set refs bool bgp_community_set_refs_unsupported = 168; + // Device not supporting table-connection need to set this true + bool table_connections_unsupported = 169; + // Configure tag-set using vendor native model + bool use_vendor_native_tag_set_config = 170; + // Skip setting send-community-type in bgp global config + bool skip_bgp_send_community_type = 171; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 55e37dad419..8d620d3de08 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: metadata.proto package metadata_go_proto @@ -756,6 +756,12 @@ type Metadata_Deviations struct { BgpExtendedCommunityIndexUnsupported bool `protobuf:"varint,167,opt,name=bgp_extended_community_index_unsupported,json=bgpExtendedCommunityIndexUnsupported,proto3" json:"bgp_extended_community_index_unsupported,omitempty"` // Support for bgp community set refs BgpCommunitySetRefsUnsupported bool `protobuf:"varint,168,opt,name=bgp_community_set_refs_unsupported,json=bgpCommunitySetRefsUnsupported,proto3" json:"bgp_community_set_refs_unsupported,omitempty"` + // Device not supporting table-connection need to set this true + TableConnectionsUnsupported bool `protobuf:"varint,169,opt,name=table_connections_unsupported,json=tableConnectionsUnsupported,proto3" json:"table_connections_unsupported,omitempty"` + // Configure tag-set using vendor native model + UseVendorNativeTagSetConfig bool `protobuf:"varint,170,opt,name=use_vendor_native_tag_set_config,json=useVendorNativeTagSetConfig,proto3" json:"use_vendor_native_tag_set_config,omitempty"` + // Skip setting send-community-type in bgp global config + SkipBgpSendCommunityType bool `protobuf:"varint,171,opt,name=skip_bgp_send_community_type,json=skipBgpSendCommunityType,proto3" json:"skip_bgp_send_community_type,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1854,6 +1860,27 @@ func (x *Metadata_Deviations) GetBgpCommunitySetRefsUnsupported() bool { return false } +func (x *Metadata_Deviations) GetTableConnectionsUnsupported() bool { + if x != nil { + return x.TableConnectionsUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetUseVendorNativeTagSetConfig() bool { + if x != nil { + return x.UseVendorNativeTagSetConfig + } + return false +} + +func (x *Metadata_Deviations) GetSkipBgpSendCommunityType() bool { + if x != nil { + return x.SkipBgpSendCommunityType + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1917,7 +1944,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x5f, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xff, 0x60, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1951,7 +1978,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x84, 0x57, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xd2, 0x58, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, @@ -2644,44 +2671,57 @@ var file_metadata_proto_rawDesc = []byte{ 0x65, 0x66, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, - 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, - 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, - 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, - 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, - 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, - 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, - 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, - 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, - 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, - 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, - 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, - 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, - 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, - 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, - 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa9, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x75, + 0x73, 0x65, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0xaa, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x75, 0x73, 0x65, 0x56, 0x65, 0x6e, 0x64, 0x6f, + 0x72, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x62, 0x67, 0x70, 0x5f, + 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0xab, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, + 0x42, 0x67, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, + 0x54, 0x79, 0x70, 0x65, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, + 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, + 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, + 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, + 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, + 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, + 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, + 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, + 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, + 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, + 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, + 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/testregistry.textproto b/testregistry.textproto index c6750412a35..883d2bfcdba 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -487,7 +487,7 @@ test: { test: { id: "RT-1.27" description: "Static route to BGP redistribution" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/static-route_bgp_redistribution/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/static_route_bgp_redistribution/otg_tests/static_route_bgp_redistribution_test/README.md" exec: " " } test: { From 95e7a39529eb6c7bce6cf4827b243b527c7eb2c8 Mon Sep 17 00:00:00 2001 From: AmrNJ <155722765+AmrNJ@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:04:51 +0530 Subject: [PATCH 82/97] Wecmp (#2882) * Update weighted_ecmp_test.go * Update README.md Removed total traffic from the Readme as traffic values are fixed after fine tuning. * Update deviations.go Adding deviation to enable cli knob * Update metadata.proto Add deviation for Arista CLI knob * Update metadata.textproto * Update deviations.go * Generated metadata.pb.go * Fixed typo * Added new line * Added new line * Formatted the file * Formatted the file * Formatted the file --------- Co-authored-by: Pramod Maurya --- .../otg_tests/weighted_ecmp_test/README.md | 2 - .../weighted_ecmp_test/metadata.textproto | 1 + .../weighted_ecmp_test/weighted_ecmp_test.go | 71 +++++++--- internal/deviations/deviations.go | 5 + proto/metadata.proto | 8 +- proto/metadata_go_proto/metadata.pb.go | 126 ++++++++++-------- 6 files changed, 128 insertions(+), 85 deletions(-) diff --git a/feature/isis/otg_tests/weighted_ecmp_test/README.md b/feature/isis/otg_tests/weighted_ecmp_test/README.md index 11c38537efc..e5755106280 100644 --- a/feature/isis/otg_tests/weighted_ecmp_test/README.md +++ b/feature/isis/otg_tests/weighted_ecmp_test/README.md @@ -81,7 +81,6 @@ In the topology above, * Start 1024 flows from IPv6 addresses in 2001:db8:64:65::/64 to 2001:db8:64:64::/64 -* Ensure that the total traffic of all flows combined is ~20Gbps ### Verification @@ -125,7 +124,6 @@ In the topology above, * Restart 1024 flows from IPv6 addresses in 2001:db8:64:65::/64 to 2001:db8:64:64::/64 -* Ensure that the total traffic of all flows combined is ~20Gbps ### Verification diff --git a/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto b/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto index 505f52a5505..178c2e58a26 100644 --- a/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto +++ b/feature/isis/otg_tests/weighted_ecmp_test/metadata.textproto @@ -19,5 +19,6 @@ platform_exceptions: { isis_require_same_l1_metric_with_l2_metric: true route_policy_under_afi_unsupported: true static_protocol_name: "STATIC" + rib_wecmp: true } } diff --git a/feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go b/feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go index 22edb4514ec..ad05d96cad3 100644 --- a/feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go +++ b/feature/isis/otg_tests/weighted_ecmp_test/weighted_ecmp_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "math/rand" + "github.com/open-traffic-generator/snappi/gosnappi" "github.com/openconfig/featureprofiles/internal/attrs" "github.com/openconfig/featureprofiles/internal/cfgplugins" @@ -27,13 +29,14 @@ const ( dutSysID = "1920.0000.2001" asn = 64501 acceptRoutePolicy = "PERMIT-ALL" - trafficPPS = 5000000 + trafficPPS = 50000 // Should be 5000000 + trafficv6PPS = 50000 // Should be 5000000 srcTrafficV4 = "100.0.2.1" srcTrafficV6 = "2001:db8:64:65::1" dstTrafficV4 = "100.0.1.1" dstTrafficV6 = "2001:db8:64:64::1" v4Count = 254 - v6Count = 100000000 + v6Count = 1000 // Should be 10000000 ) type aggPortData struct { @@ -85,8 +88,8 @@ var ( agg3 = &aggPortData{ dutIPv4: "192.0.2.9", ateIPv4: "192.0.2.10", - dutIPv6: "2001:db8::9", - ateIPv6: "2001:db8::10", + dutIPv6: "2001:db8::11", + ateIPv6: "2001:db8::12", ateAggName: "lag3", ateAggMAC: "02:00:01:01:01:07", atePort1MAC: "02:00:01:01:01:08", @@ -98,8 +101,8 @@ var ( agg4 = &aggPortData{ dutIPv4: "192.0.2.13", ateIPv4: "192.0.2.14", - dutIPv6: "2001:db8::13", - ateIPv6: "2001:db8::14", + dutIPv6: "2001:db8::14", + ateIPv6: "2001:db8::15", ateAggName: "lag4", ateAggMAC: "02:00:01:01:01:10", atePort1MAC: "02:00:01:01:01:11", @@ -132,25 +135,28 @@ func TestMain(m *testing.M) { } func TestWeightedECMPForISIS(t *testing.T) { + // ondatra.Debug().Breakpoint(t) dut := ondatra.DUT(t, "dut") ate := ondatra.ATE(t, "ate") aggIDs := configureDUT(t, dut) // Enable weighted ECMP and set LoadBalancing to Auto - b := &gnmi.SetBatch{} - isisPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance).Isis() - gnmi.BatchReplace(b, isisPath.Global().WeightedEcmp().Config(), true) - for _, aggID := range aggIDs { - gnmi.BatchReplace(b, isisPath.Interface(aggID).WeightedEcmp().Config(), &oc.NetworkInstance_Protocol_Isis_Interface_WeightedEcmp{ - LoadBalancingWeight: oc.NetworkInstance_Protocol_Isis_Interface_WeightedEcmp_LoadBalancingWeight_Union(oc.WeightedEcmp_LoadBalancingWeight_auto), - }) + if !deviations.RibWecmp(dut) { + b := &gnmi.SetBatch{} + // isisPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance) + isisPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance).Isis() + gnmi.BatchReplace(b, isisPath.Global().WeightedEcmp().Config(), true) + for _, aggID := range aggIDs { + gnmi.BatchReplace(b, isisPath.Interface(aggID).WeightedEcmp().Config(), &oc.NetworkInstance_Protocol_Isis_Interface_WeightedEcmp{ + LoadBalancingWeight: oc.NetworkInstance_Protocol_Isis_Interface_WeightedEcmp_LoadBalancingWeight_Union(oc.WeightedEcmp_LoadBalancingWeight_auto), + }) + } + b.Set(t, dut) } - b.Set(t, dut) top := configureATE(t, ate) flows := configureFlows(t, top, ate1AdvV4, ate1AdvV6, ate2AdvV4, ate2AdvV6) - ate.OTG().PushConfig(t, top) ate.OTG().StartProtocols(t) for _, agg := range []*aggPortData{agg1, agg2} { @@ -160,10 +166,9 @@ func TestWeightedECMPForISIS(t *testing.T) { } startTraffic(t, ate, top) - t.Run("Equal_Distribution_Of_Traffic", func(t *testing.T) { for _, flow := range flows { - loss := otgutils.GetFlowLossPct(t, ate.OTG(), flow.Name(), 5*time.Second) + loss := otgutils.GetFlowLossPct(t, ate.OTG(), flow.Name(), 20*time.Second) if got, want := loss, 0.0; got != want { t.Errorf("Flow %s loss: got %f, want %f", flow.Name(), got, want) } @@ -180,12 +185,13 @@ func TestWeightedECMPForISIS(t *testing.T) { if deviations.ATEPortLinkStateOperationsUnsupported(ate) { p3 := dut.Port(t, "port3") gnmi.Replace(t, dut, gnmi.OC().Interface(p3.Name()).Enabled().Config(), false) + t.Logf("Disable ATE2:Port1: %s, %s", p3.Name(), gnmi.OC().Interface(p3.Name()).OperStatus().State()) } else { p3 := ate.Port(t, "port3") // ATE:port3 is ATE2:port1 psa := gosnappi.NewControlState() psa.Port().Link().SetPortNames([]string{p3.ID()}).SetState(gosnappi.StatePortLinkState.DOWN) ate.OTG().SetControlState(t, psa) - + time.Sleep(10 * time.Second) defer func() { psa := gosnappi.NewControlState() psa.Port().Link().SetPortNames([]string{p3.ID()}).SetState(gosnappi.StatePortLinkState.UP) @@ -193,13 +199,14 @@ func TestWeightedECMPForISIS(t *testing.T) { }() } p3 := dut.Port(t, "port3") - gnmi.Await(t, dut, gnmi.OC().Interface(p3.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_LOWER_LAYER_DOWN) + gnmi.Await(t, dut, gnmi.OC().Interface(p3.Name()).OperStatus().State(), time.Minute*2, oc.Interface_OperStatus_DOWN) + top.Flows().Clear() startTraffic(t, ate, top) t.Run("Unequal_Distribution_Of_Traffic", func(t *testing.T) { for _, flow := range flows { - loss := otgutils.GetFlowLossPct(t, ate.OTG(), flow.Name(), 5*time.Second) + loss := otgutils.GetFlowLossPct(t, ate.OTG(), flow.Name(), 20*time.Second) if got, want := loss, 0.0; got != want { t.Errorf("Flow %s loss: got %f, want %f", flow.Name(), got, want) } @@ -239,8 +246,23 @@ func startTraffic(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) { otgutils.LogLAGMetrics(t, ate.OTG(), top) } +func randRange(t *testing.T, start, end uint32, count int) []uint32 { + if count > int(end-start) { + t.Fatal("randRange: count greater than end-start.") + } + rand.New(rand.NewSource(time.Now().UnixNano())) + var result []uint32 + for len(result) < count { + diff := end - start + randomValue := rand.Int31n(int32(diff)) + int32(start) + result = append(result, uint32(randomValue)) + } + return result +} + func configureFlows(t *testing.T, top gosnappi.Config, srcV4, srcV6, dstV4, dstV6 *ipAddr) []gosnappi.Flow { t.Helper() + top.Flows().Clear() fV4 := top.Flows().Add().SetName("flowV4") fV4.Metrics().SetEnable(true) fV4.TxRx().Device(). @@ -253,6 +275,9 @@ func configureFlows(t *testing.T, top gosnappi.Config, srcV4, srcV6, dstV4, dstV v4 := fV4.Packet().Add().Ipv4() v4.Src().Increment().SetStart(srcTrafficV4).SetCount(v4Count) v4.Dst().Increment().SetStart(dstTrafficV4).SetCount(v4Count) + udp := fV4.Packet().Add().Udp() + udp.SrcPort().SetValues(randRange(t, 34525, 65535, 500)) + udp.DstPort().SetValues(randRange(t, 49152, 65535, 500)) fV6 := top.Flows().Add().SetName("flowV6") fV6.Metrics().SetEnable(true) @@ -260,14 +285,16 @@ func configureFlows(t *testing.T, top gosnappi.Config, srcV4, srcV6, dstV4, dstV SetTxNames([]string{agg1.ateAggName + ".IPv6"}). SetRxNames([]string{agg2.ateAggName + ".IPv6", agg3.ateAggName + ".IPv6", agg4.ateAggName + ".IPv6"}) fV6.Size().SetFixed(1500) - fV6.Rate().SetPps(trafficPPS) + fV6.Rate().SetPps(trafficv6PPS) eV6 := fV6.Packet().Add().Ethernet() eV6.Src().SetValue(agg1.ateAggMAC) v6 := fV6.Packet().Add().Ipv6() v6.Src().Increment().SetStart(srcTrafficV6).SetCount(v6Count) v6.Dst().Increment().SetStart(dstTrafficV6).SetCount(v6Count) - + udpv6 := fV6.Packet().Add().Udp() + udpv6.SrcPort().SetValues(randRange(t, 35521, 65535, 500)) + udpv6.DstPort().SetValues(randRange(t, 49152, 65535, 500)) return []gosnappi.Flow{fV4, fV6} } diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 8b23ea6aae3..6843fa9700d 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -377,6 +377,11 @@ func ExplicitInterfaceInDefaultVRF(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetExplicitInterfaceInDefaultVrf() } +// RibWecmp returns if device requires CLI knob to enable wecmp feature. +func RibWecmp(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetRibWecmp() +} + // InterfaceConfigVRFBeforeAddress returns if vrf should be configured before IP address when configuring interface. func InterfaceConfigVRFBeforeAddress(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetInterfaceConfigVrfBeforeAddress() diff --git a/proto/metadata.proto b/proto/metadata.proto index 29d9e4bf132..5e0521494eb 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -475,12 +475,14 @@ message Metadata { bool bgp_extended_community_index_unsupported = 167; // Support for bgp community set refs bool bgp_community_set_refs_unsupported = 168; + // Arista device needs CLI knob to enable WECMP feature + bool rib_wecmp = 169; // Device not supporting table-connection need to set this true - bool table_connections_unsupported = 169; + bool table_connections_unsupported = 170; // Configure tag-set using vendor native model - bool use_vendor_native_tag_set_config = 170; + bool use_vendor_native_tag_set_config = 171; // Skip setting send-community-type in bgp global config - bool skip_bgp_send_community_type = 171; + bool skip_bgp_send_community_type = 172; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 8d620d3de08..fb3e67d2744 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v4.23.2 +// protoc-gen-go v1.33.0 +// protoc v3.21.12 // source: metadata.proto package metadata_go_proto @@ -756,12 +756,14 @@ type Metadata_Deviations struct { BgpExtendedCommunityIndexUnsupported bool `protobuf:"varint,167,opt,name=bgp_extended_community_index_unsupported,json=bgpExtendedCommunityIndexUnsupported,proto3" json:"bgp_extended_community_index_unsupported,omitempty"` // Support for bgp community set refs BgpCommunitySetRefsUnsupported bool `protobuf:"varint,168,opt,name=bgp_community_set_refs_unsupported,json=bgpCommunitySetRefsUnsupported,proto3" json:"bgp_community_set_refs_unsupported,omitempty"` + // Arista device needs CLI knob to enable WECMP feature + RibWecmp bool `protobuf:"varint,169,opt,name=rib_wecmp,json=ribWecmp,proto3" json:"rib_wecmp,omitempty"` // Device not supporting table-connection need to set this true - TableConnectionsUnsupported bool `protobuf:"varint,169,opt,name=table_connections_unsupported,json=tableConnectionsUnsupported,proto3" json:"table_connections_unsupported,omitempty"` + TableConnectionsUnsupported bool `protobuf:"varint,170,opt,name=table_connections_unsupported,json=tableConnectionsUnsupported,proto3" json:"table_connections_unsupported,omitempty"` // Configure tag-set using vendor native model - UseVendorNativeTagSetConfig bool `protobuf:"varint,170,opt,name=use_vendor_native_tag_set_config,json=useVendorNativeTagSetConfig,proto3" json:"use_vendor_native_tag_set_config,omitempty"` + UseVendorNativeTagSetConfig bool `protobuf:"varint,171,opt,name=use_vendor_native_tag_set_config,json=useVendorNativeTagSetConfig,proto3" json:"use_vendor_native_tag_set_config,omitempty"` // Skip setting send-community-type in bgp global config - SkipBgpSendCommunityType bool `protobuf:"varint,171,opt,name=skip_bgp_send_community_type,json=skipBgpSendCommunityType,proto3" json:"skip_bgp_send_community_type,omitempty"` + SkipBgpSendCommunityType bool `protobuf:"varint,172,opt,name=skip_bgp_send_community_type,json=skipBgpSendCommunityType,proto3" json:"skip_bgp_send_community_type,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1860,6 +1862,13 @@ func (x *Metadata_Deviations) GetBgpCommunitySetRefsUnsupported() bool { return false } +func (x *Metadata_Deviations) GetRibWecmp() bool { + if x != nil { + return x.RibWecmp + } + return false +} + func (x *Metadata_Deviations) GetTableConnectionsUnsupported() bool { if x != nil { return x.TableConnectionsUnsupported @@ -1944,7 +1953,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xff, 0x60, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x61, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1978,7 +1987,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xd2, 0x58, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xf0, 0x58, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, @@ -2671,57 +2680,58 @@ var file_metadata_proto_rawDesc = []byte{ 0x65, 0x66, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa9, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x75, - 0x73, 0x65, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0xaa, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x75, 0x73, 0x65, 0x56, 0x65, 0x6e, 0x64, 0x6f, - 0x72, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x62, 0x67, 0x70, 0x5f, - 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0xab, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, - 0x42, 0x67, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, - 0x54, 0x79, 0x70, 0x65, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, - 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, - 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, - 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, - 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, - 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, - 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, - 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, - 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, - 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, - 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, - 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, - 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, - 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, - 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, - 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, - 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x69, 0x62, 0x5f, 0x77, 0x65, + 0x63, 0x6d, 0x70, 0x18, 0xa9, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x69, 0x62, 0x57, + 0x65, 0x63, 0x6d, 0x70, 0x12, 0x43, 0x0a, 0x1d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xaa, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x75, 0x73, 0x65, + 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, + 0x61, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0xab, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x75, 0x73, 0x65, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4e, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, + 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0xac, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x67, + 0x70, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x54, 0x79, + 0x70, 0x65, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, + 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, + 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, + 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, + 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, + 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, + 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, + 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, + 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, + 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, + 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, + 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, + 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, + 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, + 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, + 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From c512619b60eb3cbafae0d52888ae46835f49a43c Mon Sep 17 00:00:00 2001 From: Calvin F <131898783+cfernanz@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:17:57 -0700 Subject: [PATCH 83/97] Update README.md (#2908) --- .../otg_tests/ipv6_slaac_link_local_test/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/interface/ip/ipv6_slaac_link_local/otg_tests/ipv6_slaac_link_local_test/README.md b/feature/interface/ip/ipv6_slaac_link_local/otg_tests/ipv6_slaac_link_local_test/README.md index 04576be20c1..2009b5991b2 100644 --- a/feature/interface/ip/ipv6_slaac_link_local/otg_tests/ipv6_slaac_link_local_test/README.md +++ b/feature/interface/ip/ipv6_slaac_link_local/otg_tests/ipv6_slaac_link_local_test/README.md @@ -25,5 +25,5 @@ Enable IPv6 on interface level so ipv6 address of link-local scope is generated/ ## Protocol/RPC Parameter Coverage None -## Required DUT platform +## Minimum required DUT platform * FFF - fixed form factor From f0ba8c92306c0202b2679c7f8fd7384095bf8b7d Mon Sep 17 00:00:00 2001 From: NishaSadhasivam-work Date: Mon, 22 Apr 2024 22:00:36 +0530 Subject: [PATCH 84/97] Update import_export_multi.go (#2910) * Update import_export_multi.go updated static check errors * Update import_export_multi.go fixing static check failures --- .../import_export_multi/import_export_multi.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go index 447f10f9f6c..e4ade0a930b 100644 --- a/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go +++ b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package import_export_test covers RT-7.11: BGP Policy - Import/Export Policy Action Using Multiple Criteria package import_export_test import ( @@ -100,11 +101,12 @@ var communityMembers = [][][]int{ }, } +// TestMain triggers the test run func TestMain(m *testing.M) { fptest.RunTests(m) } -func configureImportExportAcceptAllBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, ipv6 string, matchSetOptions oc.E_BgpPolicy_MatchSetOptionsType) { +func configureImportExportAcceptAllBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, ipv6 string) { root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() pdef1 := rp.GetOrCreatePolicyDefinition("routePolicy") @@ -365,6 +367,7 @@ func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ond } func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string, prefixesV6 [][]string, communityMembers [][][]int) { + t.Logf("configure OTG") devices := bs.ATETop.Devices().Items() ipv4 := devices[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0] @@ -409,6 +412,7 @@ func configureOTG(t *testing.T, bs *cfgplugins.BGPSession, prefixesV4 [][]string } func configureFlowV4(t *testing.T, bs *cfgplugins.BGPSession) { + t.Logf("configure V4 Flow on traffic generator") for index, prefixPairV4 := range prefixesV4 { flow := bs.ATETop.Flows().Add().SetName("flow" + "ipv4" + strconv.Itoa(index)) flow.Metrics().SetEnable(true) @@ -431,6 +435,7 @@ func configureFlowV4(t *testing.T, bs *cfgplugins.BGPSession) { } func configureFlowV6(t *testing.T, bs *cfgplugins.BGPSession) { + t.Logf("configure V6 Flow on traffic generator") for index, prefixPairV6 := range prefixesV6 { flow := bs.ATETop.Flows().Add().SetName("flow" + "ipv6" + strconv.Itoa(index)) flow.Metrics().SetEnable(true) @@ -495,6 +500,7 @@ func verifyTrafficV4AndV6(t *testing.T, bs *cfgplugins.BGPSession, testResults [ } } +// TestImportExportMultifacetMatchActionsBGPPolicy covers RT-7.11 func TestImportExportMultifacetMatchActionsBGPPolicy(t *testing.T) { bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{ @@ -512,7 +518,7 @@ func TestImportExportMultifacetMatchActionsBGPPolicy(t *testing.T) { ipv6 := bs.ATETop.Devices().Items()[1].Ethernets().Items()[0].Ipv6Addresses().Items()[0].Address() t.Logf("Verify Import Export Accept all bgp policy") - configureImportExportAcceptAllBGPPolicy(t, bs.DUT, ipv4, ipv6, matchAny) + configureImportExportAcceptAllBGPPolicy(t, bs.DUT, ipv4, ipv6) configureFlowV4(t, bs) configureFlowV6(t, bs) From 5e2961a6d67d12b24f37144b064650028fe55713 Mon Sep 17 00:00:00 2001 From: dipchauh <159579776+dipchauh@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:50:26 -0400 Subject: [PATCH 85/97] RT-7.8: BGP Community Match Action (#2850) * RT-7.8: BGP Community Match Action Initial Commit 1. Added test script bgp_comm_match_action_test.go 2. Added new deviation bgp_actions_set_community_method_unsupported "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." * goimports & OTG fix "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." * Fix deviation comment "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --- .../bgp_comm_match_action_test.go | 770 ++++++++++++++++++ .../comm_match_action_test/metadata.textproto | 23 +- internal/deviations/deviations.go | 5 + proto/metadata.proto | 3 + proto/metadata_go_proto/metadata.pb.go | 25 +- 5 files changed, 817 insertions(+), 9 deletions(-) create mode 100644 feature/bgp/policybase/otg_tests/comm_match_action_test/bgp_comm_match_action_test.go diff --git a/feature/bgp/policybase/otg_tests/comm_match_action_test/bgp_comm_match_action_test.go b/feature/bgp/policybase/otg_tests/comm_match_action_test/bgp_comm_match_action_test.go new file mode 100644 index 00000000000..c7b1ba2c0ed --- /dev/null +++ b/feature/bgp/policybase/otg_tests/comm_match_action_test/bgp_comm_match_action_test.go @@ -0,0 +1,770 @@ +// Copyright 2023 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 bgp_comm_match_action_test + +import ( + "fmt" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "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" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + otg "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +const ( + trafficDuration = 1 * time.Minute + tolerancePct = 2 + peerGrpName = "BGP-PEER-GROUP" + dutAS = 65501 + ateAS = 65502 + plenIPv4 = 30 + plenIPv6 = 126 + acceptPolicy = "PERMIT-ALL" +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "DUT to ATE Port1", + IPv4: "192.0.2.1", + IPv6: "2001:db8::192:0:2:1", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + atePort1 = attrs.Attributes{ + Name: "atePort1", + IPv4: "192.0.2.2", + IPv6: "2001:db8::192:0:2:2", + MAC: "02:00:01:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + dutPort2 = attrs.Attributes{ + Desc: "DUT to ATE Port2", + IPv4: "192.0.2.5", + IPv6: "2001:db8::192:0:2:5", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + atePort2 = attrs.Attributes{ + Name: "atePort2", + IPv4: "192.0.2.6", + IPv6: "2001:db8::192:0:2:6", + MAC: "02:00:02:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + + ebgp1NbrV4 = &bgpNeighbor{ + nbrAddr: atePort1.IPv4, + isV4: true, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, + as: ateAS} + ebgp1NbrV6 = &bgpNeighbor{ + nbrAddr: atePort1.IPv6, + isV4: false, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST, + as: ateAS} + ebgp2NbrV4 = &bgpNeighbor{ + nbrAddr: atePort2.IPv4, + isV4: true, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, + as: ateAS} + ebgp2NbrV6 = &bgpNeighbor{ + nbrAddr: atePort2.IPv6, + isV4: false, + afiSafi: oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST, + as: ateAS} + ebgpNbrs = []*bgpNeighbor{ebgp1NbrV4, ebgp2NbrV4, ebgp1NbrV6, ebgp2NbrV6} + + routes = map[string]*route{ + "prefix-set-1": { + prefixesV4: []string{"198.51.100.0", "198.51.100.4"}, + prefixesV6: []string{"2048:db1:64:64::", "2048:db1:64:64::4"}, + communityMembers: nil, + }, + "prefix-set-2": { + prefixesV4: []string{"198.51.100.8", "198.51.100.12"}, + prefixesV6: []string{"2048:db1:64:64::8", "2048:db1:64:64::c"}, + communityMembers: [][]int{{5, 5}, {6, 6}}, + }, + } + + communitySets = []communitySet{ + { + name: "match_std_comms", + members: []string{"5:5"}, + }, + { + name: "add_std_comms", + members: []string{"10:10", "20:20", "30:30"}, + }, + } +) + +type route struct { + prefixesV4 []string + prefixesV6 []string + communityMembers [][]int +} + +type communitySet struct { + name string + members []string +} + +type bgpNeighbor struct { + as uint32 + nbrAddr string + isV4 bool + afiSafi oc.E_BgpTypes_AFI_SAFI_TYPE +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + dc := gnmi.OC() + i1 := dutPort1.NewOCInterface(dut.Port(t, "port1").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) + + i2 := dutPort2.NewOCInterface(dut.Port(t, "port2").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i2.GetName()).Config(), i2) + fptest.ConfigureDefaultNetworkInstance(t, dut) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dut.Port(t, "port1")) + fptest.SetPortSpeed(t, dut.Port(t, "port2")) + } + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, dut.Port(t, "port1").Name(), deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, dut.Port(t, "port2").Name(), deviations.DefaultNetworkInstance(dut), 0) + } + + // Configure PERMIT_ALL Policy + d := &oc.Root{} + rp := d.GetOrCreateRoutingPolicy() + pdef := rp.GetOrCreatePolicyDefinition(acceptPolicy) + stmt, _ := pdef.AppendNewStatement("10") + stmt.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + + // Configure Community Sets on DUT + for _, communitySet := range communitySets { + configureCommunitySet(t, dut, communitySet) + } +} + +func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { + + // Configure BGP on DUT + dutOcRoot := &oc.Root{} + ni1 := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() + + global := bgp.GetOrCreateGlobal() + global.RouterId = ygot.String(dutPort1.IPv4) + global.As = ygot.Uint32(localAs) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + + pg := bgp.GetOrCreatePeerGroup(peerGrpName) + pg.PeerAs = ygot.Uint32(ateAS) + pg.PeerGroupName = ygot.String(peerGrpName) + as4 := pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + as4.Enabled = ygot.Bool(true) + as6 := pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + as6.Enabled = ygot.Bool(true) + + for _, nbr := range ebgpNbrs { + bgpNbr := bgp.GetOrCreateNeighbor(nbr.nbrAddr) + bgpNbr.PeerGroup = ygot.String(peerGrpName) + bgpNbr.PeerAs = ygot.Uint32(nbr.as) + bgpNbr.Enabled = ygot.Bool(true) + + if nbr.isV4 == true { + af4 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(true) + if nbr.nbrAddr == atePort2.IPv4 { + af4.GetOrCreateApplyPolicy().ExportPolicy = []string{acceptPolicy} + } + af6 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(false) + } else { + af4 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(false) + af6 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(true) + if nbr.nbrAddr == atePort2.IPv6 { + af6.GetOrCreateApplyPolicy().ExportPolicy = []string{acceptPolicy} + } + } + } + return niProto +} + +func verifyBgpState(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + + t.Logf("Waiting for BGP neighbor to establish...") + for _, nbr := range ebgpNbrs { + nbrPath := bgpPath.Neighbor(nbr.nbrAddr) + var status *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState] + status, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + return ok && state == oc.Bgp_Neighbor_SessionState_ESTABLISHED + }).Await(t) + if !ok { + fptest.LogQuery(t, "BGP reported state", nbrPath.State(), gnmi.Get(t, dut, nbrPath.State())) + t.Fatal("No BGP neighbor formed") + } + state, _ := status.Val() + t.Logf("BGP adjacency for %s: %v", nbr.nbrAddr, state) + if want := oc.Bgp_Neighbor_SessionState_ESTABLISHED; state != want { + t.Errorf("BGP peer %s status got %d, want %d", nbr.nbrAddr, state, want) + } + } +} + +func configureCommunitySet(t *testing.T, dut *ondatra.DUTDevice, communitySet communitySet) { + root := &oc.Root{} + rp := root.GetOrCreateRoutingPolicy() + commSet := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(communitySet.name) + var commMemberUnion []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union + for _, commMember := range communitySet.members { + commMemberUnion = append(commMemberUnion, oc.UnionString(commMember)) + } + commSet.SetCommunityMember(commMemberUnion) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) +} + +func configureRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice, policyName string, nbr *bgpNeighbor, pgName string) { + d := &oc.Root{} + rp := d.GetOrCreateRoutingPolicy() + batchConfig := &gnmi.SetBatch{} + + var pdef *oc.RoutingPolicy_PolicyDefinition + + switch policyName { + case "add_std_comms": + pdef = rp.GetOrCreatePolicyDefinition(policyName) + stmt1, _ := pdef.AppendNewStatement("add_std_comms") + sc := stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetCommunity() + sc.GetOrCreateReference().SetCommunitySetRef("add_std_comms") + sc.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + if !deviations.BgpActionsSetCommunityMethodUnsupported(dut) { + sc.SetMethod(oc.SetCommunity_Method_REFERENCE) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + stmt2, _ := pdef.AppendNewStatement("accept_all_routes") + stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + case "match_and_add_comms": + pdef = rp.GetOrCreatePolicyDefinition(policyName) + stmt1, _ := pdef.AppendNewStatement("match_and_add_std_comms") + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet("match_std_comms") + ds := rp.GetOrCreateDefinedSets() + cs := ds.GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet("match_std_comms") + cs.SetMatchSetOptions(oc.BgpPolicy_MatchSetOptionsType_ANY) + gnmi.BatchUpdate(batchConfig, gnmi.OC().RoutingPolicy().DefinedSets().Config(), ds) + } else { + cs := stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet() + cs.SetCommunitySet("match_std_comms") + cs.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_ANY) + } + sc := stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetCommunity() + sc.GetOrCreateReference().SetCommunitySetRef("add_std_comms") + sc.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + if !deviations.BgpActionsSetCommunityMethodUnsupported(dut) { + sc.SetMethod(oc.SetCommunity_Method_REFERENCE) + } + stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + stmt2, _ := pdef.AppendNewStatement("accept_all_routes") + stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + } + + if pdef != nil { + gnmi.BatchReplace(batchConfig, gnmi.OC().RoutingPolicy().PolicyDefinition(policyName).Config(), pdef) + } + + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + if nbr != nil { + gnmi.BatchReplace(batchConfig, bgpPath.Neighbor(nbr.nbrAddr).AfiSafi(nbr.afiSafi).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) + } + if pgName != "" { + gnmi.BatchReplace(batchConfig, bgpPath.PeerGroup(pgName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) + gnmi.BatchReplace(batchConfig, bgpPath.PeerGroup(pgName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) + gnmi.BatchDelete(batchConfig, bgpPath.Neighbor(ebgp1NbrV4.nbrAddr).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ImportPolicy().Config()) + gnmi.BatchDelete(batchConfig, bgpPath.Neighbor(ebgp1NbrV6.nbrAddr).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy().ImportPolicy().Config()) + } + + batchConfig.Set(t, dut) +} + +func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { + t.Helper() + config := gosnappi.NewConfig() + port1 := config.Ports().Add().SetName("port1") + port2 := config.Ports().Add().SetName("port2") + + // Port1 Configuration. + iDut1Dev := config.Devices().Add().SetName(atePort1.Name) + iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1.Name + ".Eth").SetMac(atePort1.MAC) + iDut1Eth.Connection().SetPortName(port1.Name()) + iDut1Ipv4 := iDut1Eth.Ipv4Addresses().Add().SetName(atePort1.Name + ".IPv4") + iDut1Ipv4.SetAddress(atePort1.IPv4).SetGateway(dutPort1.IPv4).SetPrefix(uint32(atePort1.IPv4Len)) + iDut1Ipv6 := iDut1Eth.Ipv6Addresses().Add().SetName(atePort1.Name + ".IPv6") + iDut1Ipv6.SetAddress(atePort1.IPv6).SetGateway(dutPort1.IPv6).SetPrefix(uint32(atePort1.IPv6Len)) + + // Port2 Configuration. + iDut2Dev := config.Devices().Add().SetName(atePort2.Name) + iDut2Eth := iDut2Dev.Ethernets().Add().SetName(atePort2.Name + ".Eth").SetMac(atePort2.MAC) + iDut2Eth.Connection().SetPortName(port2.Name()) + iDut2Ipv4 := iDut2Eth.Ipv4Addresses().Add().SetName(atePort2.Name + ".IPv4") + iDut2Ipv4.SetAddress(atePort2.IPv4).SetGateway(dutPort2.IPv4).SetPrefix(uint32(atePort2.IPv4Len)) + iDut2Ipv6 := iDut2Eth.Ipv6Addresses().Add().SetName(atePort2.Name + ".IPv6") + iDut2Ipv6.SetAddress(atePort2.IPv6).SetGateway(dutPort2.IPv6).SetPrefix(uint32(atePort2.IPv6Len)) + + // eBGP v4 session on Port1. + iDut1Bgp := iDut1Dev.Bgp().SetRouterId(iDut1Ipv4.Address()) + iDut1Bgp4Peer := iDut1Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut1Ipv4.Name()).Peers().Add().SetName(atePort1.Name + ".BGP4.peer") + iDut1Bgp4Peer.SetPeerAddress(iDut1Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) + // eBGP v6 session on Port1. + iDut1Bgp6Peer := iDut1Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut1Ipv6.Name()).Peers().Add().SetName(atePort1.Name + ".BGP6.peer") + iDut1Bgp6Peer.SetPeerAddress(iDut1Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + iDut1Bgp6Peer.LearnedInformationFilter().SetUnicastIpv6Prefix(true) + + // eBGP v4 session on Port2. + iDut2Bgp := iDut2Dev.Bgp().SetRouterId(iDut2Ipv4.Address()) + iDut2Bgp4Peer := iDut2Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut2Ipv4.Name()).Peers().Add().SetName(atePort2.Name + ".BGP4.peer") + iDut2Bgp4Peer.SetPeerAddress(iDut2Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut2Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true) + // eBGP v6 session on Port2. + iDut2Bgp6Peer := iDut2Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut2Ipv6.Name()).Peers().Add().SetName(atePort2.Name + ".BGP6.peer") + iDut2Bgp6Peer.SetPeerAddress(iDut2Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + iDut2Bgp6Peer.LearnedInformationFilter().SetUnicastIpv6Prefix(true) + + for key, sendRoute := range routes { + // eBGP V4 routes from Port1. + bgpNeti1Bgp4PeerRoutes := iDut1Bgp4Peer.V4Routes().Add().SetName(atePort1.Name + ".BGP4.Route." + key) + bgpNeti1Bgp4PeerRoutes.SetNextHopIpv4Address(iDut1Ipv4.Address()). + SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). + SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) + + for _, prefixV4 := range sendRoute.prefixesV4 { + bgpNeti1Bgp4PeerRoutes.Addresses().Add().SetAddress(prefixV4).SetPrefix(plenIPv4) + } + + // eBGP V6 routes from Port1. + bgpNeti1Bgp6PeerRoutes := iDut1Bgp6Peer.V6Routes().Add().SetName(atePort1.Name + ".BGP6.Route." + key) + bgpNeti1Bgp6PeerRoutes.SetNextHopIpv6Address(iDut1Ipv6.Address()). + SetNextHopAddressType(gosnappi.BgpV6RouteRangeNextHopAddressType.IPV6). + SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) + + for _, prefixV6 := range sendRoute.prefixesV6 { + bgpNeti1Bgp6PeerRoutes.Addresses().Add().SetAddress(prefixV6).SetPrefix(plenIPv6) + } + + if sendRoute.communityMembers != nil { + for _, community := range sendRoute.communityMembers { + commV4 := bgpNeti1Bgp4PeerRoutes.Communities().Add() + commV4.SetType(gosnappi.BgpCommunityType.MANUAL_AS_NUMBER) + commV4.SetAsNumber(uint32(community[0])) + commV4.SetAsCustom(uint32(community[1])) + + commV6 := bgpNeti1Bgp6PeerRoutes.Communities().Add() + commV6.SetType(gosnappi.BgpCommunityType.MANUAL_AS_NUMBER) + commV6.SetAsNumber(uint32(community[0])) + commV6.SetAsCustom(uint32(community[1])) + } + } + } + + // ATE Traffic Configuration. + t.Logf("TestBGP:start ate Traffic config") + + var dstBgp4PeerRoutes, dst4Prefixes []string + for _, routeV4 := range iDut1Bgp4Peer.V4Routes().Items() { + dstBgp4PeerRoutes = append(dstBgp4PeerRoutes, routeV4.Name()) + for _, prefix := range routeV4.Addresses().Items() { + dst4Prefixes = append(dst4Prefixes, prefix.Address()) + } + } + flowipv4 := config.Flows().Add().SetName("bgpv4RoutesFlow") + flowipv4.Metrics().SetEnable(true) + flowipv4.TxRx().Device(). + SetTxNames([]string{iDut2Ipv4.Name()}). + SetRxNames(dstBgp4PeerRoutes) + flowipv4.Size().SetFixed(512) + flowipv4.Duration().FixedPackets().SetPackets(1000) + e1 := flowipv4.Packet().Add().Ethernet() + e1.Src().SetValue(iDut2Eth.Mac()) + v4 := flowipv4.Packet().Add().Ipv4() + v4.Src().SetValue(iDut2Ipv4.Address()) + v4.Dst().SetValues(dst4Prefixes) + + var dstBgp6PeerRoutes, dst6Prefixes []string + for _, routeV6 := range iDut1Bgp6Peer.V6Routes().Items() { + dstBgp6PeerRoutes = append(dstBgp6PeerRoutes, routeV6.Name()) + for _, prefix := range routeV6.Addresses().Items() { + dst6Prefixes = append(dst6Prefixes, prefix.Address()) + } + } + flowipv6 := config.Flows().Add().SetName("bgpv6RoutesFlow") + flowipv6.Metrics().SetEnable(true) + flowipv6.TxRx().Device(). + SetTxNames([]string{iDut2Ipv6.Name()}). + SetRxNames(dstBgp6PeerRoutes) + flowipv6.Size().SetFixed(512) + flowipv6.Duration().FixedPackets().SetPackets(1000) + e2 := flowipv6.Packet().Add().Ethernet() + e2.Src().SetValue(iDut2Eth.Mac()) + v6 := flowipv6.Packet().Add().Ipv6() + v6.Src().SetValue(iDut2Ipv6.Address()) + v6.Dst().SetValues(dst6Prefixes) + + otg.PushConfig(t, config) + otg.StartProtocols(t) + return config +} + +func sendTraffic(t *testing.T, otg *otg.OTG) { + t.Logf("Starting traffic") + otg.StartTraffic(t) + time.Sleep(trafficDuration) + t.Logf("Stop traffic") + otg.StopTraffic(t) +} + +func verifyTraffic(t *testing.T, ate *ondatra.ATEDevice, conf gosnappi.Config) { + otg := ate.OTG() + otgutils.LogFlowMetrics(t, otg, conf) + for _, flow := range conf.Flows().Items() { + recvMetric := gnmi.Get(t, otg, gnmi.OTG().Flow(flow.Name()).State()) + txPackets := float32(recvMetric.GetCounters().GetOutPkts()) + rxPackets := float32(recvMetric.GetCounters().GetInPkts()) + if txPackets == 0 { + t.Fatalf("TxPkts = 0, want > 0") + } + lostPackets := txPackets - rxPackets + lossPct := lostPackets * 100 / txPackets + if lossPct > tolerancePct { + t.Errorf("Traffic Loss Pct for Flow %s: got %v, want max %v pct failure", flow.Name(), lossPct, tolerancePct) + } else { + t.Logf("Traffic Test Passed! for flow %s", flow.Name()) + } + } +} + +func validateATEIPv4PrefixCommunitySet(t *testing.T, ate *ondatra.ATEDevice, bgpPeerName, subnet string, wantCommunitySet []string) { + otg := ate.OTG() + var gotCommunitySet []string + peerPath := gnmi.OTG().BgpPeer(bgpPeerName) + + _, ok := gnmi.Watch(t, + otg, + peerPath.UnicastIpv4Prefix(subnet, plenIPv4, otgtelemetry.UnicastIpv4Prefix_Origin_IGP, 0).State(), + time.Minute, + func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { + prefix, ok := v.Val() + if ok { + gotCommunitySet = nil + for _, community := range prefix.Community { + gotCommunityNumber := community.GetCustomAsNumber() + gotCommunityValue := community.GetCustomAsValue() + gotCommunitySet = append(gotCommunitySet, fmt.Sprint(gotCommunityNumber)+":"+fmt.Sprint(gotCommunityValue)) + } + if cmp.Equal(gotCommunitySet, wantCommunitySet, cmpopts.SortSlices(func(a, b string) bool { return a < b })) { + t.Logf("ATE: Prefix %v learned with community %v", prefix.GetAddress(), gotCommunitySet) + return true + } + prefix.Community = nil + } + return false + }).Await(t) + + if !ok { + fptest.LogQuery(t, "ATE BGP Peer reported state", peerPath.State(), gnmi.Get(t, otg, peerPath.State())) + t.Errorf("ATE: Prefix %v got communities %v, want communities %v", subnet, gotCommunitySet, wantCommunitySet) + } +} + +func validateDutIPv4PrefixCommunitySet(t *testing.T, dut *ondatra.DUTDevice, bgpNbr *bgpNeighbor, subnet string, wantCommunitySet []string) { + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + statePath := bgpPath.Rib().AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast() + state := gnmi.Get(t, dut, statePath.State()) + + if communityIndex := state.GetNeighbor(bgpNbr.nbrAddr).GetAdjRibInPost().GetRoute(subnet, 0).GetCommunityIndex(); communityIndex != 0 { + t.Logf("DUT: Prefix %v learned with CommunityIndex: %v", subnet, communityIndex) + } else { + fptest.LogQuery(t, "Node BGP", statePath.State(), state) + t.Logf("DUT: Could not find AdjRibInPost Community for Prefix %v", subnet) + } + //TODO Validate Community for ipv4 prefixes on DUT +} + +func validateATEIPv6PrefixCommunitySet(t *testing.T, ate *ondatra.ATEDevice, bgpPeerName, subnet string, wantCommunitySet []string) { + otg := ate.OTG() + var gotCommunitySet []string + peerPath := gnmi.OTG().BgpPeer(bgpPeerName) + + _, ok := gnmi.Watch(t, + otg, + peerPath.UnicastIpv6Prefix(subnet, plenIPv6, otgtelemetry.UnicastIpv6Prefix_Origin_IGP, 0).State(), + time.Minute, + func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv6Prefix]) bool { + prefix, ok := v.Val() + if ok { + for _, community := range prefix.Community { + gotCommunityNumber := community.GetCustomAsNumber() + gotCommunityValue := community.GetCustomAsValue() + gotCommunitySet = append(gotCommunitySet, fmt.Sprint(gotCommunityNumber)+":"+fmt.Sprint(gotCommunityValue)) + } + if cmp.Equal(gotCommunitySet, wantCommunitySet, cmpopts.SortSlices(func(a, b string) bool { return a < b })) { + t.Logf("ATE: Prefix %v learned with community %v", prefix.GetAddress(), gotCommunitySet) + return true + } + prefix.Community = nil + gotCommunitySet = nil + } + return false + }).Await(t) + + if !ok { + fptest.LogQuery(t, "ATE BGP Peer reported state", peerPath.State(), gnmi.Get(t, otg, peerPath.State())) + t.Errorf("ATE: Prefix %v got communities %v, want communities %v", subnet, gotCommunitySet, wantCommunitySet) + } +} + +func validateDutIPv6PrefixCommunitySet(t *testing.T, dut *ondatra.DUTDevice, bgpNbr *bgpNeighbor, subnet string, wantCommunitySet []string) { + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + statePath := bgpPath.Rib().AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Ipv6Unicast() + state := gnmi.Get(t, dut, statePath.State()) + + if communityIndex := state.GetNeighbor(bgpNbr.nbrAddr).GetAdjRibInPost().GetRoute(subnet, 0).GetCommunityIndex(); communityIndex != 0 { + t.Logf("DUT: Prefix %v learned with CommunityIndex: %v", subnet, communityIndex) + } else { + fptest.LogQuery(t, "Node BGP", statePath.State(), state) + t.Logf("DUT: Could not find AdjRibInPost Community for Prefix %v", subnet) + } + //TODO Validate Community for ipv6 prefixes on DUT +} + +type TestResults struct { + prefixSetName string + wantCommunitySet []string +} + +type testCase struct { + desc string + nbr *bgpNeighbor + peerGrp string + policyName string + testResults []TestResults +} + +// TestBGPCommMatchAction is to test community match actions at BGP neighbor & peer group levels. +func TestBGPCommMatchAction(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + otg := ate.OTG() + + configureDUT(t, dut) + + dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + gnmi.Delete(t, dut, dutConfPath.Config()) + dutConf := bgpCreateNbr(dutAS, ateAS, dut) + gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) + + otgConfig := configureOTG(t, otg) + verifyBgpState(t, dut) + + t.Run("RT-7.8.1", func(t *testing.T) { + testCases := []testCase{ + { + desc: "Validate Initial Config", + peerGrp: "", + policyName: acceptPolicy, + testResults: []TestResults{ + { + prefixSetName: "prefix-set-1", + wantCommunitySet: nil, + }, + { + prefixSetName: "prefix-set-2", + wantCommunitySet: []string{"5:5", "6:6"}, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + configureRoutingPolicy(t, dut, tc.policyName, ebgp1NbrV4, tc.peerGrp) + configureRoutingPolicy(t, dut, tc.policyName, ebgp1NbrV6, tc.peerGrp) + for _, testResult := range tc.testResults { + for _, prefix := range routes[testResult.prefixSetName].prefixesV4 { + validateATEIPv4PrefixCommunitySet(t, ate, atePort2.Name+".BGP4.peer", prefix, testResult.wantCommunitySet) + validateDutIPv4PrefixCommunitySet(t, dut, ebgp1NbrV4, prefix, nil) + } + for _, prefix := range routes[testResult.prefixSetName].prefixesV6 { + validateATEIPv6PrefixCommunitySet(t, ate, atePort2.Name+".BGP6.peer", prefix, testResult.wantCommunitySet) + validateDutIPv6PrefixCommunitySet(t, dut, ebgp1NbrV6, prefix, nil) + } + } + // Starting ATE Traffic and verify Traffic Flows + sendTraffic(t, otg) + verifyTraffic(t, ate, otgConfig) + }) + } + }) + + t.Run("RT-7.8.2", func(t *testing.T) { + testCases := []testCase{ + { + desc: "neighborV4-match_and_add_comms", + nbr: ebgp1NbrV4, + peerGrp: "", + policyName: "match_and_add_comms", + testResults: []TestResults{ + { + prefixSetName: "prefix-set-1", + wantCommunitySet: nil, + }, + { + prefixSetName: "prefix-set-2", + wantCommunitySet: []string{"5:5", "6:6", "10:10", "20:20", "30:30"}, + }, + }, + }, + { + desc: "neighborV6-match_and_add_comms", + nbr: ebgp1NbrV6, + peerGrp: "", + policyName: "match_and_add_comms", + testResults: []TestResults{ + { + prefixSetName: "prefix-set-1", + wantCommunitySet: nil, + }, + { + prefixSetName: "prefix-set-2", + wantCommunitySet: []string{"5:5", "6:6", "10:10", "20:20", "30:30"}, + }, + }, + }, + { + desc: "PeerGrp-match_and_add_comms", + nbr: nil, + peerGrp: peerGrpName, + policyName: "match_and_add_comms", + testResults: []TestResults{ + { + prefixSetName: "prefix-set-1", + wantCommunitySet: nil, + }, + { + prefixSetName: "prefix-set-2", + wantCommunitySet: []string{"5:5", "6:6", "10:10", "20:20", "30:30"}, + }, + }, + }, + { + desc: "neighborV4-add_std_comms", + nbr: ebgp1NbrV4, + peerGrp: "", + policyName: "add_std_comms", + testResults: []TestResults{ + { + prefixSetName: "prefix-set-1", + wantCommunitySet: []string{"10:10", "20:20", "30:30"}, + }, + { + prefixSetName: "prefix-set-2", + wantCommunitySet: []string{"5:5", "6:6", "10:10", "20:20", "30:30"}, + }, + }, + }, + { + desc: "neighborV6-add_std_comms", + nbr: ebgp1NbrV6, + peerGrp: "", + policyName: "add_std_comms", + testResults: []TestResults{ + { + prefixSetName: "prefix-set-1", + wantCommunitySet: []string{"10:10", "20:20", "30:30"}, + }, + { + prefixSetName: "prefix-set-2", + wantCommunitySet: []string{"5:5", "6:6", "10:10", "20:20", "30:30"}, + }, + }, + }, + { + desc: "PeerGrp-add_std_comms", + nbr: nil, + peerGrp: peerGrpName, + policyName: "add_std_comms", + testResults: []TestResults{ + { + prefixSetName: "prefix-set-1", + wantCommunitySet: []string{"10:10", "20:20", "30:30"}, + }, + { + prefixSetName: "prefix-set-2", + wantCommunitySet: []string{"5:5", "6:6", "10:10", "20:20", "30:30"}, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + configureRoutingPolicy(t, dut, tc.policyName, tc.nbr, tc.peerGrp) + for _, testResult := range tc.testResults { + for _, prefix := range routes[testResult.prefixSetName].prefixesV4 { + if (tc.nbr == nil) || (tc.nbr != nil && tc.nbr.isV4 == true) { + validateATEIPv4PrefixCommunitySet(t, ate, atePort2.Name+".BGP4.peer", prefix, testResult.wantCommunitySet) + validateDutIPv4PrefixCommunitySet(t, dut, ebgp1NbrV4, prefix, nil) + } + } + for _, prefix := range routes[testResult.prefixSetName].prefixesV6 { + if (tc.nbr == nil) || (tc.nbr != nil && tc.nbr.isV4 != true) { + validateATEIPv6PrefixCommunitySet(t, ate, atePort2.Name+".BGP6.peer", prefix, testResult.wantCommunitySet) + validateDutIPv6PrefixCommunitySet(t, dut, ebgp1NbrV6, prefix, nil) + } + } + } + }) + } + }) +} diff --git a/feature/bgp/policybase/otg_tests/comm_match_action_test/metadata.textproto b/feature/bgp/policybase/otg_tests/comm_match_action_test/metadata.textproto index 624d867dfa7..c560af7dabd 100644 --- a/feature/bgp/policybase/otg_tests/comm_match_action_test/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/comm_match_action_test/metadata.textproto @@ -1,7 +1,22 @@ # proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata -plan_id: "RT-7.8" -description: "BGP Policy Match Standard Community and Add Community Import/Export Policy" -testbed: TESTBED_DUT_ATE_2LINKS -tags: [TAGS_AGGREGATION, TAGS_TRANSIT, TAGS_DATACENTER_EDGE] +uuid: "384964cf-2e53-4ee5-b8a5-eb99f4345cc1" +plan_id: "RT-7.8" +description: "BGP Policy Match Standard Community and Add Community Import/Export Policy" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_port_speed: true + explicit_interface_in_default_vrf: true + interface_enabled: true + bgp_conditions_match_community_set_unsupported: true + bgp_actions_set_community_method_unsupported: true + } +} +tags: TAGS_AGGREGATION +tags: TAGS_TRANSIT +tags: TAGS_DATACENTER_EDGE diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 6843fa9700d..23d10adcb3d 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -926,3 +926,8 @@ func UseVendorNativeTagSetConfig(dut *ondatra.DUTDevice) bool { func SkipBgpSendCommunityType(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetSkipBgpSendCommunityType() } + +// BgpActionsSetCommunityMethodUnsupported return true if BGP actions set-community method is unsupported +func BgpActionsSetCommunityMethodUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetBgpActionsSetCommunityMethodUnsupported() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 5e0521494eb..6deb16752dd 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -483,6 +483,9 @@ message Metadata { bool use_vendor_native_tag_set_config = 171; // Skip setting send-community-type in bgp global config bool skip_bgp_send_community_type = 172; + // Support for bgp actions set-community method + bool bgp_actions_set_community_method_unsupported = 173; + // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index fb3e67d2744..19b441813c3 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 -// protoc v3.21.12 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: metadata.proto package metadata_go_proto @@ -764,6 +764,8 @@ type Metadata_Deviations struct { UseVendorNativeTagSetConfig bool `protobuf:"varint,171,opt,name=use_vendor_native_tag_set_config,json=useVendorNativeTagSetConfig,proto3" json:"use_vendor_native_tag_set_config,omitempty"` // Skip setting send-community-type in bgp global config SkipBgpSendCommunityType bool `protobuf:"varint,172,opt,name=skip_bgp_send_community_type,json=skipBgpSendCommunityType,proto3" json:"skip_bgp_send_community_type,omitempty"` + // Support for bgp actions set-community method + BgpActionsSetCommunityMethodUnsupported bool `protobuf:"varint,173,opt,name=bgp_actions_set_community_method_unsupported,json=bgpActionsSetCommunityMethodUnsupported,proto3" json:"bgp_actions_set_community_method_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1890,6 +1892,13 @@ func (x *Metadata_Deviations) GetSkipBgpSendCommunityType() bool { return false } +func (x *Metadata_Deviations) GetBgpActionsSetCommunityMethodUnsupported() bool { + if x != nil { + return x.BgpActionsSetCommunityMethodUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1953,7 +1962,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x61, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfd, 0x61, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1987,7 +1996,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xf0, 0x58, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xd0, 0x59, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, @@ -2695,7 +2704,13 @@ var file_metadata_proto_rawDesc = []byte{ 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0xac, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x67, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x54, 0x79, - 0x70, 0x65, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, + 0x70, 0x65, 0x12, 0x5e, 0x0a, 0x2c, 0x62, 0x67, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x18, 0xad, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x62, 0x67, 0x70, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, + 0x79, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, From c9a0467b68b5358f03fc38d55cccdf29f44c8118 Mon Sep 17 00:00:00 2001 From: Octavian Petre <96260185+octpetre@users.noreply.github.com> Date: Mon, 22 Apr 2024 22:14:36 -0400 Subject: [PATCH 86/97] OTG Test - TE-3.3: Hierarchical weight resolution (#2357) * Initial ATE test copy * initial changes - not final * changes to the ate test * ate sync * added metadata and egress tracking * Corrected the egress packets * gosnappi.NewConfig * small fixes * update README and sync to ate test * PR comments addressed * PR reviews addressed * Added missing interface on port1 --- .../README.md | 142 ++++ .../hierarchical_weight_resolution_test.go | 745 ++++++++++++++++++ .../metadata.textproto | 49 ++ 3 files changed, 936 insertions(+) create mode 100644 feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md create mode 100644 feature/gribi/otg_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go create mode 100644 feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md new file mode 100644 index 00000000000..a7b35daed86 --- /dev/null +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md @@ -0,0 +1,142 @@ +# TE-3.3: Hierarchical weight resolution + +## Summary + +Ensures that next-hop weights (for WCMP) are honored hierarchically in gRIBI +recursive resolution and traffic is load-shared according to these weights. + +## Procedure + +Configure ATE and DUT: + +* Connect ATE port-1 to DUT port-1. ATE port-2 to DUT port-2. + +* Create a non-default VRF (VRF-1) that contains no interfaces. + +* On DUT port-2 and ATE port-2 create 18 L3 sub-interfaces each with a /30 + subnet as below: + + * On DUT port-2, create subinterfaces with indices 1 to 18 mapped to VLAN + IDs 1 to 18 and corressponding IPv4 addresses 192.0.2.5, 192.0.2.9, ..., + 192.0.2.73 respectively. + + * On ATE port-2, create subinterfaces with indices 1 to 18 mapped to VLAN + IDs 1 to 18 and corresponding IPv4 addresses 192.0.2.6, 192.0.2.10, ..., + 192.0.2.74 and default gateways as 192.0.2.5, 192.0.2.9, ..., 192.0.2.73 + respectively. + +* On DUT port-1 and ATE port-1 create a single L3 interface. + +* On DUT, create a policy-based forwarding rule to redirect all traffic + received from DUT port-1 into VRF-1 (based on src. IP match criteria). + +Test case for basic hierarchical weight: + +* Establish gRIBI client connection with DUT with PERSISTENCE, make it become + leader and install the following Entries: + + * IPv4Entry 203.0.113.0/32 in VRF-1, pointing to NextHopGroup(NHG#1) in + default VRF, with two NextHops(NH#1, NH#2) in default VRF: + + * NH#1 with weight:1, pointing to 192.0.2.111 + + * NH#2 with weight:3, pointing to 192.0.2.222 + + * IPv4Entry 192.0.2.111/32 in default VRF, pointing to NextHopGroup(NHG#2) + in default VRF, with two NextHops(NH#10, NH#11) in default VRF: + + * NH#10 with weight:1, pointing to 192.0.2.10 + + * NH#11 with weight:3, pointing to 192.0.2.14 + + * IPv4Entry 192.0.2.222/32 in default VRF, pointing to NextHopGroup(NHG#3) + in default VRF, with two NextHops(NH#100, NH#101) in default VRF: + + * NH#100 with weight:3, pointing to 192.0.2.18 + + * NH#101 with weight:5, pointing to 192.0.2.22 + +* Validate with traffic: + + * NH10: (1/4) * (1/4) = 6.25% traffic received by ATE port-2 VLAN 1 + + * NH11: (1/4) * (3/4) = 18.75% traffic received by ATE port-2 VLAN 2 + + * NH100: (3/4) * (3/8) = 28.12% traffic received by ATE port-2 VLAN 3 + + * NH101: (3/4) * (5/8) = 46.87% traffic received by ATE port-2 VLAN 4 + + * A tolerance of 0.2% is allowed for each VLAN for now, since we only test + for 2 mins. + +Test case for hierarchical weight in boundary scenarios, with maximum expected +WCMP width of 16 nexthops: + +* Flush previous gRIBI Entries for all NIs and establish a new connection with + DUT with PERSISTENCE and install the following Entries: + + * IPv4Entry 203.0.113.0/32 in VRF-1, pointing to NextHopGroup(NHG#1) in + default VRF, with two NextHops(NH#1, NH#2) in default VRF: + + * NH#1 with weight:1, pointing to 192.0.2.111 + + * NH#2 with weight:31, pointing to 192.0.2.222 + + * IPv4Entry 192.0.2.111/32 in default VRF, pointing to NextHopGroup(NHG#2) + in default VRF, with two NextHops(NH#10, NH#11) in default VRF: + + * NH#10 with weight:3, pointing to 192.0.2.10 + + * NH#11 with weight:5, pointing to 192.0.2.14 + + * IPv4Entry 192.0.2.222/32 in default VRF, pointing to NextHopGroup(NHG#3) + in default VRF, with 16 NextHops(NH#100, NH#101, ..., NH#115), all with + weight: 16 except NHG#100 is of weight 1, in default VRF: + + * NH#100 with weight:1, pointing to 192.0.2.18 + + * NH#101 with weight:16, pointing to 192.0.2.22 + + * ... + + * NH#115 with weight:16, pointing to 192.0.2.79 + +* Validate with traffic: + + * NH10: (1/32) * (3/8) ~ 1.171% traffic received by ATE port-2 VLAN 1 + + * NH11: (1/32) * (5/8) ~ 1.953% traffic received by ATE port-2 VLAN 2 + + * NH100: (31/32) * (1/241) ~ 0.402% traffic received by ATE port-2 VLAN 3 + + * for each VLAN ID in 4...18: + + * NH: (31/32) * (16/241) ~ 6.432% traffic received by ATE port-2 VLAN + ID + + * A tolerance of 0.2% is allowed for each VLAN for now, since we only test + for 2 mins. + +## Config Parameter Coverage + +N/A + +## Telemetry Parameter Coverage + +TODO: +/network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight + +## Protocol/RPC Parameter coverage + +* gRIBI: + * Modify() + * ModifyRequest: + * AFTOperation: + * next_hop_group + * NextHopGroupKey: id + * NextHopGroup: weight + +## Minimum DUT platform requirement + +vRX + diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go new file mode 100644 index 00000000000..4d0bc5d8d34 --- /dev/null +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go @@ -0,0 +1,745 @@ +// Copyright 2022 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 hierarchical_weight_resolution_test implements TE-3.3 of the Popgate vendor testplan +package hierarchical_weight_resolution_test + +import ( + "bytes" + "context" + "encoding/binary" + "fmt" + "net" + "strconv" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "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/gribi" + "github.com/openconfig/featureprofiles/internal/otgutils" + "github.com/openconfig/gribigo/chk" + "github.com/openconfig/gribigo/constants" + "github.com/openconfig/gribigo/fluent" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +type attributes struct { + attrs.Attributes + numSubIntf uint32 + ip func(vlan uint8) string + gateway func(vlan uint8) string +} + +type nhInfo struct { + index uint64 + weight uint64 +} + +const ( + ipv4EntryPrefix = "203.0.113.0/32" + ipv4FlowIP = "203.0.113.0" + innerSrcIPv4Start = "198.18.0.0" + innerDstIPv4Start = "198.19.0.0" + ipv4PrefixLen = 30 + ipv4FlowCount = 65000 + nhEntryIP1 = "192.0.2.111" + nhEntryIP2 = "192.0.2.222" + nonDefaultVRF = "VRF-1" + policyName = "redirect-to-VRF1" + ipipProtocol = 4 +) + +var ( + dutPort1 = attributes{ + Attributes: attrs.Attributes{ + Desc: "dutPort1", + Name: "port1", + IPv4: dutPort1IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 0, + ip: dutPort1IPv4, + } + + atePort1 = attributes{ + Attributes: attrs.Attributes{ + Name: "port1", + MAC: "02:00:01:01:01:01", + IPv4: atePort1IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 0, + ip: atePort1IPv4, + gateway: dutPort1IPv4, + } + + dutPort2 = attributes{ + Attributes: attrs.Attributes{ + Desc: "dutPort2", + Name: "port2", + IPv4: dutPort2IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 18, + ip: dutPort2IPv4, + } + + atePort2 = attributes{ + Attributes: attrs.Attributes{ + Name: "port2", + MAC: "02:00:02:01:01:01", + IPv4: atePort2IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 18, + ip: atePort2IPv4, + gateway: dutPort2IPv4, + } + + // nhgIPv4EntryMap maps NextHopGroups to the ipv4 entries pointing to that NextHopGroup. + nhgIPv4EntryMap = map[uint64]string{ + 1: ipv4EntryPrefix, + 2: cidr(nhEntryIP1, 32), + 3: cidr(nhEntryIP2, 32), + } + // 'tolerance' is the maximum difference that is allowed between the observed + // traffic distribution and the required traffic distribution. + tolerance = 0.2 +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// dutPort1IPv4 returns ip address 192.0.2.1, for every vlanID. +func dutPort1IPv4(uint8) string { + return "192.0.2.1" +} + +// atePort1IPv4 returns ip address 192.0.2.2, for every vlanID +func atePort1IPv4(uint8) string { + return "192.0.2.2" +} + +// dutPort2IPv4 returns ip addresses starting 192.0.2.5, increasing by 4 +// for every vlanID. +func dutPort2IPv4(vlan uint8) string { + return fmt.Sprintf("192.0.2.%d", vlan*4+5) +} + +// atePort2IPv4 returns ip addresses starting 192.0.2.6, increasing by 4 +// for every vlanID. +func atePort2IPv4(vlan uint8) string { + return fmt.Sprintf("192.0.2.%d", vlan*4+6) +} + +// cidr taks as input the IPv4 address and the Mask and returns the IP string in +// CIDR notation. +func cidr(ipv4 string, ones int) string { + return ipv4 + "/" + strconv.Itoa(ones) +} + +// filterPacketReceived uses ATE:EgressTracking bucket counters to create a map +// with bucket-label as the Key and the percentage of packets-received for that +// bucket as the Value. +func filterPacketReceived(t *testing.T, flow string, ate *ondatra.ATEDevice) map[string]float64 { + t.Helper() + + // Check the egress packets + vlanTags := gnmi.GetAll(t, ate.OTG(), gnmi.OTG().Flow(flow).TaggedMetricAny().State()) + tags := gnmi.GetAll(t, ate.OTG(), gnmi.OTG().Flow(flow).TaggedMetricAny().TagsAny().State()) + t.Logf("There are a total of %v vlans", len(tags)) + + inPkts := map[string]uint64{} + for i, tag := range tags { + vlanHex := strings.Replace(tag.GetTagValue().GetValueAsHex(), "0x", "", -1) + vlanDec, _ := strconv.ParseUint(vlanHex, 16, 64) + inPkts[strconv.Itoa(int(vlanDec))] = vlanTags[i].GetCounters().GetInPkts() + } + inPct := map[string]float64{} + total := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow(flow).Counters().InPkts().State()) + for k, v := range inPkts { + inPct[k] = (float64(v) / float64(total)) * 100.0 + } + return inPct +} + +// configureGRIBIClient configures a new GRIBI client with PRESERVE and FIB_ACK. +func configureGRIBIClient(t *testing.T, dut *ondatra.DUTDevice) *fluent.GRIBIClient { + t.Helper() + gribic := dut.RawAPIs().GRIBI(t) + + // Configure the gRIBI client. + c := fluent.NewClient() + c.Connection(). + WithStub(gribic). + WithRedundancyMode(fluent.ElectedPrimaryClient). + WithInitialElectionID(1 /* low */, 0 /* hi */). + WithPersistence(). + WithFIBACK() + + return c +} + +// nextHopEntry configures a fluent.GRIBIEntry for a NextHopEntry. +func nextHopEntry(index uint64, networkInstance string, ipAddr string) fluent.GRIBIEntry { + return fluent.NextHopEntry(). + WithNetworkInstance(networkInstance). + WithIndex(index). + WithIPAddress(ipAddr) +} + +// nextHopGroupEntry configures a fluent.GRIBIEntry for a NextHopGroupEntry. +func nextHopGroupEntry(index uint64, networkInstance string, nhs []nhInfo) fluent.GRIBIEntry { + x := fluent.NextHopGroupEntry(). + WithNetworkInstance(networkInstance). + WithID(index) + for _, nh := range nhs { + x.AddNextHop(nh.index, nh.weight) + } + return x +} + +// ipv4Entry configures a fluent.GRIBIEntry for an IPv4Entry. +func ipv4Entry(prefix string, networkInstance string, nhgIndex uint64, nextHopGroupNetworkInstance string) fluent.GRIBIEntry { + return fluent.IPv4Entry(). + WithPrefix(prefix). + WithNetworkInstance(networkInstance). + WithNextHopGroup(nhgIndex). + WithNextHopGroupNetworkInstance(nextHopGroupNetworkInstance) +} + +// awaitTimeout calls a fluent client Await, adding a timeout to the context. +func awaitTimeout(ctx context.Context, c *fluent.GRIBIClient, t testing.TB, timeout time.Duration) error { + t.Helper() + subctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + return c.Await(subctx, t) +} + +// configSubinterfaceDUT configures the Sub Interfaces of an Interfaces, +// starting from Sub Interface 1. Each Subinterface is configured with a +// unique VlanID starting from 1 and an IP address. The starting IP Address +// for Subinterface(1) = dutPort.ip(1) = dutPort.ip + 4. +func (a *attributes) configSubinterfaceDUT(t *testing.T, intf *oc.Interface, dut *ondatra.DUTDevice) { + t.Helper() + if deviations.RequireRoutedSubinterface0(dut) { + s0 := intf.GetOrCreateSubinterface(0).GetOrCreateIpv4() + s0.Enabled = ygot.Bool(true) + } + for i := uint32(1); i <= a.numSubIntf; i++ { + ip := a.ip(uint8(i)) + + s := intf.GetOrCreateSubinterface(i) + if deviations.InterfaceEnabled(dut) { + s.Enabled = ygot.Bool(true) + } + if deviations.DeprecatedVlanID(dut) { + s.GetOrCreateVlan().VlanId = oc.UnionUint16(i) + } else { + s.GetOrCreateVlan().GetOrCreateMatch().GetOrCreateSingleTagged().VlanId = ygot.Uint16(uint16(i)) + } + s4 := s.GetOrCreateIpv4() + if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { + s4.Enabled = ygot.Bool(true) + } + s4a := s4.GetOrCreateAddress(ip) + s4a.PrefixLength = ygot.Uint8(a.IPv4Len) + t.Logf("Adding DUT Subinterface with ID: %d, Vlan ID: %d and IPv4 address: %s", i, i, ip) + } +} + +// configInterfaceDUT configures the DUT interface with the provided IP Address. +// Sub Interfaces are also configured if numSubIntf > 0. +func (a *attributes) configInterfaceDUT(t *testing.T, d *ondatra.DUTDevice) { + t.Helper() + p := d.Port(t, a.Name) + i := &oc.Interface{Name: ygot.String(p.Name())} + + if a.numSubIntf > 0 { + i.Description = ygot.String(a.Desc) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + if deviations.InterfaceEnabled(d) { + i.Enabled = ygot.Bool(true) + } + } else { + i = a.NewOCInterface(p.Name(), d) + } + + if deviations.ExplicitPortSpeed(d) { + i.GetOrCreateEthernet().PortSpeed = fptest.GetIfSpeed(t, p) + } + + a.configSubinterfaceDUT(t, i, d) + intfPath := gnmi.OC().Interface(p.Name()) + gnmi.Replace(t, d, intfPath.Config(), i) + fptest.LogQuery(t, "DUT", intfPath.Config(), gnmi.Get(t, d, intfPath.Config())) +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + // configure NI. + configureNetworkInstance(t, dut) + + // Configure DUT ports. + dutPort1.configInterfaceDUT(t, dut) + dutPort2.configInterfaceDUT(t, dut) + + // assign subinterfaces to DEFAULT network instance if needed (deviation-based). + dutPort1.assignSubifsToDefaultNetworkInstance(t, dut) + dutPort2.assignSubifsToDefaultNetworkInstance(t, dut) + + // apply PBF to src interface. + dp1 := dut.Port(t, dutPort1.Name) + applyForwardingPolicy(t, dp1.Name()) +} + +// configureNetworkInstance creates and configures non-default and default NIs. +func configureNetworkInstance(t *testing.T, d *ondatra.DUTDevice) { + t.Helper() + + // configure non-default VRF + ni := &oc.NetworkInstance{ + Name: ygot.String(nonDefaultVRF), + Type: oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF, + } + dni := gnmi.OC().NetworkInstance(nonDefaultVRF) + gnmi.Replace(t, d, dni.Config(), ni) + fptest.LogQuery(t, "NI", dni.Config(), gnmi.Get(t, d, dni.Config())) + + // configure PBF in DEFAULT vrf + defNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(d)) + fptest.ConfigureDefaultNetworkInstance(t, d) + gnmi.Replace(t, d, defNIPath.PolicyForwarding().Config(), configurePBF(d)) + +} + +// assignSubifsToDefaultNetworkInstance assign subinterfaces to the default network instance when ExplicitInterfaceInDefaultVRF is enabled. +func (a *attributes) assignSubifsToDefaultNetworkInstance(t *testing.T, d *ondatra.DUTDevice) { + p := d.Port(t, a.Name) + if deviations.ExplicitInterfaceInDefaultVRF(d) { + if a.numSubIntf == 0 { + fptest.AssignToNetworkInstance(t, d, p.Name(), deviations.DefaultNetworkInstance(d), 0) + } else { + for i := uint32(1); i <= a.numSubIntf; i++ { + fptest.AssignToNetworkInstance(t, d, p.Name(), deviations.DefaultNetworkInstance(d), i) + } + } + } +} + +// configurePBF returns a fully configured network-instance PF struct. +func configurePBF(dut *ondatra.DUTDevice) *oc.NetworkInstance_PolicyForwarding { + d := &oc.Root{} + ni := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + pf := ni.GetOrCreatePolicyForwarding() + vrfPolicy := pf.GetOrCreatePolicy(policyName) + vrfPolicy.SetType(oc.Policy_Type_VRF_SELECTION_POLICY) + vrfPolicy.GetOrCreateRule(1).GetOrCreateIpv4().Protocol = oc.UnionUint8(ipipProtocol) + vrfPolicy.GetOrCreateRule(1).GetOrCreateAction().NetworkInstance = ygot.String(nonDefaultVRF) + return pf +} + +// applyForwardingPolicy applies the forwarding policy on the interface. +func applyForwardingPolicy(t *testing.T, ingressPort string) { + t.Logf("Applying forwarding policy on interface %v ... ", ingressPort) + d := &oc.Root{} + dut := ondatra.DUT(t, "dut") + interfaceID := ingressPort + if deviations.InterfaceRefInterfaceIDFormat(dut) { + interfaceID = ingressPort + ".0" + } + pfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Interface(interfaceID) + pfCfg := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)).GetOrCreatePolicyForwarding().GetOrCreateInterface(interfaceID) + pfCfg.ApplyVrfSelectionPolicy = ygot.String(policyName) + pfCfg.GetOrCreateInterfaceRef().Interface = ygot.String(ingressPort) + pfCfg.GetOrCreateInterfaceRef().Subinterface = ygot.Uint32(0) + if deviations.InterfaceRefConfigUnsupported(dut) { + pfCfg.InterfaceRef = nil + } + gnmi.Replace(t, dut, pfPath.Config(), pfCfg) +} + +// configureATE configures Ethernet + IPv4 on the ATE. If the number of +// Subinterfaces(numSubIntf) > 0, we then create additional sub-interfaces +// each with a unique VlanID starting from 1. The IPv4 addresses start with +// ATE:Port.IPv4 and then nextIP(ATE:Port.IPv4, 4) for each sub interface. +func (a *attributes) configureATE(t *testing.T, top gosnappi.Config, ate *ondatra.ATEDevice) { + t.Helper() + p := ate.Port(t, a.Name) + + // Configure source port on ATE : Port1. + + top.Ports().Add().SetName(p.ID()) + if a.numSubIntf == 0 { + ip := a.ip(0) + gateway := a.gateway(0) + dev := top.Devices().Add().SetName(a.Name) + eth := dev.Ethernets().Add().SetName(a.Name + ".Eth").SetMac(a.MAC) + eth.Connection().SetPortName(p.ID()) + ipObj := eth.Ipv4Addresses().Add().SetName(dev.Name() + ".IPv4") + ipObj.SetAddress(ip).SetGateway(gateway).SetPrefix(uint32(a.IPv4Len)) + t.Logf("Adding ATE Ipv4 address: %s with gateway: %s", cidr(ip, int(a.IPv4Len)), gateway) + } + // Configure destination port on ATE : Port2. + for i := uint32(1); i <= a.numSubIntf; i++ { + name := fmt.Sprintf(`dst%d`, i) + ip := a.ip(uint8(i)) + gateway := a.gateway(uint8(i)) + mac, err := incrementMAC(a.MAC, int(i)+1) + if err != nil { + t.Fatalf("Failed to generate mac address with error %s", err) + } + + dev := top.Devices().Add().SetName(name + ".Dev") + eth := dev.Ethernets().Add().SetName(name + ".Eth").SetMac(mac) + eth.Connection().SetPortName(p.ID()) + eth.Vlans().Add().SetName(name).SetId(uint32(i)) + eth.Ipv4Addresses().Add().SetName(name + ".IPv4").SetAddress(ip).SetGateway(gateway).SetPrefix(uint32(a.IPv4Len)) + + t.Logf("Adding ATE Ipv4 address: %s with gateway: %s and VlanID: %d", cidr(ip, 30), gateway, i) + } + // } +} + +// incrementMAC increments the MAC by i. Returns error if the mac cannot be parsed or overflows the mac address space +func incrementMAC(mac string, i int) (string, error) { + macAddr, err := net.ParseMAC(mac) + if err != nil { + return "", err + } + convMac := binary.BigEndian.Uint64(append([]byte{0, 0}, macAddr...)) + convMac = convMac + uint64(i) + buf := new(bytes.Buffer) + err = binary.Write(buf, binary.BigEndian, convMac) + if err != nil { + return "", err + } + newMac := net.HardwareAddr(buf.Bytes()[2:8]) + return newMac.String(), nil +} + +// testTraffic creates a traffic flow with ATE source & destination endpoints +// and configures a VlanID filter for output frames. The IPv4 header for the +// flow contains the ATE:Port1 address as source and the configured gRIBI- +// IndirectEntry as the destination. The function also takes as input a map of +// that is wanted and compares it to the actual +// traffic test result. +func testTraffic(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) map[string]float64 { + + dut := ondatra.DUT(t, "dut") + dstMac := gnmi.Get(t, dut, gnmi.OC().Interface(dut.Port(t, "port1").Name()).Ethernet().MacAddress().State()) + top.Flows().Clear().Items() + flowipv4 := top.Flows().Add().SetName("flow") + flowipv4.Metrics().SetEnable(true) + flowipv4.TxRx().Port().SetTxName(atePort1.Name).SetRxNames([]string{atePort2.Name}) + flowipv4.Size().SetFixed(100) + e1 := flowipv4.Packet().Add().Ethernet() + e1.Src().SetValue(atePort1.MAC) + e1.Dst().SetValue(dstMac) + v4 := flowipv4.Packet().Add().Ipv4() + v4.Src().SetValue(atePort1.IPv4) + v4.Dst().SetValue(ipv4FlowIP) + v4Inner := flowipv4.Packet().Add().Ipv4() + v4Inner.Src().Increment().SetStart(innerSrcIPv4Start).SetCount(ipv4FlowCount) + v4Inner.Dst().Increment().SetStart(innerDstIPv4Start).SetCount(ipv4FlowCount) + flowipv4.EgressPacket().Add().Ethernet() + vlan := flowipv4.EgressPacket().Add().Vlan() + vlanTag := vlan.Id().MetricTags().Add() + vlanTag.SetName("EgressVlanIdTrackingFlow") + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, ate.OTG(), top, "IPv4") + + // Run traffic for 2 minutes. + ate.OTG().StartTraffic(t) + time.Sleep(1 * time.Minute) + ate.OTG().StopTraffic(t) + + otgutils.LogFlowMetrics(t, ate.OTG(), top) + + recvMetric := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow(flowipv4.Name()).State()) + txPkts := float32(recvMetric.GetCounters().GetOutPkts()) + rxPkts := float32(recvMetric.GetCounters().GetInPkts()) + lossPct := (txPkts - rxPkts) * 100 / txPkts + if txPkts == 0 { + t.Fatalf("TxPkts == 0, want > 0.") + } + if lossPct > 0 && recvMetric.GetCounters().GetOutPkts() > 0 { + t.Fatalf("Loss Pct for %s got %v, want 0", flowipv4.Name(), lossPct) + } + + // Compare traffic distribution with the wanted results. + results := filterPacketReceived(t, "flow", ate) + t.Logf("Filters: %v", results) + return results +} + +// aftNextHopWeights queries AFT telemetry using Get() and returns +// the weights. If not-found, an empty list is returned. +func aftNextHopWeights(t *testing.T, dut *ondatra.DUTDevice, nhg uint64, networkInstance string) []uint64 { + aft := gnmi.Get(t, dut, gnmi.OC().NetworkInstance(networkInstance).Afts().State()) + var nhgD *oc.NetworkInstance_Afts_NextHopGroup + for _, nhgData := range aft.NextHopGroup { + if nhgData.GetProgrammedId() == nhg { + nhgD = nhgData + break + } + } + + if nhgD == nil { + return []uint64{} + } + + got := []uint64{} + for _, nhD := range nhgD.NextHop { + got = append(got, nhD.GetWeight()) + } + + return got +} + +// testBasicHierarchicalWeight tests and validates traffic through 4 Vlans. +func testBasicHierarchicalWeight(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice, + ate *ondatra.ATEDevice, top gosnappi.Config, gRIBI *fluent.GRIBIClient) { + defaultVRF := deviations.DefaultNetworkInstance(dut) + + // Set up NH#10, NH#11, NHG#2, IPv4Entry(192.0.2.111). + nh10 := nextHopEntry(10, defaultVRF, atePort2.ip(1)) + nh11 := nextHopEntry(11, defaultVRF, atePort2.ip(2)) + nhg2 := nextHopGroupEntry(2, defaultVRF, []nhInfo{{index: 10, weight: 1}, {index: 11, weight: 3}}) + ipEntry2 := ipv4Entry(nhgIPv4EntryMap[2], defaultVRF, 2, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh10, nh11, nhg2, ipEntry2) + + // Set up NH#100, NH#101, NHG#3, IPv4Entry(192.0.2.222). + nh100 := nextHopEntry(100, defaultVRF, atePort2.ip(3)) + nh101 := nextHopEntry(101, defaultVRF, atePort2.ip(4)) + nhg3 := nextHopGroupEntry(3, defaultVRF, []nhInfo{{index: 100, weight: 3}, {index: 101, weight: 5}}) + ipEntry3 := ipv4Entry(nhgIPv4EntryMap[3], defaultVRF, 3, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh100, nh101, nhg3, ipEntry3) + + // Set up NH#1, NH#2, NHG#1, IPv4Entry(198.18.196.1/22). + nh1 := nextHopEntry(1, defaultVRF, nhEntryIP1) + nh2 := nextHopEntry(2, defaultVRF, nhEntryIP2) + nhg1 := nextHopGroupEntry(1, defaultVRF, []nhInfo{{index: 1, weight: 1}, {index: 2, weight: 3}}) + ipEntry1 := ipv4Entry(nhgIPv4EntryMap[1], nonDefaultVRF, 1, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh1, nh2, nhg1, ipEntry1) + + if err := awaitTimeout(ctx, gRIBI, t, time.Minute); err != nil { + t.Fatalf("Could not program entries via gRIBI, got err: %v", err) + } + + // Validate entries were installed in FIB. + for _, route := range nhgIPv4EntryMap { + chk.HasResult(t, gRIBI.Results(t), + fluent.OperationResult(). + WithIPv4Operation(route). + WithOperationType(constants.Add). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + } + + // Test traffic flows correctly and + wantWeights := map[string]float64{ + "1": 6.25, + "2": 18.75, + "3": 28.12, + "4": 46.87, + } + t.Run("testTraffic", func(t *testing.T) { + got := testTraffic(t, ate, top) + if diff := cmp.Diff(wantWeights, got, cmpopts.EquateApprox(0, tolerance)); diff != "" { + t.Errorf("Packet distribution ratios -want,+got:\n%s", diff) + } + }) + + t.Run("validateAFTWeights", func(t *testing.T) { + for nhg, weights := range map[uint64][]uint64{ + 2: {1, 3}, + 3: {3, 5}, + } { + got := aftNextHopWeights(t, dut, nhg, defaultVRF) + ok := cmp.Equal(weights, got, cmpopts.SortSlices(func(a, b uint64) bool { return a < b })) + if !ok { + t.Errorf("Valid weights not present for NI: %s, NHG: %d, got: %v, want: %v", defaultVRF, nhg, got, weights) + } + } + }) + + // Flush gRIBI routes after test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Error(err) + } +} + +// testHierarchicalWeightBoundaryScenario tests and validates traffic through all 18 Vlans. +func testHierarchicalWeightBoundaryScenario(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice, + ate *ondatra.ATEDevice, top gosnappi.Config, gRIBI *fluent.GRIBIClient) { + defaultVRF := deviations.DefaultNetworkInstance(dut) + + // Set up NH#10, NH#11, NHG#2, IPv4Entry(192.0.2.111). + nh10 := nextHopEntry(10, defaultVRF, atePort2.ip(1)) + nh11 := nextHopEntry(11, defaultVRF, atePort2.ip(2)) + nhg2 := nextHopGroupEntry(2, defaultVRF, []nhInfo{{index: 10, weight: 3}, {index: 11, weight: 5}}) + ipEntry2 := ipv4Entry(nhgIPv4EntryMap[2], defaultVRF, 2, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh10, nh11, nhg2, ipEntry2) + + // Set up NH#100..NH#116, NHG#3, IPv4Entry(192.0.2.222). + nextHopWeights := []nhInfo{} + nhIdx := uint64(100) + gribiEntries := []fluent.GRIBIEntry{} + for i := 0; i < 16; i++ { + nh := nextHopEntry(nhIdx, defaultVRF, atePort2.ip(uint8(3+i))) + gribiEntries = append(gribiEntries, nh) + if i == 0 { + nextHopWeights = append(nextHopWeights, nhInfo{index: nhIdx, weight: 1}) + } else { + nextHopWeights = append(nextHopWeights, nhInfo{index: nhIdx, weight: 16}) + } + nhIdx++ + } + nhg3 := nextHopGroupEntry(3, defaultVRF, nextHopWeights) + ipEntry3 := ipv4Entry(nhgIPv4EntryMap[3], defaultVRF, 3, defaultVRF) + gribiEntries = append(gribiEntries, nhg3, ipEntry3) + + gRIBI.Modify().AddEntry(t, gribiEntries...) + + // Set up NH#1, NH#2, NHG#1, IPv4Entry(198.18.196.1/22). + nh1 := nextHopEntry(1, defaultVRF, nhEntryIP1) + nh2 := nextHopEntry(2, defaultVRF, nhEntryIP2) + nhg1 := nextHopGroupEntry(1, defaultVRF, []nhInfo{{index: 1, weight: 1}, {index: 2, weight: 31}}) + ipEntry1 := ipv4Entry(nhgIPv4EntryMap[1], nonDefaultVRF, 1, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh1, nh2, nhg1, ipEntry1) + + if err := awaitTimeout(ctx, gRIBI, t, time.Minute); err != nil { + t.Fatalf("Could not program entries via gRIBI, got err: %v", err) + } + + // Validate entries were installed in FIB. + for _, route := range nhgIPv4EntryMap { + chk.HasResult(t, gRIBI.Results(t), + fluent.OperationResult(). + WithIPv4Operation(route). + WithOperationType(constants.Add). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + } + + wantWeights := map[string]float64{ + "1": 1.171, + "2": 1.953, + "3": 0.402, + } + // 6.432 weight for vlans 4 to 18. + for i := 4; i <= 18; i++ { + wantWeights[strconv.Itoa(i)] = 6.432 + } + t.Run("testTraffic", func(t *testing.T) { + got := testTraffic(t, ate, top) + + if deviations.HierarchicalWeightResolutionTolerance(dut) != tolerance { + tolerance = deviations.HierarchicalWeightResolutionTolerance(dut) + } + if diff := cmp.Diff(wantWeights, got, cmpopts.EquateApprox(0, tolerance)); diff != "" { + t.Errorf("Packet distribution ratios -want,+got:\n%s", diff) + } + }) + + t.Run("validateAFTWeights", func(t *testing.T) { + for nhg, weights := range map[uint64][]uint64{ + 2: {3, 5}, + 3: {1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}, + } { + got := aftNextHopWeights(t, dut, nhg, defaultVRF) + ok := cmp.Equal(weights, got, cmpopts.SortSlices(func(a, b uint64) bool { return a < b })) + if !ok { + t.Errorf("Valid weights not present for NI: %s, NHG: %d, got: %v, want: %v", defaultVRF, nhg, got, weights) + } + } + }) + + // Flush gRIBI routes after test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Error(err) + } +} + +func TestHierarchicalWeightResolution(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + ctx := context.Background() + + // Configure ATE ports and start Ethernet+IPv4. + top := gosnappi.NewConfig() + atePort1.configureATE(t, top, ate) + atePort2.configureATE(t, top, ate) + + ate.OTG().PushConfig(t, top) + + // configure DUT. + configureDUT(t, dut) + + ate.OTG().StartProtocols(t) + + // Configure gRIBI with FIB_ACK. + gRIBI := configureGRIBIClient(t, dut) + + gRIBI.Start(ctx, t) + defer gRIBI.Stop(t) + + defer func() { + // Flush all gRIBI routes after test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Error(err) + } + }() + + gRIBI.StartSending(ctx, t) + if err := awaitTimeout(ctx, gRIBI, t, time.Minute); err != nil { + t.Fatalf("Await got error during session negotiation for gRIBI: %v", err) + } + gribi.BecomeLeader(t, gRIBI) + + // Flush existing gRIBI routes before test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Fatal(err) + } + + t.Run("TestBasicHierarchicalWeight", func(t *testing.T) { + testBasicHierarchicalWeight(ctx, t, dut, ate, top, gRIBI) + }) + + t.Run("TestHierarchicalWeightBoundaryScenario", func(t *testing.T) { + testHierarchicalWeightBoundaryScenario(ctx, t, dut, ate, top, gRIBI) + }) + + ate.OTG().StopProtocols(t) +} diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto new file mode 100644 index 00000000000..63b7b4f20f6 --- /dev/null +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto @@ -0,0 +1,49 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "93695155-2898-47d4-9bbb-ac40611d3882" +plan_id: "TE-3.3" +description: "Hierarchical weight resolution" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + hierarchical_weight_resolution_tolerance: 1.5 + ipv4_missing_enabled: true + interface_ref_interface_id_format: true + } +} +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + hierarchical_weight_resolution_tolerance: 0.4 + explicit_interface_ref_definition: true + } +} +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_interface_ref_definition: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + interface_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + deprecated_vlan_id: true + interface_enabled: true + default_network_instance: "default" + } +} +tags: TAGS_TRANSIT From 6d95799ae2ec5c57df6c6dba972d9be2a690226d Mon Sep 17 00:00:00 2001 From: prakashbadri-arista <127355794+prakashbadri-arista@users.noreply.github.com> Date: Mon, 22 Apr 2024 21:06:42 -0700 Subject: [PATCH 87/97] Fix for TE-11.1: Backup NHG test due to Next hop entry missing (#2914) There is a small race condition possible in the test validation of the AFT telemetry where get for the nexthop group AFT state may miss the expected nexthop entry since the get is done prematurely. As a fix, add a gnmi.Watch for the expected state. --- .../backup_nhg_test/backup_nhg_test.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go b/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go index 5903ebf83d9..e80bd9718f5 100644 --- a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go +++ b/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go @@ -397,12 +397,22 @@ func (a *testArgs) validateAftTelemetry(t *testing.T, vrfName, prefix, ipAddress t.Fatalf("Could not find prefix %s in telemetry AFT", prefix+"/"+mask) } aftPfx, _ := aftPfxVal.Val() - - aftNHG := gnmi.Get(t, a.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(a.dut)).Afts().NextHopGroup(aftPfx.GetNextHopGroup()).State()) - if got := len(aftNHG.NextHop); got != 1 { - t.Fatalf("Prefix %s next-hop entry count: got %d, want 1", prefix+"/"+mask, got) + _, found = gnmi.Watch(t, a.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(a.dut)).Afts().NextHopGroup(aftPfx.GetNextHopGroup()).State(), + 2*time.Minute, func(val *ygnmi.Value[*oc.NetworkInstance_Afts_NextHopGroup]) bool { + value, present := val.Val() + return present && len(value.NextHop) == 1 + }).Await(t) + if !found { + t.Fatalf("nexthop entry count mismatch for prefix %s", prefix+"/"+mask) } + /* + aftNHG := gnmi.Get(t, a.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(a.dut)).Afts().NextHopGroup(aftPfx.GetNextHopGroup()).State()) + if got := len(aftNHG.NextHop); got != 1 { + t.Fatalf("Prefix %s next-hop entry count: got %d, want 1", prefix+"/"+mask, got) + } + */ + aftNHG := gnmi.Get(t, a.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(a.dut)).Afts().NextHopGroup(aftPfx.GetNextHopGroup()).State()) for k := range aftNHG.NextHop { aftnh := gnmi.Get(t, a.dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(a.dut)).Afts().NextHop(k).State()) // Handle the cases where the device returns the indirect NH or the recursively resolved NH. From a9dfd0e56f3439298ac384e155fea2911ffa75b0 Mon Sep 17 00:00:00 2001 From: AmrNJ <155722765+AmrNJ@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:43:05 +0530 Subject: [PATCH 88/97] Bgp prefix set test (#2884) * Update bgp_prefix_set_test.go * Update metadata.textproto * Update bgp_prefix_set_test.go * Update metadata.proto * Update deviations.go * Generated metadata.pb.go * Updated ygot import * Updated imports * Updated imports * Formatted the file * Update metadata.proto * Update metadata.pb.go --------- Co-authored-by: Pramod Maurya --- .../prefix_set_test/bgp_prefix_set_test.go | 60 ++++++---- .../prefix_set_test/metadata.textproto | 1 + internal/deviations/deviations.go | 5 + proto/metadata.proto | 5 +- proto/metadata_go_proto/metadata.pb.go | 110 ++++++++++-------- 5 files changed, 110 insertions(+), 71 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go b/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go index 5034077c35f..1b0d1c21391 100644 --- a/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go +++ b/feature/bgp/policybase/otg_tests/prefix_set_test/bgp_prefix_set_test.go @@ -25,7 +25,7 @@ import ( "github.com/openconfig/ondatra" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - otg "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ondatra/otg" "github.com/openconfig/ygnmi/ygnmi" "github.com/openconfig/ygot/ygot" ) @@ -190,7 +190,6 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { } func configurePrefixSet(t *testing.T, dut *ondatra.DUTDevice, prefixSet []*prefixSetPolicy) { - // configure prefix-sets d := &oc.Root{} rp := d.GetOrCreateRoutingPolicy() for _, ps := range prefixSet { @@ -298,7 +297,6 @@ func verifyBgpState(t *testing.T, dut *ondatra.DUTDevice) { t.Fatal("No BGP neighbor formed") } state, _ := status.Val() - t.Logf("BGP adjacency for %s: %v", nbr.nbrAddr, state) if want := oc.Bgp_Neighbor_SessionState_ESTABLISHED; state != want { t.Errorf("BGP peer %s status got %d, want %d", nbr.nbrAddr, state, want) } @@ -311,7 +309,7 @@ func configureOTG(t *testing.T, otg *otg.OTG) { port1 := config.Ports().Add().SetName("port1") port2 := config.Ports().Add().SetName("port2") - // Port1 Configuration. + // Port1 Configuration. Sets the ATE port iDut1Dev := config.Devices().Add().SetName(atePort1.Name) iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1.Name + ".Eth").SetMac(atePort1.MAC) iDut1Eth.Connection().SetPortName(port1.Name()) @@ -384,8 +382,9 @@ func validatePrefixCount(t *testing.T, dut *ondatra.DUTDevice, nbr bgpNeighbor, prefixPath := statePath.Neighbor(nbr.nbrAddr).AfiSafi(nbr.afiSafi).Prefixes() // Waiting for Installed count to get updated after session comes up or policy is applied - gotInstalled, ok := gnmi.Watch(t, dut, prefixPath.Installed().State(), 10*time.Second, func(val *ygnmi.Value[uint32]) bool { + gotInstalled, ok := gnmi.Watch(t, dut, prefixPath.Installed().State(), 20*time.Second, func(val *ygnmi.Value[uint32]) bool { // increased wait time to 20s from 10s gotInstalled, _ := val.Val() + t.Logf("Prefix that are installed %v and want %v", gotInstalled, wantInstalled) return gotInstalled == wantInstalled }).Await(t) if !ok { @@ -396,6 +395,7 @@ func validatePrefixCount(t *testing.T, dut *ondatra.DUTDevice, nbr bgpNeighbor, // Waiting for Received count to get updated after session comes up or policy is applied gotRx, ok := gnmi.Watch(t, dut, prefixPath.ReceivedPrePolicy().State(), 10*time.Second, func(val *ygnmi.Value[uint32]) bool { gotRx, _ := val.Val() + t.Logf("Prefix that are received %v and want %v", gotRx, wantRx) return gotRx == wantRx }).Await(t) if !ok { @@ -405,7 +405,9 @@ func validatePrefixCount(t *testing.T, dut *ondatra.DUTDevice, nbr bgpNeighbor, // Waiting for Sent count to get updated after session comes up or policy is applied gotSent, ok := gnmi.Watch(t, dut, prefixPath.Sent().State(), 10*time.Second, func(val *ygnmi.Value[uint32]) bool { + t.Logf("Prefix that are sent %v", prefixPath.Sent().State()) gotSent, _ := val.Val() + t.Logf("Prefix that are sent %v and want %v", gotSent, wantSent) return gotSent == wantSent }).Await(t) if !ok { @@ -424,20 +426,27 @@ func testPrefixSet(t *testing.T, dut *ondatra.DUTDevice) { }) // Associating prefix-set with the required routing-policy and applying to BGP neighbors on ATE-port-1 - t.Run("Validate acceptance based on prefix-set policy", func(t *testing.T) { + t.Run("Validate acceptance based on prefix-set policy - import policy on neighbor", func(t *testing.T) { applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet1V4, prefixSet2V4}, bgpImportIPv4, *ebgp1NbrV4, importPolicy) applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet1V6, prefixSet2V6}, bgpImportIPv6, *ebgp1NbrV6, importPolicy) - - // route1, route2, route4 expected to be accepted based on prefix-set - validatePrefixCount(t, dut, *ebgp1NbrV4, 3, 5, 0) - // only route6 is expected to accepted based on prefix-set - validatePrefixCount(t, dut, *ebgp1NbrV6, 1, 5, 0) - validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 0) - validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 0) + if !deviations.DefaultImportExportPolicy(dut) { + t.Logf("Validate for neighbour %v", ebgp1NbrV4) + validatePrefixCount(t, dut, *ebgp1NbrV4, 3, 5, 0) + validatePrefixCount(t, dut, *ebgp1NbrV6, 1, 5, 0) + validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 3) + validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 1) + } else { + t.Logf("Validate for neighbour %v", ebgp1NbrV4) + validatePrefixCount(t, dut, *ebgp1NbrV4, 3, 5, 0) + // only route6 is expected to accepted based on prefix-set + validatePrefixCount(t, dut, *ebgp1NbrV6, 1, 5, 0) + validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 0) + validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 0) + } }) // Associating prefix-set with the required routing-policy and applying to BGP neighbors on ATE-port-2 - t.Run("Validate advertise based on prefix-set policy", func(t *testing.T) { + t.Run("Validate advertise based on prefix-set policy - export policy on neighbor", func(t *testing.T) { applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet2V4}, bgpExportIPv4, *ebgp2NbrV4, !importPolicy) applyPrefixSetPolicy(t, dut, []*prefixSetPolicy{prefixSet1V6}, bgpExportIPv6, *ebgp2NbrV6, !importPolicy) @@ -467,13 +476,22 @@ func TestBGPPrefixSet(t *testing.T) { verifyBgpState(t, dut) }) - // Validate route count for BGP neighbors with default deny-all routing-policy - t.Run("Validate initial prefix count", func(t *testing.T) { - validatePrefixCount(t, dut, *ebgp1NbrV4, 0, 5, 0) - validatePrefixCount(t, dut, *ebgp1NbrV6, 0, 5, 0) - validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 0) - validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 0) - }) + if !deviations.DefaultImportExportPolicy(dut) { + t.Run("Validate initial prefix count", func(t *testing.T) { + validatePrefixCount(t, dut, *ebgp1NbrV4, 5, 5, 0) + validatePrefixCount(t, dut, *ebgp1NbrV6, 5, 5, 0) + validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 5) + validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 5) + }) + } else { + t.Run("Validate initial prefix count", func(t *testing.T) { + validatePrefixCount(t, dut, *ebgp1NbrV4, 0, 1, 0) + validatePrefixCount(t, dut, *ebgp1NbrV6, 0, 5, 0) + validatePrefixCount(t, dut, *ebgp2NbrV4, 0, 0, 0) + validatePrefixCount(t, dut, *ebgp2NbrV6, 0, 0, 0) + }) + + } testPrefixSet(t, dut) } diff --git a/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto b/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto index a4365e30d39..6b2bf873c36 100644 --- a/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/prefix_set_test/metadata.textproto @@ -27,6 +27,7 @@ platform_exceptions: { default_network_instance: "default" missing_value_for_defaults: true skip_set_rp_match_set_options: true + default_import_export_policy: false } } diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 23d10adcb3d..67d5c0f392a 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -912,6 +912,11 @@ func BgpCommunitySetRefsUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetBgpCommunitySetRefsUnsupported() } +// DefaultImportExportPolicy returns true when device does not have a default deny action in the absence of a route policy +func DefaultImportExportPolicy(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetDefaultImportExportPolicy() +} + // TableConnectionsUnsupported returns true if Table Connections are unsupported. func TableConnectionsUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetTableConnectionsUnsupported() diff --git a/proto/metadata.proto b/proto/metadata.proto index 6deb16752dd..5735220a367 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -483,9 +483,10 @@ message Metadata { bool use_vendor_native_tag_set_config = 171; // Skip setting send-community-type in bgp global config bool skip_bgp_send_community_type = 172; + // Device does not have a default deny action in the absence of a route policy + bool default_import_export_policy = 173; // Support for bgp actions set-community method - bool bgp_actions_set_community_method_unsupported = 173; - + bool bgp_actions_set_community_method_unsupported = 174; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 19b441813c3..f0bd72fe372 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v4.23.2 +// protoc-gen-go v1.33.0 +// protoc v3.21.12 // source: metadata.proto package metadata_go_proto @@ -764,8 +764,10 @@ type Metadata_Deviations struct { UseVendorNativeTagSetConfig bool `protobuf:"varint,171,opt,name=use_vendor_native_tag_set_config,json=useVendorNativeTagSetConfig,proto3" json:"use_vendor_native_tag_set_config,omitempty"` // Skip setting send-community-type in bgp global config SkipBgpSendCommunityType bool `protobuf:"varint,172,opt,name=skip_bgp_send_community_type,json=skipBgpSendCommunityType,proto3" json:"skip_bgp_send_community_type,omitempty"` + // Device does not have a default deny action in the absence of a route policy + DefaultImportExportPolicy bool `protobuf:"varint,173,opt,name=default_import_export_policy,json=defaultImportExportPolicy,proto3" json:"default_import_export_policy,omitempty"` // Support for bgp actions set-community method - BgpActionsSetCommunityMethodUnsupported bool `protobuf:"varint,173,opt,name=bgp_actions_set_community_method_unsupported,json=bgpActionsSetCommunityMethodUnsupported,proto3" json:"bgp_actions_set_community_method_unsupported,omitempty"` + BgpActionsSetCommunityMethodUnsupported bool `protobuf:"varint,174,opt,name=bgp_actions_set_community_method_unsupported,json=bgpActionsSetCommunityMethodUnsupported,proto3" json:"bgp_actions_set_community_method_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1892,6 +1894,13 @@ func (x *Metadata_Deviations) GetSkipBgpSendCommunityType() bool { return false } +func (x *Metadata_Deviations) GetDefaultImportExportPolicy() bool { + if x != nil { + return x.DefaultImportExportPolicy + } + return false +} + func (x *Metadata_Deviations) GetBgpActionsSetCommunityMethodUnsupported() bool { if x != nil { return x.BgpActionsSetCommunityMethodUnsupported @@ -1962,7 +1971,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfd, 0x61, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x62, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1996,7 +2005,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xd0, 0x59, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x92, 0x5a, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, @@ -2704,49 +2713,54 @@ var file_metadata_proto_rawDesc = []byte{ 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0xac, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x67, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x5e, 0x0a, 0x2c, 0x62, 0x67, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, - 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0xad, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x62, 0x67, 0x70, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, - 0x79, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, - 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, - 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, - 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x07, - 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, - 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, - 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, - 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, - 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, - 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, - 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, - 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, - 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, - 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, - 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, - 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x65, 0x12, 0x40, 0x0a, 0x1c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x18, 0xad, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x12, 0x5e, 0x0a, 0x2c, 0x62, 0x67, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, + 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x18, 0xae, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x62, 0x67, 0x70, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, + 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, + 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, + 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, + 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfa, 0x01, + 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, + 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, + 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, + 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, + 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, + 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, + 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, + 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( From 380361427788e5205457577ab256869a203ba5bf Mon Sep 17 00:00:00 2001 From: Octavian Petre <96260185+octpetre@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:54:05 -0400 Subject: [PATCH 89/97] OTG Test - TE-3.31: Hierarchical weight resolution with PBF (#2772) * initial copy * otg changes * added missing deviations to the metadata file * added changes from TE-3.3 --- .../README.md | 149 ++++ ...hierarchical_weight_resolution_pbf_test.go | 751 ++++++++++++++++++ .../metadata.textproto | 51 ++ 3 files changed, 951 insertions(+) create mode 100644 feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md create mode 100644 feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/hierarchical_weight_resolution_pbf_test.go create mode 100644 feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md new file mode 100644 index 00000000000..3dbc48f28fc --- /dev/null +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md @@ -0,0 +1,149 @@ +# TE-3.31: Hierarchical weight resolution with PBF + +## Summary + +Ensures that next-hop weights (for WCMP) are honored hierarchically in gRIBI +recursive resolution and traffic is load-shared according to these weights. + +## Procedure + +Configure ATE and DUT: + +* Connect ATE port-1 to DUT port-1. ATE port-2 to DUT port-2. + +* Create a non-default VRF (VRF-1) that contains no interfaces. + +* On DUT port-2 and ATE port-2 create 18 L3 sub-interfaces each with a /30 + subnet as below: + + * On DUT port-2, create subinterfaces with indices 1 to 18 mapped to VLAN + IDs 1 to 18 and corressponding IPv4 addresses 192.0.2.5, 192.0.2.9, ..., + 192.0.2.73 respectively. + + * On ATE port-2, create subinterfaces with indices 1 to 18 mapped to VLAN + IDs 1 to 18 and corresponding IPv4 addresses 192.0.2.6, 192.0.2.10, ..., + 192.0.2.74 and default gateways as 192.0.2.5, 192.0.2.9, ..., 192.0.2.73 + respectively. + +* On DUT port-1 and ATE port-1 create a single L3 interface. + +* On DUT, create a policy-based forwarding rule to redirect all traffic + received from DUT port-1 into VRF-1 (based on src. IP match criteria). + +* Add an empty decap VRF, `DECAP_TE_VRF`. + +* Add 4 empty encap VRFs, `ENCAP_TE_VRF_A`, `ENCAP_TE_VRF_B`, `ENCAP_TE_VRF_C` + and `ENCAP_TE_VRF_D`. + +* Replace the existing VRF selection policy with `vrf_selection_policy_w` as + in + +Test case for basic hierarchical weight: + +* Establish gRIBI client connection with DUT with PERSISTENCE, make it become + leader and install the following Entries: + + * IPv4Entry 203.0.113.0/32 in VRF-1, pointing to NextHopGroup(NHG#1) in + default VRF, with two NextHops(NH#1, NH#2) in default VRF: + + * NH#1 with weight:1, pointing to 192.0.2.111 + + * NH#2 with weight:3, pointing to 192.0.2.222 + + * IPv4Entry 192.0.2.111/32 in default VRF, pointing to NextHopGroup(NHG#2) + in default VRF, with two NextHops(NH#10, NH#11) in default VRF: + + * NH#10 with weight:1, pointing to 192.0.2.10 + + * NH#11 with weight:3, pointing to 192.0.2.14 + + * IPv4Entry 192.0.2.222/32 in default VRF, pointing to NextHopGroup(NHG#3) + in default VRF, with two NextHops(NH#100, NH#101) in default VRF: + + * NH#100 with weight:3, pointing to 192.0.2.18 + + * NH#101 with weight:5, pointing to 192.0.2.22 + +* Validate with traffic: + + * NH10: (1/4) * (1/4) = 6.25% traffic received by ATE port-2 VLAN 1 + + * NH11: (1/4) * (3/4) = 18.75% traffic received by ATE port-2 VLAN 2 + + * NH100: (3/4) * (3/8) = 28.12% traffic received by ATE port-2 VLAN 3 + + * NH101: (3/4) * (5/8) = 46.87% traffic received by ATE port-2 VLAN 4 + + * A tolerance of 0.2% is allowed for each VLAN for now, since we only test + for 2 mins. + +Test case for hierarchical weight in boundary scenarios, with maximum expected +WCMP width of 16 nexthops: + +* Flush previous gRIBI Entries for all NIs and establish a new connection with + DUT with PERSISTENCE and install the following Entries: + + * IPv4Entry 203.0.113.0/32 in VRF-1, pointing to NextHopGroup(NHG#1) in + default VRF, with two NextHops(NH#1, NH#2) in default VRF: + + * NH#1 with weight:1, pointing to 192.0.2.111 + + * NH#2 with weight:31, pointing to 192.0.2.222 + + * IPv4Entry 192.0.2.111/32 in default VRF, pointing to NextHopGroup(NHG#2) + in default VRF, with two NextHops(NH#10, NH#11) in default VRF: + + * NH#10 with weight:3, pointing to 192.0.2.10 + + * NH#11 with weight:5, pointing to 192.0.2.14 + + * IPv4Entry 192.0.2.222/32 in default VRF, pointing to NextHopGroup(NHG#3) + in default VRF, with 16 NextHops(NH#100, NH#101, ..., NH#115), all with + weight: 16 except NHG#100 is of weight 1, in default VRF: + + * NH#100 with weight:1, pointing to 192.0.2.18 + + * NH#101 with weight:16, pointing to 192.0.2.22 + + * ... + + * NH#115 with weight:16, pointing to 192.0.2.79 + +* Validate with traffic: + + * NH10: (1/32) * (3/8) ~ 1.171% traffic received by ATE port-2 VLAN 1 + + * NH11: (1/32) * (5/8) ~ 1.953% traffic received by ATE port-2 VLAN 2 + + * NH100: (31/32) * (1/241) ~ 0.402% traffic received by ATE port-2 VLAN 3 + + * for each VLAN ID in 4...18: + + * NH: (31/32) * (16/241) ~ 6.432% traffic received by ATE port-2 VLAN + ID + + * A tolerance of 0.2% is allowed for each VLAN for now, since we only test + for 2 mins. + +## Config Parameter Coverage + +N/A + +## Telemetry Parameter Coverage + +TODO: +/network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight + +## Protocol/RPC Parameter coverage + +* gRIBI: + * Modify() + * ModifyRequest: + * AFTOperation: + * next_hop_group + * NextHopGroupKey: id + * NextHopGroup: weight + +## Minimum DUT platform requirement + +vRX diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/hierarchical_weight_resolution_pbf_test.go b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/hierarchical_weight_resolution_pbf_test.go new file mode 100644 index 00000000000..2291b2aad96 --- /dev/null +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/hierarchical_weight_resolution_pbf_test.go @@ -0,0 +1,751 @@ +// Copyright 2022 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 hierarchical_weight_resolution_test implements TE-3.3 of the Popgate vendor testplan +package hierarchical_weight_resolution_pbf_test + +import ( + "bytes" + "context" + "encoding/binary" + "fmt" + "net" + "strconv" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "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/gribi" + "github.com/openconfig/featureprofiles/internal/otgutils" + "github.com/openconfig/featureprofiles/internal/vrfpolicy" + "github.com/openconfig/gribigo/chk" + "github.com/openconfig/gribigo/constants" + "github.com/openconfig/gribigo/fluent" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +type attributes struct { + attrs.Attributes + numSubIntf uint32 + ip func(vlan uint8) string + gateway func(vlan uint8) string +} + +type nhInfo struct { + index uint64 + weight uint64 +} + +const ( + ipv4EntryPrefix = "203.0.113.0/32" + ipv4FlowIP = "203.0.113.0" + innerSrcIPv4Start = "198.18.0.0" + innerDstIPv4Start = "198.19.0.0" + ipv4PrefixLen = 30 + ipv4FlowCount = 65000 + nhEntryIP1 = "192.0.2.111" + nhEntryIP2 = "192.0.2.222" + nonDefaultVRF = "TE_VRF_111" + policyName = "redirect-to-VRF1" + ipipProtocol = 4 + decapFlowSrc = "198.51.100.111" + dscpEncapA1 = 10 +) + +var ( + dutPort1 = attributes{ + Attributes: attrs.Attributes{ + Desc: "dutPort1", + Name: "port1", + IPv4: dutPort1IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 0, + ip: dutPort1IPv4, + } + + atePort1 = attributes{ + Attributes: attrs.Attributes{ + Name: "port1", + MAC: "02:00:01:01:01:01", + IPv4: atePort1IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 0, + ip: atePort1IPv4, + gateway: dutPort1IPv4, + } + + dutPort2 = attributes{ + Attributes: attrs.Attributes{ + Desc: "dutPort2", + Name: "port2", + IPv4: dutPort2IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 18, + ip: dutPort2IPv4, + } + + atePort2 = attributes{ + Attributes: attrs.Attributes{ + Name: "port2", + MAC: "02:00:02:01:01:01", + IPv4: atePort2IPv4(0), + IPv4Len: ipv4PrefixLen, + }, + numSubIntf: 18, + ip: atePort2IPv4, + gateway: dutPort2IPv4, + } + + // nhgIPv4EntryMap maps NextHopGroups to the ipv4 entries pointing to that NextHopGroup. + nhgIPv4EntryMap = map[uint64]string{ + 1: ipv4EntryPrefix, + 2: cidr(nhEntryIP1, 32), + 3: cidr(nhEntryIP2, 32), + } + // 'tolerance' is the maximum difference that is allowed between the observed + // traffic distribution and the required traffic distribution. + tolerance = 0.2 +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// dutPort1IPv4 returns ip address 192.0.2.1, for every vlanID. +func dutPort1IPv4(uint8) string { + return "192.0.2.1" +} + +// atePort1IPv4 returns ip address 192.0.2.2, for every vlanID +func atePort1IPv4(uint8) string { + return "192.0.2.2" +} + +// dutPort2IPv4 returns ip addresses starting 192.0.2.5, increasing by 4 +// for every vlanID. +func dutPort2IPv4(vlan uint8) string { + return fmt.Sprintf("192.0.2.%d", vlan*4+5) +} + +// atePort2IPv4 returns ip addresses starting 192.0.2.6, increasing by 4 +// for every vlanID. +func atePort2IPv4(vlan uint8) string { + return fmt.Sprintf("192.0.2.%d", vlan*4+6) +} + +// cidr taks as input the IPv4 address and the Mask and returns the IP string in +// CIDR notation. +func cidr(ipv4 string, ones int) string { + return ipv4 + "/" + strconv.Itoa(ones) +} + +// filterPacketReceived uses ATE:EgressTracking bucket counters to create a map +// with bucket-label as the Key and the percentage of packets-received for that +// bucket as the Value. +func filterPacketReceived(t *testing.T, flow string, ate *ondatra.ATEDevice) map[string]float64 { + t.Helper() + + // Check the egress packets + vlanTags := gnmi.GetAll(t, ate.OTG(), gnmi.OTG().Flow(flow).TaggedMetricAny().State()) + tags := gnmi.GetAll(t, ate.OTG(), gnmi.OTG().Flow(flow).TaggedMetricAny().TagsAny().State()) + t.Logf("There are a total of %v vlans", len(tags)) + + inPkts := map[string]uint64{} + for i, tag := range tags { + vlanHex := strings.Replace(tag.GetTagValue().GetValueAsHex(), "0x", "", -1) + vlanDec, _ := strconv.ParseUint(vlanHex, 16, 64) + inPkts[strconv.Itoa(int(vlanDec))] = vlanTags[i].GetCounters().GetInPkts() + } + inPct := map[string]float64{} + total := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow(flow).Counters().InPkts().State()) + for k, v := range inPkts { + inPct[k] = (float64(v) / float64(total)) * 100.0 + } + return inPct +} + +// configureGRIBIClient configures a new GRIBI client with PRESERVE and FIB_ACK. +func configureGRIBIClient(t *testing.T, dut *ondatra.DUTDevice) *fluent.GRIBIClient { + t.Helper() + gribic := dut.RawAPIs().GRIBI(t) + + // Configure the gRIBI client. + c := fluent.NewClient() + c.Connection(). + WithStub(gribic). + WithRedundancyMode(fluent.ElectedPrimaryClient). + WithInitialElectionID(1 /* low */, 0 /* hi */). + WithPersistence(). + WithFIBACK() + + return c +} + +// nextHopEntry configures a fluent.GRIBIEntry for a NextHopEntry. +func nextHopEntry(index uint64, networkInstance string, ipAddr string) fluent.GRIBIEntry { + return fluent.NextHopEntry(). + WithNetworkInstance(networkInstance). + WithIndex(index). + WithIPAddress(ipAddr) +} + +// nextHopGroupEntry configures a fluent.GRIBIEntry for a NextHopGroupEntry. +func nextHopGroupEntry(index uint64, networkInstance string, nhs []nhInfo) fluent.GRIBIEntry { + x := fluent.NextHopGroupEntry(). + WithNetworkInstance(networkInstance). + WithID(index) + for _, nh := range nhs { + x.AddNextHop(nh.index, nh.weight) + } + return x +} + +// ipv4Entry configures a fluent.GRIBIEntry for an IPv4Entry. +func ipv4Entry(prefix string, networkInstance string, nhgIndex uint64, nextHopGroupNetworkInstance string) fluent.GRIBIEntry { + return fluent.IPv4Entry(). + WithPrefix(prefix). + WithNetworkInstance(networkInstance). + WithNextHopGroup(nhgIndex). + WithNextHopGroupNetworkInstance(nextHopGroupNetworkInstance) +} + +// awaitTimeout calls a fluent client Await, adding a timeout to the context. +func awaitTimeout(ctx context.Context, c *fluent.GRIBIClient, t testing.TB, timeout time.Duration) error { + t.Helper() + subctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + return c.Await(subctx, t) +} + +// configSubinterfaceDUT configures the Sub Interfaces of an Interfaces, +// starting from Sub Interface 1. Each Subinterface is configured with a +// unique VlanID starting from 1 and an IP address. The starting IP Address +// for Subinterface(1) = dutPort.ip(1) = dutPort.ip + 4. +func (a *attributes) configSubinterfaceDUT(t *testing.T, intf *oc.Interface, dut *ondatra.DUTDevice) { + t.Helper() + if deviations.RequireRoutedSubinterface0(dut) { + s0 := intf.GetOrCreateSubinterface(0).GetOrCreateIpv4() + s0.Enabled = ygot.Bool(true) + } + for i := uint32(1); i <= a.numSubIntf; i++ { + ip := a.ip(uint8(i)) + + s := intf.GetOrCreateSubinterface(i) + if deviations.InterfaceEnabled(dut) { + s.Enabled = ygot.Bool(true) + } + if deviations.DeprecatedVlanID(dut) { + s.GetOrCreateVlan().VlanId = oc.UnionUint16(i) + } else { + s.GetOrCreateVlan().GetOrCreateMatch().GetOrCreateSingleTagged().VlanId = ygot.Uint16(uint16(i)) + } + s4 := s.GetOrCreateIpv4() + if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { + s4.Enabled = ygot.Bool(true) + } + s4a := s4.GetOrCreateAddress(ip) + s4a.PrefixLength = ygot.Uint8(a.IPv4Len) + t.Logf("Adding DUT Subinterface with ID: %d, Vlan ID: %d and IPv4 address: %s", i, i, ip) + } +} + +// configInterfaceDUT configures the DUT interface with the provided IP Address. +// Sub Interfaces are also configured if numSubIntf > 0. +func (a *attributes) configInterfaceDUT(t *testing.T, d *ondatra.DUTDevice) { + t.Helper() + p := d.Port(t, a.Name) + i := &oc.Interface{Name: ygot.String(p.Name())} + + if a.numSubIntf > 0 { + i.Description = ygot.String(a.Desc) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + if deviations.InterfaceEnabled(d) { + i.Enabled = ygot.Bool(true) + } + } else { + i = a.NewOCInterface(p.Name(), d) + } + + if deviations.ExplicitPortSpeed(d) { + i.GetOrCreateEthernet().PortSpeed = fptest.GetIfSpeed(t, p) + } + + a.configSubinterfaceDUT(t, i, d) + intfPath := gnmi.OC().Interface(p.Name()) + gnmi.Replace(t, d, intfPath.Config(), i) + fptest.LogQuery(t, "DUT", intfPath.Config(), gnmi.Get(t, d, intfPath.Config())) +} + +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + // configure NI. + configureNetworkInstance(t, dut) + + // Configure DUT ports. + dutPort1.configInterfaceDUT(t, dut) + dutPort2.configInterfaceDUT(t, dut) + + // assign subinterfaces to DEFAULT network instance if needed (deviation-based). + dutPort1.assignSubifsToDefaultNetworkInstance(t, dut) + dutPort2.assignSubifsToDefaultNetworkInstance(t, dut) + + // apply PBF to src interface. + dp1 := dut.Port(t, dutPort1.Name) + applyForwardingPolicy(t, dp1.Name()) +} + +// configureNetworkInstance creates and configures non-default and default NIs. +func configureNetworkInstance(t *testing.T, d *ondatra.DUTDevice) { + t.Helper() + + // configure non-default VRF + ni := &oc.NetworkInstance{ + Name: ygot.String(nonDefaultVRF), + Type: oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF, + } + dni := gnmi.OC().NetworkInstance(nonDefaultVRF) + gnmi.Replace(t, d, dni.Config(), ni) + fptest.LogQuery(t, "NI", dni.Config(), gnmi.Get(t, d, dni.Config())) + + // configure PBF in DEFAULT vrf + defNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(d)) + fptest.ConfigureDefaultNetworkInstance(t, d) + gnmi.Replace(t, d, defNIPath.PolicyForwarding().Config(), configurePBF(d)) + +} + +// assignSubifsToDefaultNetworkInstance assign subinterfaces to the default network instance when ExplicitInterfaceInDefaultVRF is enabled. +func (a *attributes) assignSubifsToDefaultNetworkInstance(t *testing.T, d *ondatra.DUTDevice) { + p := d.Port(t, a.Name) + if deviations.ExplicitInterfaceInDefaultVRF(d) { + if a.numSubIntf == 0 { + fptest.AssignToNetworkInstance(t, d, p.Name(), deviations.DefaultNetworkInstance(d), 0) + } else { + for i := uint32(1); i <= a.numSubIntf; i++ { + fptest.AssignToNetworkInstance(t, d, p.Name(), deviations.DefaultNetworkInstance(d), i) + } + } + } +} + +// configurePBF returns a fully configured network-instance PF struct. +func configurePBF(dut *ondatra.DUTDevice) *oc.NetworkInstance_PolicyForwarding { + d := &oc.Root{} + ni := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + pf := ni.GetOrCreatePolicyForwarding() + vrfPolicy := pf.GetOrCreatePolicy(policyName) + vrfPolicy.SetType(oc.Policy_Type_VRF_SELECTION_POLICY) + vrfPolicy.GetOrCreateRule(1).GetOrCreateIpv4().Protocol = oc.UnionUint8(ipipProtocol) + vrfPolicy.GetOrCreateRule(1).GetOrCreateAction().NetworkInstance = ygot.String(nonDefaultVRF) + return pf +} + +// applyForwardingPolicy applies the forwarding policy on the interface. +func applyForwardingPolicy(t *testing.T, ingressPort string) { + t.Logf("Applying forwarding policy on interface %v ... ", ingressPort) + d := &oc.Root{} + dut := ondatra.DUT(t, "dut") + interfaceID := ingressPort + if deviations.InterfaceRefInterfaceIDFormat(dut) { + interfaceID = ingressPort + ".0" + } + pfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding().Interface(interfaceID) + pfCfg := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)).GetOrCreatePolicyForwarding().GetOrCreateInterface(interfaceID) + pfCfg.ApplyVrfSelectionPolicy = ygot.String(policyName) + pfCfg.GetOrCreateInterfaceRef().Interface = ygot.String(ingressPort) + pfCfg.GetOrCreateInterfaceRef().Subinterface = ygot.Uint32(0) + if deviations.InterfaceRefConfigUnsupported(dut) { + pfCfg.InterfaceRef = nil + } + gnmi.Replace(t, dut, pfPath.Config(), pfCfg) +} + +// configureATE configures Ethernet + IPv4 on the ATE. If the number of +// Subinterfaces(numSubIntf) > 0, we then create additional sub-interfaces +// each with a unique VlanID starting from 1. The IPv4 addresses start with +// ATE:Port.IPv4 and then nextIP(ATE:Port.IPv4, 4) for each sub interface. +func (a *attributes) configureATE(t *testing.T, top gosnappi.Config, ate *ondatra.ATEDevice) { + t.Helper() + p := ate.Port(t, a.Name) + + // Configure source port on ATE : Port1. + + top.Ports().Add().SetName(p.ID()) + if a.numSubIntf == 0 { + ip := a.ip(0) + gateway := a.gateway(0) + dev := top.Devices().Add().SetName(a.Name) + eth := dev.Ethernets().Add().SetName(a.Name + ".Eth").SetMac(a.MAC) + eth.Connection().SetPortName(p.ID()) + ipObj := eth.Ipv4Addresses().Add().SetName(dev.Name() + ".IPv4") + ipObj.SetAddress(ip).SetGateway(gateway).SetPrefix(uint32(a.IPv4Len)) + t.Logf("Adding ATE Ipv4 address: %s with gateway: %s", cidr(ip, int(a.IPv4Len)), gateway) + } + // Configure destination port on ATE : Port2. + for i := uint32(1); i <= a.numSubIntf; i++ { + name := fmt.Sprintf(`dst%d`, i) + ip := a.ip(uint8(i)) + gateway := a.gateway(uint8(i)) + mac, err := incrementMAC(a.MAC, int(i)+1) + if err != nil { + t.Fatalf("Failed to generate mac address with error %s", err) + } + + dev := top.Devices().Add().SetName(name + ".Dev") + eth := dev.Ethernets().Add().SetName(name + ".Eth").SetMac(mac) + eth.Connection().SetPortName(p.ID()) + eth.Vlans().Add().SetName(name).SetId(uint32(i)) + eth.Ipv4Addresses().Add().SetName(name + ".IPv4").SetAddress(ip).SetGateway(gateway).SetPrefix(uint32(a.IPv4Len)) + + t.Logf("Adding ATE Ipv4 address: %s with gateway: %s and VlanID: %d", cidr(ip, 30), gateway, i) + } + // } +} + +// incrementMAC increments the MAC by i. Returns error if the mac cannot be parsed or overflows the mac address space +func incrementMAC(mac string, i int) (string, error) { + macAddr, err := net.ParseMAC(mac) + if err != nil { + return "", err + } + convMac := binary.BigEndian.Uint64(append([]byte{0, 0}, macAddr...)) + convMac = convMac + uint64(i) + buf := new(bytes.Buffer) + err = binary.Write(buf, binary.BigEndian, convMac) + if err != nil { + return "", err + } + newMac := net.HardwareAddr(buf.Bytes()[2:8]) + return newMac.String(), nil +} + +// testTraffic creates a traffic flow with ATE source & destination endpoints +// and configures a VlanID filter for output frames. The IPv4 header for the +// flow contains the ATE:Port1 address as source and the configured gRIBI- +// IndirectEntry as the destination. The function also takes as input a map of +// that is wanted and compares it to the actual +// traffic test result. +func testTraffic(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) map[string]float64 { + + dut := ondatra.DUT(t, "dut") + dstMac := gnmi.Get(t, dut, gnmi.OC().Interface(dut.Port(t, "port1").Name()).Ethernet().MacAddress().State()) + top.Flows().Clear().Items() + flowipv4 := top.Flows().Add().SetName("flow") + flowipv4.Metrics().SetEnable(true) + flowipv4.TxRx().Port().SetTxName(atePort1.Name).SetRxNames([]string{atePort2.Name}) + flowipv4.Size().SetFixed(100) + e1 := flowipv4.Packet().Add().Ethernet() + e1.Src().SetValue(atePort1.MAC) + e1.Dst().SetValue(dstMac) + v4 := flowipv4.Packet().Add().Ipv4() + v4.Src().SetValue(decapFlowSrc) + v4.Priority().Dscp().Phb().SetValue(dscpEncapA1) + v4.Dst().SetValue(ipv4FlowIP) + v4Inner := flowipv4.Packet().Add().Ipv4() + v4Inner.Src().Increment().SetStart(innerSrcIPv4Start).SetCount(ipv4FlowCount) + v4Inner.Dst().Increment().SetStart(innerDstIPv4Start).SetCount(ipv4FlowCount) + flowipv4.EgressPacket().Add().Ethernet() + vlan := flowipv4.EgressPacket().Add().Vlan() + vlanTag := vlan.Id().MetricTags().Add() + vlanTag.SetName("EgressVlanIdTrackingFlow") + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, ate.OTG(), top, "IPv4") + + // Run traffic for 2 minutes. + ate.OTG().StartTraffic(t) + time.Sleep(1 * time.Minute) + ate.OTG().StopTraffic(t) + + otgutils.LogFlowMetrics(t, ate.OTG(), top) + + recvMetric := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow(flowipv4.Name()).State()) + txPkts := float32(recvMetric.GetCounters().GetOutPkts()) + rxPkts := float32(recvMetric.GetCounters().GetInPkts()) + lossPct := (txPkts - rxPkts) * 100 / txPkts + if txPkts == 0 { + t.Fatalf("TxPkts == 0, want > 0.") + } + if lossPct > 0 && recvMetric.GetCounters().GetOutPkts() > 0 { + t.Fatalf("Loss Pct for %s got %v, want 0", flowipv4.Name(), lossPct) + } + + // Compare traffic distribution with the wanted results. + results := filterPacketReceived(t, "flow", ate) + t.Logf("Filters: %v", results) + return results +} + +// aftNextHopWeights queries AFT telemetry using Get() and returns +// the weights. If not-found, an empty list is returned. +func aftNextHopWeights(t *testing.T, dut *ondatra.DUTDevice, nhg uint64, networkInstance string) []uint64 { + aft := gnmi.Get(t, dut, gnmi.OC().NetworkInstance(networkInstance).Afts().State()) + var nhgD *oc.NetworkInstance_Afts_NextHopGroup + for _, nhgData := range aft.NextHopGroup { + if nhgData.GetProgrammedId() == nhg { + nhgD = nhgData + break + } + } + + if nhgD == nil { + return []uint64{} + } + + got := []uint64{} + for _, nhD := range nhgD.NextHop { + got = append(got, nhD.GetWeight()) + } + + return got +} + +// testBasicHierarchicalWeight tests and validates traffic through 4 Vlans. +func testBasicHierarchicalWeight(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice, + ate *ondatra.ATEDevice, top gosnappi.Config, gRIBI *fluent.GRIBIClient) { + defaultVRF := deviations.DefaultNetworkInstance(dut) + + // Set up NH#10, NH#11, NHG#2, IPv4Entry(192.0.2.111). + nh10 := nextHopEntry(10, defaultVRF, atePort2.ip(1)) + nh11 := nextHopEntry(11, defaultVRF, atePort2.ip(2)) + nhg2 := nextHopGroupEntry(2, defaultVRF, []nhInfo{{index: 10, weight: 1}, {index: 11, weight: 3}}) + ipEntry2 := ipv4Entry(nhgIPv4EntryMap[2], defaultVRF, 2, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh10, nh11, nhg2, ipEntry2) + + // Set up NH#100, NH#101, NHG#3, IPv4Entry(192.0.2.222). + nh100 := nextHopEntry(100, defaultVRF, atePort2.ip(3)) + nh101 := nextHopEntry(101, defaultVRF, atePort2.ip(4)) + nhg3 := nextHopGroupEntry(3, defaultVRF, []nhInfo{{index: 100, weight: 3}, {index: 101, weight: 5}}) + ipEntry3 := ipv4Entry(nhgIPv4EntryMap[3], defaultVRF, 3, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh100, nh101, nhg3, ipEntry3) + + // Set up NH#1, NH#2, NHG#1, IPv4Entry(198.18.196.1/22). + nh1 := nextHopEntry(1, defaultVRF, nhEntryIP1) + nh2 := nextHopEntry(2, defaultVRF, nhEntryIP2) + nhg1 := nextHopGroupEntry(1, defaultVRF, []nhInfo{{index: 1, weight: 1}, {index: 2, weight: 3}}) + ipEntry1 := ipv4Entry(nhgIPv4EntryMap[1], nonDefaultVRF, 1, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh1, nh2, nhg1, ipEntry1) + + if err := awaitTimeout(ctx, gRIBI, t, time.Minute); err != nil { + t.Fatalf("Could not program entries via gRIBI, got err: %v", err) + } + + // Validate entries were installed in FIB. + for _, route := range nhgIPv4EntryMap { + chk.HasResult(t, gRIBI.Results(t), + fluent.OperationResult(). + WithIPv4Operation(route). + WithOperationType(constants.Add). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + } + + // Test traffic flows correctly and + wantWeights := map[string]float64{ + "1": 6.25, + "2": 18.75, + "3": 28.12, + "4": 46.87, + } + t.Run("testTraffic", func(t *testing.T) { + got := testTraffic(t, ate, top) + if diff := cmp.Diff(wantWeights, got, cmpopts.EquateApprox(0, tolerance)); diff != "" { + t.Errorf("Packet distribution ratios -want,+got:\n%s", diff) + } + }) + + t.Run("validateAFTWeights", func(t *testing.T) { + for nhg, weights := range map[uint64][]uint64{ + 2: {1, 3}, + 3: {3, 5}, + } { + got := aftNextHopWeights(t, dut, nhg, defaultVRF) + ok := cmp.Equal(weights, got, cmpopts.SortSlices(func(a, b uint64) bool { return a < b })) + if !ok { + t.Errorf("Valid weights not present for NI: %s, NHG: %d, got: %v, want: %v", defaultVRF, nhg, got, weights) + } + } + }) + + // Flush gRIBI routes after test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Error(err) + } +} + +// testHierarchicalWeightBoundaryScenario tests and validates traffic through all 18 Vlans. +func testHierarchicalWeightBoundaryScenario(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice, + ate *ondatra.ATEDevice, top gosnappi.Config, gRIBI *fluent.GRIBIClient) { + defaultVRF := deviations.DefaultNetworkInstance(dut) + + // Set up NH#10, NH#11, NHG#2, IPv4Entry(192.0.2.111). + nh10 := nextHopEntry(10, defaultVRF, atePort2.ip(1)) + nh11 := nextHopEntry(11, defaultVRF, atePort2.ip(2)) + nhg2 := nextHopGroupEntry(2, defaultVRF, []nhInfo{{index: 10, weight: 3}, {index: 11, weight: 5}}) + ipEntry2 := ipv4Entry(nhgIPv4EntryMap[2], defaultVRF, 2, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh10, nh11, nhg2, ipEntry2) + + // Set up NH#100..NH#116, NHG#3, IPv4Entry(192.0.2.222). + nextHopWeights := []nhInfo{} + nhIdx := uint64(100) + gribiEntries := []fluent.GRIBIEntry{} + for i := 0; i < 16; i++ { + nh := nextHopEntry(nhIdx, defaultVRF, atePort2.ip(uint8(3+i))) + gribiEntries = append(gribiEntries, nh) + if i == 0 { + nextHopWeights = append(nextHopWeights, nhInfo{index: nhIdx, weight: 1}) + } else { + nextHopWeights = append(nextHopWeights, nhInfo{index: nhIdx, weight: 16}) + } + nhIdx++ + } + nhg3 := nextHopGroupEntry(3, defaultVRF, nextHopWeights) + ipEntry3 := ipv4Entry(nhgIPv4EntryMap[3], defaultVRF, 3, defaultVRF) + gribiEntries = append(gribiEntries, nhg3, ipEntry3) + + gRIBI.Modify().AddEntry(t, gribiEntries...) + + // Set up NH#1, NH#2, NHG#1, IPv4Entry(198.18.196.1/22). + nh1 := nextHopEntry(1, defaultVRF, nhEntryIP1) + nh2 := nextHopEntry(2, defaultVRF, nhEntryIP2) + nhg1 := nextHopGroupEntry(1, defaultVRF, []nhInfo{{index: 1, weight: 1}, {index: 2, weight: 31}}) + ipEntry1 := ipv4Entry(nhgIPv4EntryMap[1], nonDefaultVRF, 1, defaultVRF) + + gRIBI.Modify().AddEntry(t, nh1, nh2, nhg1, ipEntry1) + + if err := awaitTimeout(ctx, gRIBI, t, time.Minute); err != nil { + t.Fatalf("Could not program entries via gRIBI, got err: %v", err) + } + + // Validate entries were installed in FIB. + for _, route := range nhgIPv4EntryMap { + chk.HasResult(t, gRIBI.Results(t), + fluent.OperationResult(). + WithIPv4Operation(route). + WithOperationType(constants.Add). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + } + + wantWeights := map[string]float64{ + "1": 1.171, + "2": 1.953, + "3": 0.402, + } + // 6.432 weight for vlans 4 to 18. + for i := 4; i <= 18; i++ { + wantWeights[strconv.Itoa(i)] = 6.432 + } + t.Run("testTraffic", func(t *testing.T) { + got := testTraffic(t, ate, top) + + if deviations.HierarchicalWeightResolutionTolerance(dut) != tolerance { + tolerance = deviations.HierarchicalWeightResolutionTolerance(dut) + } + if diff := cmp.Diff(wantWeights, got, cmpopts.EquateApprox(0, tolerance)); diff != "" { + t.Errorf("Packet distribution ratios -want,+got:\n%s", diff) + } + }) + + t.Run("validateAFTWeights", func(t *testing.T) { + for nhg, weights := range map[uint64][]uint64{ + 2: {3, 5}, + 3: {1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}, + } { + got := aftNextHopWeights(t, dut, nhg, defaultVRF) + ok := cmp.Equal(weights, got, cmpopts.SortSlices(func(a, b uint64) bool { return a < b })) + if !ok { + t.Errorf("Valid weights not present for NI: %s, NHG: %d, got: %v, want: %v", defaultVRF, nhg, got, weights) + } + } + }) + + // Flush gRIBI routes after test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Error(err) + } +} + +func TestHierarchicalWeightResolution(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + ctx := context.Background() + + // Configure ATE ports and start Ethernet+IPv4. + top := gosnappi.NewConfig() + atePort1.configureATE(t, top, ate) + atePort2.configureATE(t, top, ate) + + ate.OTG().PushConfig(t, top) + + // configure DUT. + configureDUT(t, dut) + + ate.OTG().StartProtocols(t) + + // Configure gRIBI with FIB_ACK. + gRIBI := configureGRIBIClient(t, dut) + + gRIBI.Start(ctx, t) + defer gRIBI.Stop(t) + + defer func() { + // Flush all gRIBI routes after test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Error(err) + } + }() + + gRIBI.StartSending(ctx, t) + if err := awaitTimeout(ctx, gRIBI, t, time.Minute); err != nil { + t.Fatalf("Await got error during session negotiation for gRIBI: %v", err) + } + gribi.BecomeLeader(t, gRIBI) + + // Flush existing gRIBI routes before test. + if err := gribi.FlushAll(gRIBI); err != nil { + t.Fatal(err) + } + + t.Run("TestBasicHierarchicalWeightWithVrfPolW", func(t *testing.T) { + vrfpolicy.ConfigureVRFSelectionPolicyW(t, dut) + testBasicHierarchicalWeight(ctx, t, dut, ate, top, gRIBI) + }) + + t.Run("TestHierarchicalWeightBoundaryScenarioWithVrfPolW", func(t *testing.T) { + vrfpolicy.ConfigureVRFSelectionPolicyW(t, dut) + testHierarchicalWeightBoundaryScenario(ctx, t, dut, ate, top, gRIBI) + }) + + ate.OTG().StopProtocols(t) +} diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto new file mode 100644 index 00000000000..f64bcea4013 --- /dev/null +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto @@ -0,0 +1,51 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "bf5df0ee-79b7-460b-8146-3a1351fd56d7" +plan_id: "TE-3.31" +description: "Hierarchical weight resolution with PBF" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + hierarchical_weight_resolution_tolerance: 1.5 + ipv4_missing_enabled: true + interface_ref_interface_id_format: true + pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true + } +} +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + hierarchical_weight_resolution_tolerance: 0.4 + explicit_interface_ref_definition: true + } +} +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_interface_ref_definition: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + interface_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + deprecated_vlan_id: true + interface_enabled: true + default_network_instance: "default" + } +} +tags: TAGS_DATACENTER_EDGE From b9729afe209807245761ac5bfa41db7ef88f8c89 Mon Sep 17 00:00:00 2001 From: Prem Singh <94350992+singh-prem@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:12:14 +0530 Subject: [PATCH 90/97] TE-16.1 Basic Encap Test - fix for using l2 rules and sequenceID (#2885) * fixing issues * added deviation for sequential rules under policy * added vendor.CISCO check in PMD check --- .../basic_encap_test/basic_encap_test.go | 29 ++++++++++++++----- .../basic_encap_test/metadata.textproto | 1 + 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go index 66b26e27181..a9d33bea3e2 100644 --- a/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go +++ b/feature/gribi/otg_tests/basic_encap_test/basic_encap_test.go @@ -104,6 +104,7 @@ const ( // observing on IXIA OTG: Cannot start capture on more than one port belonging to the // same resource group or on more than one port behind the same front panel port in the chassis otgMutliPortCaptureSupported = false + seqIDBase = uint32(10) ) var ( @@ -588,6 +589,16 @@ func getPbrRules(dut *ondatra.DUTDevice, clusterFacing bool) []pbrRule { return pbrRules } +// seqIDOffset returns sequence ID offset added with seqIDBase (10), to avoid sequences +// like 1, 10, 11, 12,..., 2, 21, 22, ... while being sent by Ondatra to the DUT. +// It now generates sequences like 11, 12, 13, ..., 19, 20, 21,..., 99. +func seqIDOffset(dut *ondatra.DUTDevice, i uint32) uint32 { + if deviations.PfRequireSequentialOrderPbrRules(dut) { + return i + seqIDBase + } + return i +} + // configDefaultRoute configures a static route in DEFAULT network-instance. func configDefaultRoute(t *testing.T, dut *ondatra.DUTDevice, v4Prefix, v4NextHop, v6Prefix, v6NextHop string) { t.Logf("Configuring static route in DEFAULT network-instance") @@ -630,7 +641,7 @@ func getPbrPolicy(dut *ondatra.DUTDevice, name string, clusterFacing bool) *oc.N p.SetType(oc.Policy_Type_VRF_SELECTION_POLICY) for _, pRule := range getPbrRules(dut, clusterFacing) { - r := p.GetOrCreateRule(pRule.sequence) + r := p.GetOrCreateRule(seqIDOffset(dut, pRule.sequence)) r4 := r.GetOrCreateIpv4() if pRule.dscpSet != nil { @@ -654,6 +665,11 @@ func getPbrPolicy(dut *ondatra.DUTDevice, name string, clusterFacing bool) *oc.N ra.PostDecapNetworkInstance = ygot.String(pRule.decapVrfSet[1]) ra.DecapFallbackNetworkInstance = ygot.String(pRule.decapVrfSet[2]) } + if deviations.PfRequireMatchDefaultRule(dut) { + if pRule.etherType != nil { + r.GetOrCreateL2().Ethertype = pRule.etherType + } + } if pRule.encapVrf != "" { r.GetOrCreateAction().SetNetworkInstance(pRule.encapVrf) @@ -775,7 +791,7 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { for idx, a := range []attrs.Attributes{dutPort1, dutPort2, dutPort3, dutPort4, dutPort5} { p := portList[idx] intf := a.NewOCInterface(p.Name(), dut) - if p.PMD() == ondatra.PMD100GBASEFR { + if p.PMD() == ondatra.PMD100GBASEFR && dut.Vendor() != ondatra.CISCO { e := intf.GetOrCreateEthernet() e.AutoNegotiate = ygot.Bool(false) e.DuplexMode = oc.Ethernet_DuplexMode_FULL @@ -896,9 +912,6 @@ func (fa *flowAttr) getFlow(flowType string, name string, dscp uint32) gosnappi. v4.Dst().SetValue(fa.dst) v4.TimeToLive().SetValue(ttl) v4.Priority().Dscp().Phb().SetValue(dscp) - udp := flow.Packet().Add().Udp() - udp.SrcPort().SetValues(randRange(50001, 10000)) - udp.DstPort().SetValues(randRange(50001, 10000)) // add inner ipv4 headers if flowType == "ipv4in4" { @@ -919,10 +932,10 @@ func (fa *flowAttr) getFlow(flowType string, name string, dscp uint32) gosnappi. v6.Dst().SetValue(fa.dst) v6.HopLimit().SetValue(ttl) v6.TrafficClass().SetValue(dscp << 2) - udp := flow.Packet().Add().Udp() - udp.SrcPort().SetValues(randRange(50001, 10000)) - udp.DstPort().SetValues(randRange(50001, 10000)) } + udp := flow.Packet().Add().Udp() + udp.SrcPort().SetValues(randRange(50001, 10000)) + udp.DstPort().SetValues(randRange(50001, 10000)) return flow } diff --git a/feature/gribi/otg_tests/basic_encap_test/metadata.textproto b/feature/gribi/otg_tests/basic_encap_test/metadata.textproto index 8170adcc237..adf9ef8379d 100644 --- a/feature/gribi/otg_tests/basic_encap_test/metadata.textproto +++ b/feature/gribi/otg_tests/basic_encap_test/metadata.textproto @@ -15,6 +15,7 @@ platform_exceptions: { interface_ref_interface_id_format: true ttl_copy_unsupported: true pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true } } platform_exceptions: { From f48bf369191dac5042c6312066c776c519a166b3 Mon Sep 17 00:00:00 2001 From: dipchauh <159579776+dipchauh@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:35:55 -0400 Subject: [PATCH 91/97] Authz fixes (#2877) "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --- .../gnsi/authz/tests/authz/authz1_4_test.go | 49 ++++++++++--------- internal/security/gnxi/rpcexec.go | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/feature/security/gnsi/authz/tests/authz/authz1_4_test.go b/feature/security/gnsi/authz/tests/authz/authz1_4_test.go index 579a8c7710e..ec6f2008aa6 100644 --- a/feature/security/gnsi/authz/tests/authz/authz1_4_test.go +++ b/feature/security/gnsi/authz/tests/authz/authz1_4_test.go @@ -206,7 +206,7 @@ func TestAuthz1(t *testing.T) { // Pre-Test Section _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-everyone-can-gnmi-not-gribi"] @@ -229,7 +229,7 @@ func TestAuthz1(t *testing.T) { // Pre-Test Section _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-everyone-can-gribi-not-gnmi"] @@ -252,7 +252,7 @@ func TestAuthz1(t *testing.T) { dut := ondatra.DUT(t, "dut") _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate - 1 newpolicy, ok := policyMap["policy-gribi-get"] @@ -274,7 +274,7 @@ func TestAuthz1(t *testing.T) { } newpolicy.AddAllowRules("base", []string{*testInfraID}, []*gnxi.RPC{gnxi.RPCs.AllRPC}) // Rotate the policy. - newpolicy.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + newpolicy.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Verification of Policy for read-only to deny gRIBI Get and allow gNMI Get t.Run("Verification of Policy for read-only to deny gRIBI Get and allow gNMI Get", func(t *testing.T) { @@ -287,7 +287,7 @@ func TestAuthz1(t *testing.T) { // Pre-Test Section _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-normal-1"] @@ -313,7 +313,7 @@ func TestAuthz2(t *testing.T) { // Pre-Test Section _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-everyone-can-gnmi-not-gribi"] @@ -334,7 +334,7 @@ func TestAuthz2(t *testing.T) { autzRotateReq := &authzpb.RotateAuthzRequest_UploadRequest{ UploadRequest: &authzpb.UploadRequest{ Version: fmt.Sprintf("v0.%v", (time.Now().UnixNano())), - CreatedOn: uint64(time.Now().UnixMilli()), + CreatedOn: uint64(time.Now().Unix()), Policy: string(jsonPolicy), }, } @@ -348,9 +348,9 @@ func TestAuthz2(t *testing.T) { t.Fatalf("Error while receiving rotate request reply (client 1) %v", err) } // Rotate Request 2 - Before Finalizing the Request 1 - newpolicy, ok = policyMap["policy-everyone-can-gnmi-not-gribi"] + newpolicy, ok = policyMap["policy-everyone-can-gribi-not-gnmi"] if !ok { - t.Fatal("Policy policy-everyone-can-gnmi-not-gribi is not loaded from policy json file") + t.Fatal("Policy policy-everyone-can-gribi-not-gnmi is not loaded from policy json file") } newpolicy.AddAllowRules("base", []string{*testInfraID}, []*gnxi.RPC{gnxi.RPCs.AllRPC}) jsonPolicy, err = newpolicy.Marshal() @@ -365,7 +365,7 @@ func TestAuthz2(t *testing.T) { autzRotateReq = &authzpb.RotateAuthzRequest_UploadRequest{ UploadRequest: &authzpb.UploadRequest{ Version: fmt.Sprintf("v0.%v", (time.Now().UnixNano())), - CreatedOn: uint64(time.Now().UnixMilli()), + CreatedOn: uint64(time.Now().Unix()), Policy: string(jsonPolicy), }, } @@ -390,7 +390,7 @@ func TestAuthz2(t *testing.T) { // Pre-Test Section _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-gribi-get"] @@ -399,7 +399,7 @@ func TestAuthz2(t *testing.T) { } newpolicy.AddAllowRules("base", []string{*testInfraID}, []*gnxi.RPC{gnxi.RPCs.AllRPC}) // Rotate the policy. - newpolicy.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + newpolicy.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Verification of Policy for read_only to allow gRIBI Get and to deny gNMI Get t.Run("Verification of Policy for read_only to allow gRIBI Get and to deny gNMI Get", func(t *testing.T) { @@ -425,7 +425,7 @@ func TestAuthz2(t *testing.T) { autzRotateReq := &authzpb.RotateAuthzRequest_UploadRequest{ UploadRequest: &authzpb.UploadRequest{ Version: fmt.Sprintf("v0.%v", (time.Now().UnixNano())), - CreatedOn: uint64(time.Now().UnixMilli()), + CreatedOn: uint64(time.Now().Unix()), Policy: string(jsonPolicy), }, } @@ -459,7 +459,7 @@ func TestAuthz2(t *testing.T) { // Pre-Test Section _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-gribi-get"] @@ -468,7 +468,7 @@ func TestAuthz2(t *testing.T) { } newpolicy.AddAllowRules("base", []string{*testInfraID}, []*gnxi.RPC{gnxi.RPCs.AllRPC}) // Rotate the policy. - newpolicy.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + newpolicy.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Verification of Policy for read_only to allow gRIBI Get and to deny gNMI Get t.Run("Verification of Policy for read_only to allow gRIBI Get and to deny gNMI Get", func(t *testing.T) { @@ -495,7 +495,7 @@ func TestAuthz2(t *testing.T) { autzRotateReq := &authzpb.RotateAuthzRequest_UploadRequest{ UploadRequest: &authzpb.UploadRequest{ Version: fmt.Sprintf("v0.%v", (time.Now().UnixNano())), - CreatedOn: uint64(time.Now().UnixMilli()), + CreatedOn: uint64(time.Now().Unix()), Policy: string(jsonPolicy), }, } @@ -527,7 +527,7 @@ func TestAuthz2(t *testing.T) { // Pre-Test Section _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-gribi-get"] @@ -537,7 +537,7 @@ func TestAuthz2(t *testing.T) { newpolicy.AddAllowRules("base", []string{*testInfraID}, []*gnxi.RPC{gnxi.RPCs.AllRPC}) // Rotate the policy. prevVersion := fmt.Sprintf("v0.%v", (time.Now().UnixNano())) - newpolicy.Rotate(t, dut, uint64(time.Now().UnixMilli()), prevVersion, false) + newpolicy.Rotate(t, dut, uint64(time.Now().Unix()), prevVersion, false) newpolicy, ok = policyMap["policy-gnmi-get"] if !ok { @@ -556,7 +556,7 @@ func TestAuthz2(t *testing.T) { autzRotateReq := &authzpb.RotateAuthzRequest_UploadRequest{ UploadRequest: &authzpb.UploadRequest{ Version: prevVersion, - CreatedOn: uint64(time.Now().UnixMilli()), + CreatedOn: uint64(time.Now().Unix()), Policy: string(jsonPolicy), }, } @@ -576,7 +576,7 @@ func TestAuthz2(t *testing.T) { }) t.Logf("Preforming Rotate with the same version with force overwrite\n") - newpolicy.Rotate(t, dut, uint64(time.Now().UnixMilli()), prevVersion, true) + newpolicy.Rotate(t, dut, uint64(time.Now().Unix()), prevVersion, true) // Verification of Policy for read_only to allow gRIBI Get and to deny gNMI Get t.Run("Verification of Policy for read_only to allow gRIBI Get and to deny gNMI Get after rotate wth force overwrite", func(t *testing.T) { authz.Verify(t, dut, spiffeCertReadOnly, gnxi.RPCs.GribiGet, &authz.ExceptDeny{}, &authz.HardVerify{}) @@ -593,7 +593,7 @@ func TestAuthz3(t *testing.T) { setUpBaseline(t, dut) _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Rotate Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy object. newpolicy, ok := policyMap["policy-gribi-get"] @@ -603,7 +603,7 @@ func TestAuthz3(t *testing.T) { // Attach base Admin Policy // Rotate the policy. newpolicy.AddAllowRules("base", []string{*testInfraID}, []*gnxi.RPC{gnxi.RPCs.AllRPC}) - expCreatedOn := uint64(time.Now().UnixMilli()) + expCreatedOn := uint64(time.Now().Unix()) expVersion := fmt.Sprintf("v0.%v", (time.Now().UnixNano())) newpolicy.Rotate(t, dut, expCreatedOn, expVersion, false) t.Logf("New Rotated Authz Policy is %s", newpolicy.PrettyPrint(t)) @@ -635,9 +635,10 @@ func TestAuthz3(t *testing.T) { func TestAuthz4(t *testing.T) { // Pre-Test Section dut := ondatra.DUT(t, "dut") + setUpBaseline(t, dut) _, policyBefore := authz.Get(t, dut) t.Logf("Authz Policy of the Device %s before the Reboot Trigger is %s", dut.Name(), policyBefore.PrettyPrint(t)) - defer policyBefore.Rotate(t, dut, uint64(time.Now().UnixMilli()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) + defer policyBefore.Rotate(t, dut, uint64(time.Now().Unix()), fmt.Sprintf("v0.%v", (time.Now().UnixNano())), false) // Fetch the Desired Authorization Policy and Attach base Admin Policy Before Rotate newpolicy, ok := policyMap["policy-normal-1"] @@ -645,7 +646,7 @@ func TestAuthz4(t *testing.T) { t.Fatal("Policy policy-normal-1 is not loaded from policy json file") } newpolicy.AddAllowRules("base", []string{*testInfraID}, []*gnxi.RPC{gnxi.RPCs.AllRPC}) - expCreatedOn := uint64(time.Now().UnixMilli()) + expCreatedOn := uint64(time.Now().Unix()) expVersion := fmt.Sprintf("v0.%v", (time.Now().UnixNano())) t.Logf("New Authz Policy is %s", newpolicy.PrettyPrint(t)) newpolicy.Rotate(t, dut, expCreatedOn, expVersion, false) diff --git a/internal/security/gnxi/rpcexec.go b/internal/security/gnxi/rpcexec.go index 9cf326f7fd5..f91274b8633 100644 --- a/internal/security/gnxi/rpcexec.go +++ b/internal/security/gnxi/rpcexec.go @@ -507,7 +507,7 @@ func GnsiAuthzRotate(ctx context.Context, dut *ondatra.DUTDevice, opts []grpc.Di } _, err = gnsiCStream.Recv() // invalid policy is expected since the empty policy is not allowed - if strings.Contains(err.Error(), "invalid policy") { + if strings.Contains(err.Error(), "invalid policy") || status.Code(err) == codes.InvalidArgument { return nil } return err From 6ed7f418b28eb9e81a2261f7d0a987952a76fefd Mon Sep 17 00:00:00 2001 From: NishaSadhasivam-work Date: Wed, 24 Apr 2024 22:16:51 +0530 Subject: [PATCH 92/97] [NOKIA][FNT] Test is failing due to mac resolution on otg is failing (#2909) --- feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go b/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go index ba98e083401..2e8e158c370 100644 --- a/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go +++ b/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go @@ -432,6 +432,7 @@ func TestBurstyTraffic(t *testing.T) { t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) t.Logf("Running traffic 2 on DUT interfaces: %s => %s ", dp2.Name(), dp3.Name()) t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) + time.Sleep(30 * time.Second) ate.OTG().StartTraffic(t) time.Sleep(30 * time.Second) ate.OTG().StopTraffic(t) From a409b1405eb8b492d776654d29806919bd69ee6d Mon Sep 17 00:00:00 2001 From: jasdeep-hundal Date: Wed, 24 Apr 2024 11:05:25 -0700 Subject: [PATCH 93/97] Remove next set of converted ATE tests (#2917) All removed tests have had OTG versions merged/validated > 1 month ago. --- .../ate_tests/bgp_2byte_4byte_asn/README.md | 29 - .../bgp_2byte_4byte_asn_test.go | 253 --------- .../bgp_2byte_4byte_asn/metadata.textproto | 29 - .../bgp_2byte_4byte_asn_policy_test/README.md | 34 -- .../bgp_2byte_4byte_asn_policy_test.go | 499 ------------------ .../metadata.textproto | 38 -- .../ate_tests/bgp_remove_private_as/README.md | 41 -- .../bgp_remove_private_as_test.go | 394 -------------- .../bgp_remove_private_as/metadata.textproto | 24 - .../README.md | 55 -- ...configuration_convergence_time_bgp_test.go | 367 ------------- ...onfiguration_convergence_time_isis_test.go | 150 ------ .../metadata.textproto | 43 -- 13 files changed, 1956 deletions(-) delete mode 100644 feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/README.md delete mode 100644 feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go delete mode 100644 feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/metadata.textproto delete mode 100644 feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md delete mode 100644 feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go delete mode 100644 feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto delete mode 100644 feature/experimental/bgp/ate_tests/bgp_remove_private_as/README.md delete mode 100644 feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go delete mode 100644 feature/experimental/bgp/ate_tests/bgp_remove_private_as/metadata.textproto delete mode 100644 feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/README.md delete mode 100644 feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go delete mode 100644 feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go delete mode 100644 feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/metadata.textproto diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/README.md b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/README.md deleted file mode 100644 index 724e759f578..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# RT-1.19: BGP 2-Byte and 4-Byte ASN support - -## Summary - -BGP 2-Byte and 4-Byte ASN support - -## Procedure - -* Establish BGP sessions as follows and verify all the sessions are established - * ATE (2-byte) - DUT (4-byte) - eBGP IPv4 with ASN < 65535 on DUT side - * ATE (2-byte) - DUT (4-byte) - eBGP IPv6 with ASN < 65535 on DUT side - * ATE (4-byte) - DUT (4-byte) - eBGP IPv4 - * ATE (4-byte) - DUT (4-byte) - eBGP IPv6 - * ATE (2-byte) - DUT (4-byte) - iBGP IPv4 with ASN < 65535 on DUT side - * ATE (4-byte) - DUT (4-byte) - iBGP IPv6 with ASN < 65535 on DUT side - * ATE (4-byte) - DUT (4-byte) - iBGP IPv4 - * ATE (4-byte) - DUT (4-byte) - iBGP IPv6 - -## Config Parameter Coverage - -* /global/config/as -* /neighbors/neighbor/config/peer-as -* /neighbors/neighbor/config/local-as - -## Telemetry Parameter Coverage - -* /global/config/as -* /neighbors/neighbor/config/peer-as -* /neighbors/neighbor/config/local-as diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go deleted file mode 100644 index af656255725..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2023 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 bgp_2byte_4byte_asn_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" -) - -const ( - connInternal = "INTERNAL" - connExternal = "EXTERNAL" -) - -var ( - dutSrc = attrs.Attributes{ - Desc: "DUT to ATE source", - IPv4: "192.0.2.1", - IPv6: "2001:db8::192:0:2:1", - IPv4Len: 30, - IPv6Len: 126, - } - ateSrc = attrs.Attributes{ - Name: "ateSrc", - IPv4: "192.0.2.2", - IPv6: "2001:db8::192:0:2:2", - IPv4Len: 30, - IPv6Len: 126, - } -) - -type bgpNbr struct { - globalAS, localAS, peerAS uint32 - peerIP string - isV4 bool -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -func TestBgpSession(t *testing.T) { - t.Log("Configure DUT interface") - dut := ondatra.DUT(t, "dut") - dc := gnmi.OC() - i1 := dutSrc.NewOCInterface(dut.Port(t, "port1").Name(), dut) - gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, i1.GetName(), deviations.DefaultNetworkInstance(dut), 0) - } - - t.Log("Configure Network Instance") - dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) - gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) - - dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - - cases := []struct { - name string - nbr *bgpNbr - dutConf *oc.NetworkInstance_Protocol - ateConf *ondatra.ATETopology - }{ - { - name: "Establish eBGP connection between ATE (2-byte) - DUT (4-byte < 65535) for ipv4 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 100, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 100, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 200, peerIP: dutSrc.IPv4, peerAS: 100, isV4: true}, connExternal), - }, { - name: "Establish eBGP connection between ATE (2-byte) - DUT (4-byte < 65535) for ipv6 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 100, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 100, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 200, peerIP: dutSrc.IPv6, peerAS: 100, isV4: false}, connExternal), - }, { - name: "Establish eBGP connection between ATE (4-byte) - DUT (4-byte) for ipv4 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 70000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 70000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 80000, peerIP: dutSrc.IPv4, peerAS: 70000, isV4: true}, connExternal), - }, { - name: "Establish eBGP connection between ATE (4-byte) - DUT (4-byte) for ipv6 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 70000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 70000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 80000, peerIP: dutSrc.IPv6, peerAS: 70000, isV4: false}, connExternal), - }, { - name: "Establish iBGP connection between ATE (2-byte) - DUT (4-byte < 65535) for ipv4 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 200, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 200, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 200, peerIP: dutSrc.IPv4, peerAS: 200, isV4: true}, connInternal), - }, { - name: "Establish iBGP connection between ATE (4-byte) - DUT (4-byte < 65535) for ipv6 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 200, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 200, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 200, peerIP: dutSrc.IPv6, peerAS: 200, isV4: false}, connInternal), - }, { - name: "Establish iBGP connection between ATE (4-byte) - DUT (4-byte) for ipv4 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 80000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 80000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 80000, peerIP: dutSrc.IPv4, peerAS: 80000, isV4: true}, connInternal), - }, { - name: "Establish iBGP connection between ATE (4-byte) - DUT (4-byte) for ipv6 peers", - nbr: &bgpNbr{globalAS: 300, localAS: 80000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: false}, - dutConf: createBgpNeighbor(&bgpNbr{globalAS: 300, localAS: 80000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{globalAS: 300, localAS: 80000, peerIP: dutSrc.IPv6, peerAS: 80000, isV4: false}, connInternal), - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - t.Log("Clear BGP Configs on DUT") - bgpClearConfig(t, dut) - - t.Log("Configure BGP on DUT") - gnmi.Replace(t, dut, dutConfPath.Config(), tc.dutConf) - - fptest.LogQuery(t, "DUT BGP Config ", dutConfPath.Config(), gnmi.Get(t, dut, dutConfPath.Config())) - t.Log("Configure BGP on ATE") - tc.ateConf.Push(t) - tc.ateConf.StartProtocols(t) - - t.Log("Verify BGP session state : ESTABLISHED") - nbrPath := statePath.Neighbor(tc.nbr.peerIP) - gnmi.Await(t, dut, nbrPath.SessionState().State(), time.Second*60, oc.Bgp_Neighbor_SessionState_ESTABLISHED) - - t.Log("Verify BGP AS numbers") - verifyPeer(t, tc.nbr, dut) - - t.Log("Clear BGP Configs on ATE") - tc.ateConf.StopProtocols(t) - }) - } -} - -// bgpClearConfig removes all BGP configuration from the DUT. -func bgpClearConfig(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - resetBatch := &gnmi.SetBatch{} - gnmi.BatchDelete(resetBatch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config()) - - if deviations.NetworkInstanceTableDeletionRequired(dut) { - tablePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).TableAny() - for _, table := range gnmi.LookupAll(t, dut, tablePath.Config()) { - if val, ok := table.Val(); ok { - if val.GetProtocol() == oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP { - gnmi.BatchDelete(resetBatch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Table(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, val.GetAddressFamily()).Config()) - } - } - } - } - resetBatch.Set(t, dut) -} - -func verifyPeer(t *testing.T, nbr *bgpNbr, dut *ondatra.DUTDevice) { - t.Helper() - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - nbrPath := statePath.Neighbor(nbr.peerIP) - glblPath := statePath.Global() - - // Check BGP peerAS from telemetry. - peerAS := gnmi.Get(t, dut, nbrPath.State()).GetPeerAs() - if peerAS != nbr.peerAS { - t.Errorf("BGP peerAs: got %v, want %v", peerAS, nbr.peerAS) - } - - // Check BGP localAS from telemetry. - localAS := gnmi.Get(t, dut, nbrPath.State()).GetLocalAs() - if localAS != nbr.localAS { - t.Errorf("BGP localAS: got %v, want %v", localAS, nbr.localAS) - } - - // Check BGP globalAS from telemetry. - globalAS := gnmi.Get(t, dut, glblPath.State()).GetAs() - if globalAS != nbr.globalAS { - t.Errorf("BGP globalAS: got %v, want %v", globalAS, nbr.globalAS) - } -} - -func configureATE(t *testing.T, ateParams *bgpNbr, connectionType string) *ondatra.ATETopology { - t.Helper() - t.Log("Configure ATE interface") - ate := ondatra.ATE(t, "ate") - port1 := ate.Port(t, "port1") - topo := ate.Topology().New() - - iDut1 := topo.AddInterface(ateSrc.Name).WithPort(port1) - iDut1.IPv4().WithAddress(ateSrc.IPv4CIDR()).WithDefaultGateway(dutSrc.IPv4) - iDut1.IPv6().WithAddress(ateSrc.IPv6CIDR()).WithDefaultGateway(dutSrc.IPv6) - - bgpDut1 := iDut1.BGP() - - peer := bgpDut1.AddPeer().WithPeerAddress(ateParams.peerIP).WithLocalASN(ateParams.localAS) - if connectionType == connInternal { - peer.WithTypeInternal() - } else { - peer.WithTypeExternal() - } - return topo -} - -func createBgpNeighbor(nbr *bgpNbr, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { - d := &oc.Root{} - ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := niProto.GetOrCreateBgp() - - global := bgp.GetOrCreateGlobal() - global.As = ygot.Uint32(nbr.globalAS) - global.RouterId = ygot.String(dutSrc.IPv4) - global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) - - pg := bgp.GetOrCreatePeerGroup("ATE") - pg.PeerAs = ygot.Uint32(nbr.peerAS) - pg.PeerGroupName = ygot.String("ATE") - - neighbor := bgp.GetOrCreateNeighbor(nbr.peerIP) - neighbor.PeerAs = ygot.Uint32(nbr.peerAS) - neighbor.Enabled = ygot.Bool(true) - neighbor.PeerGroup = ygot.String("ATE") - neighbor.LocalAs = ygot.Uint32(nbr.localAS) - neighbor.GetOrCreateTimers().RestartTime = ygot.Uint16(75) - - if nbr.isV4 { - afisafi := neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - afisafi.Enabled = ygot.Bool(true) - neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(false) - } else { - afisafi6 := neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) - afisafi6.Enabled = ygot.Bool(true) - neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(false) - } - return niProto -} diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/metadata.textproto b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/metadata.textproto deleted file mode 100644 index 18a90886ebd..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/metadata.textproto +++ /dev/null @@ -1,29 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "b960ced4-2f59-49bf-b078-e53f169fac06" -plan_id: "RT-1.19" -description: "BGP 2-Byte and 4-Byte ASN support" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - route_policy_under_afi_unsupported: true - omit_l2_mtu: true - network_instance_table_deletion_required: true - interface_enabled: true - default_network_instance: "default" - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - interface_enabled: true - explicit_interface_in_default_vrf: true - } -} -tags: TAGS_AGGREGATION diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md deleted file mode 100644 index 51d125b5eb9..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# RT-1.24: BGP 2-Byte and 4-Byte ASN support with policy - -## Summary - -BGP 2-Byte and 4-Byte ASN support with policy - -## Procedure - -* Establish BGP sessions as follows and verify all the sessions are established: - * ATE (2-byte) - DUT (4-byte) - eBGP IPv4 with ASN < 65535 on DUT side - * ATE (2-byte) - DUT (4-byte) - eBGP IPv6 with ASN < 65535 on DUT side - * ATE (4-byte) - DUT (4-byte) - eBGP IPv4 - * ATE (4-byte) - DUT (4-byte) - eBGP IPv6 - * ATE (2-byte) - DUT (4-byte) - iBGP IPv4 with ASN < 65535 on DUT side - * ATE (4-byte) - DUT (4-byte) - iBGP IPv6 with ASN < 65535 on DUT side - * ATE (4-byte) - DUT (4-byte) - iBGP IPv4 - * ATE (4-byte) - DUT (4-byte) - iBGP IPv6 - -* Configure below policies and verify prefix count: - * Policy to reject prefix with prefix filter - * Policy to reject prefix with community filter - * Policy to reject prefix with regex filter to match as-path - -## Config Parameter Coverage - -* /global/config/as -* /neighbors/neighbor/config/peer-as -* /neighbors/neighbor/config/local-as - -## Telemetry Parameter Coverage - -* /global/config/as -* /neighbors/neighbor/config/peer-as -* /neighbors/neighbor/config/local-as diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go deleted file mode 100644 index 7ea95500983..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go +++ /dev/null @@ -1,499 +0,0 @@ -// Copyright 2023 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 bgp_2byte_4byte_asn_with_policy_test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - gpb "github.com/openconfig/gnmi/proto/gnmi" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" -) - -const ( - connInternal = "INTERNAL" - connExternal = "EXTERNAL" - rejectPrefix = "REJECT-PREFIX" - communitySet = "COMM-SET" - rejectCommunity = "REJECT-COMMUNITY" - rejectAspath = "REJECT-AS-PATH" - aclStatement1 = "10" - aclStatement2 = "20" - aclStatement3 = "50" - aclStatement4 = "60" - prefixSubnetRangeV4 = "30..32" - prefixSubnetRangeV6 = "126..128" - globalAsNumber = 999 -) - -var prefixV4 = []string{"198.51.100.0/30", "198.51.100.4/30", "198.51.100.8/30"} -var prefixV6 = []string{"2001:DB8:1::0/126", "2001:DB8:1::4/126", "2001:DB8:1::8/126"} -var community = []string{"200:1"} - -var ( - dutSrc = attrs.Attributes{ - Desc: "DUT to ATE source", - IPv4: "192.0.2.1", - IPv6: "2001:db8::192:0:2:1", - IPv4Len: 30, - IPv6Len: 126, - } - ateSrc = attrs.Attributes{ - Name: "ateSrc", - IPv4: "192.0.2.2", - IPv6: "2001:db8::192:0:2:2", - IPv4Len: 30, - IPv6Len: 126, - } -) - -type bgpNbr struct { - localAS, peerAS uint32 - peerIP string - isV4 bool -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} -func TestBgpSession(t *testing.T) { - t.Log("Configure DUT interface") - dut := ondatra.DUT(t, "dut") - dc := gnmi.OC() - i1 := dutSrc.NewOCInterface(dut.Port(t, "port1").Name(), dut) - gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) - - t.Log("Configure Network Instance") - dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) - gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) - - dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - - cases := []struct { - name string - nbr *bgpNbr - dutConf *oc.NetworkInstance_Protocol - ateConf *ondatra.ATETopology - }{ - { - name: "Establish eBGP connection between ATE (2-byte) - DUT (4-byte < 65535) for ipv4 peers", - nbr: &bgpNbr{localAS: 100, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 100, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 200, peerIP: dutSrc.IPv4, peerAS: 100, isV4: true}, connExternal, prefixV4), - }, { - name: "Establish eBGP connection between ATE (2-byte) - DUT (4-byte < 65535) for ipv6 peers", - nbr: &bgpNbr{localAS: 100, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 100, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 200, peerIP: dutSrc.IPv6, peerAS: 100, isV4: false}, connExternal, prefixV6), - }, { - name: "Establish eBGP connection between ATE (4-byte) - DUT (4-byte) for ipv4 peers", - nbr: &bgpNbr{localAS: 70000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 70000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 80000, peerIP: dutSrc.IPv4, peerAS: 70000, isV4: true}, connExternal, prefixV4), - }, { - name: "Establish eBGP connection between ATE (4-byte) - DUT (4-byte) for ipv6 peers", - nbr: &bgpNbr{localAS: 70000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: false}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 70000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 80000, peerIP: dutSrc.IPv6, peerAS: 70000, isV4: false}, connExternal, prefixV6), - }, { - name: "Establish iBGP connection between ATE (2-byte) - DUT (4-byte < 65535) for ipv4 peers", - nbr: &bgpNbr{localAS: 200, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 200, peerIP: ateSrc.IPv4, peerAS: 200, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 200, peerIP: dutSrc.IPv4, peerAS: 200, isV4: true}, connInternal, prefixV4), - }, { - name: "Establish iBGP connection between ATE (4-byte) - DUT (4-byte < 65535) for ipv6 peers", - nbr: &bgpNbr{localAS: 200, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 200, peerIP: ateSrc.IPv6, peerAS: 200, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 200, peerIP: dutSrc.IPv6, peerAS: 200, isV4: false}, connInternal, prefixV6), - }, { - name: "Establish iBGP connection between ATE (4-byte) - DUT (4-byte) for ipv4 peers", - nbr: &bgpNbr{localAS: 80000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 80000, peerIP: ateSrc.IPv4, peerAS: 80000, isV4: true}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 80000, peerIP: dutSrc.IPv4, peerAS: 80000, isV4: true}, connInternal, prefixV4), - }, { - name: "Establish iBGP connection between ATE (4-byte) - DUT (4-byte) for ipv6 peers", - nbr: &bgpNbr{localAS: 80000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: false}, - dutConf: createBgpNeighbor(&bgpNbr{localAS: 80000, peerIP: ateSrc.IPv6, peerAS: 80000, isV4: false}, dut), - ateConf: configureATE(t, &bgpNbr{localAS: 80000, peerIP: dutSrc.IPv6, peerAS: 80000, isV4: false}, connInternal, prefixV6), - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - t.Log("Clear BGP Configs on DUT") - bgpClearConfig(t, dut) - - configureRegexPolicy(t, dut) - - d := &oc.Root{} - rpl := configureBGPPolicy(t, d, tc.nbr.isV4) - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rpl) - - t.Log("Configure BGP on DUT") - gnmi.Replace(t, dut, dutConfPath.Config(), tc.dutConf) - - fptest.LogQuery(t, "DUT BGP Config ", dutConfPath.Config(), gnmi.Get(t, dut, dutConfPath.Config())) - t.Log("Configure BGP on ATE") - tc.ateConf.Push(t) - tc.ateConf.StartProtocols(t) - - t.Log("Verify BGP session state : ESTABLISHED") - nbrPath := statePath.Neighbor(tc.nbr.peerIP) - gnmi.Await(t, dut, nbrPath.SessionState().State(), time.Second*60, oc.Bgp_Neighbor_SessionState_ESTABLISHED) - - t.Log("Verify BGP AS numbers and prefix count") - verifyPeer(t, tc.nbr, dut) - - t.Log("Apply BGP policy for rejecting prefix") - pol := applyBgpPolicy(rejectPrefix, dut, tc.nbr.isV4) - gnmi.Update(t, dut, dutConfPath.Config(), pol) - verifyPrefixesTelemetry(t, dut, 2, tc.nbr.isV4) - deleteBgpPolicy(t, dut, tc.nbr.isV4) - verifyPrefixesTelemetry(t, dut, 3, tc.nbr.isV4) - - t.Log("Apply BGP policy for rejecting prefix with community filter") - pol = applyBgpPolicy(rejectCommunity, dut, tc.nbr.isV4) - gnmi.Update(t, dut, dutConfPath.Config(), pol) - verifyPrefixesTelemetry(t, dut, 2, tc.nbr.isV4) - deleteBgpPolicy(t, dut, tc.nbr.isV4) - verifyPrefixesTelemetry(t, dut, 3, tc.nbr.isV4) - - t.Log("Apply BGP policy for rejecting prefix with as-path regex filter") - pol = applyBgpPolicy(rejectAspath, dut, tc.nbr.isV4) - gnmi.Update(t, dut, dutConfPath.Config(), pol) - verifyPrefixesTelemetry(t, dut, 2, tc.nbr.isV4) - - t.Log("Clear BGP Configs on ATE") - tc.ateConf.StopProtocols(t) - }) - } -} - -// Build config with Origin set to cli and Ascii encoded config. -func buildCliConfigRequest(config string) (*gpb.SetRequest, error) { - gpbSetRequest := &gpb.SetRequest{ - Update: []*gpb.Update{{ - Path: &gpb.Path{ - Origin: "cli", - Elem: []*gpb.PathElem{}, - }, - Val: &gpb.TypedValue{ - Value: &gpb.TypedValue_AsciiVal{ - AsciiVal: config, - }, - }, - }}, - } - return gpbSetRequest, nil -} - -// juniperCLI returns Juniper CLI config statement. -func juniperCLI() string { - return fmt.Sprintf(` - policy-options { - policy-statement %s { - term term1 { - from as-path match-as-path; - then reject; - } - term term2 { - then accept; - } - } - as-path match-as-path ".* 4400 3300"; - }`, rejectAspath) -} - -// configureRegexPolicy is used to configure vendor specific config statement. -func configureRegexPolicy(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - var config string - gnmiClient := dut.RawAPIs().GNMI(t) - - switch dut.Vendor() { - case ondatra.JUNIPER: - config = juniperCLI() - t.Logf("Push the CLI config:%s", dut.Vendor()) - } - - gpbSetRequest, err := buildCliConfigRequest(config) - if err != nil { - t.Fatalf("Cannot build a gNMI SetRequest: %v", err) - } - - if _, err = gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { - t.Fatalf("gnmiClient.Set() with unexpected error: %v", err) - } -} - -// configureBGPPolicy configures a BGP routing policy to accept or reject routes based on prefix match conditions -// Additonally, it also configures policy to match prefix based on community and regex for as path -func configureBGPPolicy(t *testing.T, d *oc.Root, isV4 bool) *oc.RoutingPolicy { - t.Helper() - rp := d.GetOrCreateRoutingPolicy() - pset := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(rejectPrefix) - - if isV4 { - pset.GetOrCreatePrefix(prefixV4[2], prefixSubnetRangeV4) - } else { - pset.GetOrCreatePrefix(prefixV6[2], prefixSubnetRangeV6) - } - pdef := rp.GetOrCreatePolicyDefinition(rejectPrefix) - - stmt10, err := pdef.AppendNewStatement(aclStatement1) - if err != nil { - t.Errorf("Error while creating new statement %v", err) - } - stmt10.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE - stmt10.GetOrCreateConditions().GetOrCreateMatchPrefixSet().PrefixSet = ygot.String(rejectPrefix) - - stmt20, err := pdef.AppendNewStatement(aclStatement2) - if err != nil { - t.Errorf("Error while creating new statement %v", err) - } - stmt20.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE - - commSet := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(communitySet) - commSet.CommunitySetName = ygot.String(communitySet) - var communityMembers []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union - for _, member := range community { - communityMember, _ := commSet.To_RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union(member) - communityMembers = append(communityMembers, communityMember) - } - commSet.SetCommunityMember(communityMembers) - pdefComm := rp.GetOrCreatePolicyDefinition(rejectCommunity) - - stmt50, err := pdefComm.AppendNewStatement(aclStatement3) - if err != nil { - t.Errorf("Error while creating new statement %v", err) - } - stmt50.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE - stmt50.GetOrCreateConditions().GetOrCreateBgpConditions().CommunitySet = ygot.String(communitySet) - - stmt60, err := pdefComm.AppendNewStatement(aclStatement4) - if err != nil { - t.Errorf("Error while creating new statement %v", err) - } - stmt60.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE - - return rp -} - -func verifyPrefixesTelemetry(t *testing.T, dut *ondatra.DUTDevice, wantInstalled uint32, isV4 bool) { - t.Helper() - t.Logf("Verify BGP prefix count") - if isV4 { - verifyPrefixesTelemetryV4(t, dut, wantInstalled) - } else { - verifyPrefixesTelemetryV6(t, dut, wantInstalled) - } -} - -// verifyPrefixesTelemetry confirms that the dut shows the correct numbers of installed, sent and -// received IPv4 prefixes -func verifyPrefixesTelemetryV4(t *testing.T, dut *ondatra.DUTDevice, wantInstalled uint32) { - t.Helper() - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - prefixesv4 := statePath.Neighbor(ateSrc.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Prefixes() - - if gotInstalled := gnmi.Get(t, dut, prefixesv4.Installed().State()); gotInstalled != wantInstalled { - t.Errorf("Installed prefixes mismatch: got %v, want %v", gotInstalled, wantInstalled) - } -} - -// verifyPrefixesTelemetryV6 confirms that the dut shows the correct numbers of installed, sent and -// received IPv6 prefixes -func verifyPrefixesTelemetryV6(t *testing.T, dut *ondatra.DUTDevice, wantInstalledv6 uint32) { - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - prefixesv6 := statePath.Neighbor(ateSrc.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Prefixes() - - if gotInstalledv6 := gnmi.Get(t, dut, prefixesv6.Installed().State()); gotInstalledv6 != wantInstalledv6 { - t.Errorf("IPV6 Installed prefixes mismatch: got %v, want %v", gotInstalledv6, wantInstalledv6) - } -} - -// bgpClearConfig removes all BGP configuration from the DUT. -func bgpClearConfig(t *testing.T, dut *ondatra.DUTDevice) { - resetBatch := &gnmi.SetBatch{} - gnmi.BatchDelete(resetBatch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config()) - - if deviations.NetworkInstanceTableDeletionRequired(dut) { - tablePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).TableAny() - for _, table := range gnmi.LookupAll(t, dut, tablePath.Config()) { - if val, ok := table.Val(); ok { - if val.GetProtocol() == oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP { - gnmi.BatchDelete(resetBatch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Table(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, val.GetAddressFamily()).Config()) - } - } - } - } - resetBatch.Set(t, dut) -} - -func verifyPeer(t *testing.T, nbr *bgpNbr, dut *ondatra.DUTDevice) { - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - nbrPath := statePath.Neighbor(nbr.peerIP) - glblPath := statePath.Global() - - // Check BGP peerAS from telemetry. - peerAS := gnmi.Get(t, dut, nbrPath.State()).GetPeerAs() - if peerAS != nbr.peerAS { - t.Errorf("BGP peerAs: got %v, want %v", peerAS, nbr.peerAS) - } - - // Check BGP localAS from telemetry. - localAS := gnmi.Get(t, dut, nbrPath.State()).GetLocalAs() - if localAS != nbr.localAS { - t.Errorf("BGP localAS: got %v, want %v", localAS, nbr.localAS) - } - - // Check BGP globalAS from telemetry. - globalAS := gnmi.Get(t, dut, glblPath.State()).GetAs() - if globalAS != globalAsNumber { - t.Errorf("BGP globalAS: got %v, want %v", globalAS, nbr.localAS) - } - - verifyPrefixesTelemetry(t, dut, 3, nbr.isV4) -} - -func configureATE(t *testing.T, ateParams *bgpNbr, connectionType string, prefixes []string) *ondatra.ATETopology { - t.Helper() - t.Log("Configure ATE interface") - ate := ondatra.ATE(t, "ate") - port1 := ate.Port(t, "port1") - topo := ate.Topology().New() - - iDut1 := topo.AddInterface(ateSrc.Name).WithPort(port1) - iDut1.IPv4().WithAddress(ateSrc.IPv4CIDR()).WithDefaultGateway(dutSrc.IPv4) - iDut1.IPv6().WithAddress(ateSrc.IPv6CIDR()).WithDefaultGateway(dutSrc.IPv6) - - bgpDut1 := iDut1.BGP() - peer := bgpDut1.AddPeer().WithPeerAddress(ateParams.peerIP).WithLocalASN(ateParams.localAS) - - if connectionType == connInternal { - peer.WithTypeInternal() - } else { - peer.WithTypeExternal() - } - - network1 := iDut1.AddNetwork("bgpNeti1") - network2 := iDut1.AddNetwork("bgpNeti2") - network3 := iDut1.AddNetwork("bgpNeti3") - - if ateParams.isV4 { - network1.IPv4().WithAddress(prefixes[0]).WithCount(1) - network1.BGP().WithNextHopAddress(ateSrc.IPv4).AddASPathSegment(55000, 4400, 3300) - - network2.IPv4().WithAddress(prefixes[1]).WithCount(1) - network2.BGP().WithNextHopAddress(ateSrc.IPv4).AddASPathSegment(55000, 7700) - network2.BGP().Communities().WithPrivateCommunities("200:1") - - network3.IPv4().WithAddress(prefixes[2]).WithCount(1) - network3.BGP().WithNextHopAddress(ateSrc.IPv4) - } else { - network1.IPv6().WithAddress(prefixes[0]).WithCount(1) - network1.BGP().WithNextHopAddress(ateSrc.IPv6).AddASPathSegment(55000, 4400, 3300) - - network2.IPv6().WithAddress(prefixes[1]).WithCount(1) - network2.BGP().WithNextHopAddress(ateSrc.IPv6).AddASPathSegment(55000, 7700) - network2.BGP().Communities().WithPrivateCommunities("200:1") - - network3.IPv6().WithAddress(prefixes[2]).WithCount(1) - network3.BGP().WithNextHopAddress(ateSrc.IPv6) - } - return topo -} - -func applyBgpPolicy(policyName string, dut *ondatra.DUTDevice, isV4 bool) *oc.NetworkInstance_Protocol { - d := &oc.Root{} - ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := niProto.GetOrCreateBgp() - - pg := bgp.GetOrCreatePeerGroup("ATE") - pg.PeerGroupName = ygot.String("ATE") - - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - //policy under peer group - pg.GetOrCreateApplyPolicy().ImportPolicy = []string{policyName} - return niProto - } - - aftType := oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST - if isV4 { - aftType = oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST - } - - afisafi := pg.GetOrCreateAfiSafi(aftType) - afisafi.Enabled = ygot.Bool(true) - rpl := afisafi.GetOrCreateApplyPolicy() - rpl.SetImportPolicy([]string{policyName}) - - return niProto -} - -func deleteBgpPolicy(t *testing.T, dut *ondatra.DUTDevice, isV4 bool) { - t.Helper() - t.Logf("Delete BGP policy on DUT") - aftType := oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST - if isV4 { - aftType = oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST - } - - policyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup("ATE").AfiSafi(aftType).ApplyPolicy().Config() - gnmi.Delete(t, dut, policyConfPath) -} - -func createBgpNeighbor(nbr *bgpNbr, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { - d := &oc.Root{} - ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := niProto.GetOrCreateBgp() - - global := bgp.GetOrCreateGlobal() - global.As = ygot.Uint32(globalAsNumber) - global.RouterId = ygot.String(dutSrc.IPv4) - - pg := bgp.GetOrCreatePeerGroup("ATE") - pg.PeerAs = ygot.Uint32(nbr.peerAS) - pg.PeerGroupName = ygot.String("ATE") - - neighbor := bgp.GetOrCreateNeighbor(nbr.peerIP) - neighbor.PeerAs = ygot.Uint32(nbr.peerAS) - neighbor.LocalAs = ygot.Uint32(nbr.localAS) - neighbor.Enabled = ygot.Bool(true) - neighbor.PeerGroup = ygot.String("ATE") - neighbor.GetOrCreateTimers().RestartTime = ygot.Uint16(75) - - if nbr.isV4 { - afisafi := neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - afisafi.Enabled = ygot.Bool(true) - neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(false) - } else { - afisafi6 := neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) - afisafi6.Enabled = ygot.Bool(true) - neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(false) - } - return niProto -} diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto deleted file mode 100644 index bc335a7ac99..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto +++ /dev/null @@ -1,38 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "a993eb24-40f8-4b86-bc6b-02c19f6a0d53" -plan_id: "RT-1.24" -description: "BGP 2-Byte and 4-Byte ASN support with policy" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - use_vendor_native_acl_config: true - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - route_policy_under_afi_unsupported: true - omit_l2_mtu: true - interface_enabled: true - default_network_instance: "default" - } -} -tags: TAGS_AGGREGATION diff --git a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/README.md b/feature/experimental/bgp/ate_tests/bgp_remove_private_as/README.md deleted file mode 100644 index 3cf8f73d886..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# RT-1.11: BGP remove private AS  - -## Summary - -BGP remove private AS - -## Procedure - -* Establish BGP sessions as follows between ATE and DUT. - * ATE emulates two eBGP neighbors peering with the DUT using public AS numbers. - * DUT Port1 (AS 500) ---eBGP--- ATE Port1 (AS 100) - * DUT Port2 (AS 500) ---eBGP--- ATE Port2 (AS 200) - * Inject routes with AS_PATH modified to have private AS number 65501 from eBGP neighbor #1 - (ATE Port1). - * Validate received routes on ATE Port2 should have AS Path "500 100 65501". - * Configure "remove private AS" with type PRIVATE_AS_REMOVE_ALL on DUT. - * Validate that private AS numbers are stripped before advertisement to the eBGP peer ATE Port2. - * AS path for received routes on ATE Port2 should be "500 100". - * TODO: different patterns of private AS should be tested. - * AS Path SEQ - 65501, 65507, 65554 - * AS Path SEQ - 65501, 600 - * AS Path SEQ - 800, 65501, 600 - ## TODO : https://github.com/openconfig/featureprofiles/issues/1659 - ## SET mode is not working in ATE. - * AS Path SET - 800, 65505, 600 - -## Config Parameter coverage - -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/remove-private-as - -## Telemetry Parameter coverage - -* /network-instances/network-instance/protocols/protocol/bgp/rib/attr-sets/attr-set/as4-path/as4-segment/state - -## Protocol/RPC Parameter coverage - -N/A - -## Minimum DUT platform requirement - -N/A \ No newline at end of file diff --git a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go b/feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go deleted file mode 100644 index 0d785ad59c7..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go +++ /dev/null @@ -1,394 +0,0 @@ -// Copyright 2023 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 bgp_remove_private_as_test - -import ( - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygnmi/ygnmi" - "github.com/openconfig/ygot/ygot" -) - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// The testbed consists of ate:port1 -> dut:port1 and -// dut:port2 -> ate:port2. The first pair is called the "source" -// pair, and the second the "destination" pair. -// -// Source: ate:port1 -> dut:port1 subnet 192.0.2.0/30 -// Destination: dut:port2 -> ate:port2 subnet 192.0.2.4/30 -// -// Note that the first (.0, .3) and last (.4, .7) IPv4 addresses are -// reserved from the subnet for broadcast, so a /30 leaves exactly 2 -// usable addresses. This does not apply to IPv6 which allows /127 -// for point to point links, but we use /126 so the numbering is -// consistent with IPv4. - -const ( - trafficDuration = 1 * time.Minute - ipv4SrcTraffic = "192.0.2.2" - advertisedRoutesv4CIDR = "203.0.113.1/32" - peerGrpName1 = "BGP-PEER-GROUP1" - peerGrpName2 = "BGP-PEER-GROUP2" - policyName = "ALLOW" - routeCount = 254 - dutAS = 500 - ateAS1 = 100 - ateAS2 = 200 - plenIPv4 = 30 - plenIPv6 = 126 - removeASPath = true -) - -var ( - dutSrc = attrs.Attributes{ - Desc: "DUT to ATE source", - IPv4: "192.0.2.1", - IPv6: "2001:db8::192:0:2:1", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } - ateSrc = attrs.Attributes{ - Name: "ateSrc", - IPv4: "192.0.2.2", - IPv6: "2001:db8::192:0:2:2", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } - dutDst = attrs.Attributes{ - Desc: "DUT to ATE destination", - IPv4: "192.0.2.5", - IPv6: "2001:db8::192:0:2:5", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } - ateDst = attrs.Attributes{ - Name: "atedst", - IPv4: "192.0.2.6", - IPv6: "2001:db8::192:0:2:6", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } -) - -// configureDUT configures all the interfaces on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - dc := gnmi.OC() - i1 := dutSrc.NewOCInterface(dut.Port(t, "port1").Name(), dut) - gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) - - i2 := dutDst.NewOCInterface(dut.Port(t, "port2").Name(), dut) - gnmi.Replace(t, dut, dc.Interface(i2.GetName()).Config(), i2) -} - -// verifyPortsUp asserts that each port on the device is operating. -func verifyPortsUp(t *testing.T, dev *ondatra.Device) { - t.Helper() - for _, p := range dev.Ports() { - status := gnmi.Get(t, dev, gnmi.OC().Interface(p.Name()).OperStatus().State()) - if want := oc.Interface_OperStatus_UP; status != want { - t.Errorf("%s Status: got %v, want %v", p, status, want) - } - } -} - -// bgpCreateNbr creates a BGP object with neighbors pointing to ateSrc and ateDst. -func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { - nbr1v4 := &bgpNeighbor{as: ateAS1, neighborip: ateSrc.IPv4, isV4: true, peerGrp: peerGrpName1} - nbr2v4 := &bgpNeighbor{as: ateAS2, neighborip: ateDst.IPv4, isV4: true, peerGrp: peerGrpName2} - nbrs := []*bgpNeighbor{nbr1v4, nbr2v4} - - d := &oc.Root{} - ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := niProto.GetOrCreateBgp() - global := bgp.GetOrCreateGlobal() - global.RouterId = ygot.String(dutDst.IPv4) - global.As = ygot.Uint32(localAs) - global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) - global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) - - // Note: we have to define the peer group even if we aren't setting any policy because it's - // invalid OC for the neighbor to be part of a peer group that doesn't exist. - pg1 := bgp.GetOrCreatePeerGroup(peerGrpName1) - pg1.PeerAs = ygot.Uint32(ateAS1) - pg1.PeerGroupName = ygot.String(peerGrpName1) - - pg2 := bgp.GetOrCreatePeerGroup(peerGrpName2) - pg2.PeerAs = ygot.Uint32(ateAS2) - pg2.PeerGroupName = ygot.String(peerGrpName2) - - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - rpl := pg1.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{policyName} - rpl.ExportPolicy = []string{policyName} - - rp2 := pg2.GetOrCreateApplyPolicy() - rp2.ImportPolicy = []string{policyName} - rp2.ExportPolicy = []string{policyName} - } else { - pgaf := pg1.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - pgaf.Enabled = ygot.Bool(true) - rpl := pgaf.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{policyName} - rpl.ExportPolicy = []string{policyName} - - pgaf2 := pg2.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - pgaf2.Enabled = ygot.Bool(true) - rp2 := pgaf2.GetOrCreateApplyPolicy() - rp2.ImportPolicy = []string{policyName} - rp2.ExportPolicy = []string{policyName} - } - - for _, nbr := range nbrs { - nv4 := bgp.GetOrCreateNeighbor(nbr.neighborip) - nv4.PeerGroup = ygot.String(nbr.peerGrp) - nv4.PeerAs = ygot.Uint32(nbr.as) - nv4.Enabled = ygot.Bool(true) - af4 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - af4.Enabled = ygot.Bool(true) - af6 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) - af6.Enabled = ygot.Bool(false) - } - return niProto -} - -// verifyBGPTelemetry checks that the dut has an established BGP session with reasonable settings. -func verifyBGPTelemetry(t *testing.T, dut *ondatra.DUTDevice) { - var nbrIP = []string{ateSrc.IPv4, ateDst.IPv4} - t.Logf("Verifying BGP state.") - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - for _, nbr := range nbrIP { - var status *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState] - nbrPath := statePath.Neighbor(nbr) - t.Logf("Waiting for BGP neighbor to establish...") - status, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { - state, ok := val.Val() - return ok && state == oc.Bgp_Neighbor_SessionState_ESTABLISHED - }).Await(t) - if !ok { - fptest.LogQuery(t, "BGP reported state", nbrPath.State(), gnmi.Get(t, dut, nbrPath.State())) - t.Fatal("No BGP neighbor formed") - } - state, _ := status.Val() - t.Logf("BGP adjacency for %s: %s", nbr, state) - if want := oc.Bgp_Neighbor_SessionState_ESTABLISHED; state != want { - t.Errorf("BGP peer %s status got %v, want %d", nbr, status, want) - } - } -} - -// verifyPrefixesTelemetry confirms that the dut shows the correct numbers of installed, -// sent and received IPv4 prefixes. -func verifyPrefixesTelemetry(t *testing.T, dut *ondatra.DUTDevice, nbr string, wantInstalled, wantSent uint32) { - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - prefixesv4 := statePath.Neighbor(nbr).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Prefixes() - if gotInstalled := gnmi.Get(t, dut, prefixesv4.Installed().State()); gotInstalled != wantInstalled { - t.Errorf("Installed prefixes mismatch: got %v, want %v", gotInstalled, wantInstalled) - } - if gotSent := gnmi.Get(t, dut, prefixesv4.Sent().State()); gotSent != wantSent { - t.Errorf("Sent prefixes mismatch: got %v, want %v", gotSent, wantSent) - } -} - -// configureATE configures the interfaces and BGP protocols on an ATE, including -// advertising some(faked) networks over BGP. -func configureATE(t *testing.T, ate *ondatra.ATEDevice, asSeg []uint32, asSEQMode bool) *ondatra.ATETopology { - port1 := ate.Port(t, "port1") - topo := ate.Topology().New() - iDut1 := topo.AddInterface(ateSrc.Name).WithPort(port1) - iDut1.IPv4().WithAddress(ateSrc.IPv4CIDR()).WithDefaultGateway(dutSrc.IPv4) - - port2 := ate.Port(t, "port2") - iDut2 := topo.AddInterface(ateDst.Name).WithPort(port2) - iDut2.IPv4().WithAddress(ateDst.IPv4CIDR()).WithDefaultGateway(dutDst.IPv4) - - // Setup ATE BGP route v4 advertisement. - bgpDut1 := iDut1.BGP() - bgpDut1.AddPeer().WithPeerAddress(dutSrc.IPv4).WithLocalASN(ateAS1). - WithTypeExternal() - - bgpDut2 := iDut2.BGP() - bgpDut2.AddPeer().WithPeerAddress(dutDst.IPv4).WithLocalASN(ateAS2). - WithTypeExternal() - - bgpNeti1 := iDut1.AddNetwork("bgpNeti1") - bgpNeti1.IPv4().WithAddress(advertisedRoutesv4CIDR).WithCount(routeCount) - bgpNeti1.BGP().WithNextHopAddress(ateSrc.IPv4) - - if asSEQMode { - bgpNeti1.BGP().AddASPathSegment(asSeg...).WithTypeSEQ() - } else { - // TODO : SET mode is not working - // https://github.com/openconfig/featureprofiles/issues/1659 - bgpNeti1.BGP().AddASPathSegment(asSeg...).WithTypeSET() - } - - t.Logf("Pushing config to ATE and starting protocols...") - topo.Push(t) - topo.StartProtocols(t) - - return topo -} - -type bgpNeighbor struct { - as uint32 - neighborip string - isV4 bool - peerGrp string -} - -// verifyBGPAsPath is to Validate AS Path attribute using bgp rib telemetry on ATE. -func verifyBGPAsPath(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice, asSeg []uint32, removeASPath bool) { - at := gnmi.OC() - rib := at.NetworkInstance(ateDst.Name).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "0").Bgp().Rib() - prefixPath := rib.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast(). - NeighborAny().AdjRibInPre().RouteAny().WithPathId(0).Prefix() - - gnmi.WatchAll(t, ate, prefixPath.State(), time.Minute, func(v *ygnmi.Value[string]) bool { - _, present := v.Val() - return present - }).Await(t) - - var wantASSeg = []uint32{dutAS, ateAS1} - - if removeASPath { - for _, as := range asSeg { - if as < 64512 { - wantASSeg = append(wantASSeg, as) - } - } - } else { - wantASSeg = append(wantASSeg, asSeg...) - } - - gotASSeg, ok := gnmi.WatchAll(t, ate, rib.AttrSetAny().AsSegmentMap().State(), 1*time.Minute, func(v *ygnmi.Value[map[uint32]*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet_AsSegment]) bool { - val, present := v.Val() - if present { - for _, as := range val { - if cmp.Equal(as.Member, wantASSeg) { - return true - } - } - } - return false - }).Await(t) - if !ok { - t.Errorf("Obtained AS path on ATE is not as expected, gotASSeg %v, wantASSeg %v", gotASSeg, wantASSeg) - } -} - -// configreRoutePolicy adds route-policy config -func configureRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, name string, pr oc.E_RoutingPolicy_PolicyResultType) { - d := &oc.Root{} - rp := d.GetOrCreateRoutingPolicy() - pd := rp.GetOrCreatePolicyDefinition(name) - st, err := pd.AppendNewStatement("id-1") - if err != nil { - t.Fatal(err) - } - stc := st.GetOrCreateConditions() - stc.InstallProtocolEq = oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP - st.GetOrCreateActions().PolicyResult = pr - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) -} - -// TestRemovePrivateAS is to Validate that private AS numbers are stripped -// before advertisement to the eBGP neighbor. -func TestRemovePrivateAS(t *testing.T) { - t.Logf("Start DUT config load.") - dut := ondatra.DUT(t, "dut") - - t.Run("Configure DUT interfaces", func(t *testing.T) { - t.Logf("Start DUT interface Config.") - configureDUT(t, dut) - }) - - t.Run("Configure DEFAULT network instance.", func(t *testing.T) { - t.Log("Configure Network Instance type to DEFAULT.") - dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) - gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) - }) - - dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - t.Run("Configure BGP Neighbors.", func(t *testing.T) { - t.Logf("Start DUT BGP Config.") - gnmi.Delete(t, dut, dutConfPath.Config()) - configureRoutePolicy(t, dut, policyName, oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) - dutConf := bgpCreateNbr(dutAS, ateAS1, dut) - gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) - fptest.LogQuery(t, "DUT BGP Config", dutConfPath.Config(), gnmi.Get(t, dut, dutConfPath.Config())) - }) - - cases := []struct { - desc string - asSeg []uint32 - asSEQMode bool - }{{ - desc: "AS Path SEQ - 65501, 65507, 65534", - asSeg: []uint32{65501, 65507, 65534}, - asSEQMode: true, - }, { - desc: "AS Path SEQ - 65501, 600", - asSeg: []uint32{65501, 600}, - asSEQMode: true, - }, { - desc: "AS Path SEQ - 800, 65501, 600", - asSeg: []uint32{800, 65501, 600}, - asSEQMode: true, - }} - - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - t.Logf("Start ATE Config.") - ate := ondatra.ATE(t, "ate") - topo := configureATE(t, ate, tc.asSeg, tc.asSEQMode) - - t.Log("Verifying port status.") - verifyPortsUp(t, dut.Device) - - t.Log("Check BGP parameters.") - verifyBGPTelemetry(t, dut) - - t.Log("Verify BGP prefix telemetry.") - verifyPrefixesTelemetry(t, dut, ateSrc.IPv4, routeCount, 0) - verifyPrefixesTelemetry(t, dut, ateDst.IPv4, 0, routeCount) - - t.Log("Verify AS Path list received at ate Port2 including private AS number.") - verifyBGPAsPath(t, dut, ate, tc.asSeg, !removeASPath) - - t.Log("Configure remove private AS on DUT.") - gnmi.Update(t, dut, dutConfPath.Bgp().PeerGroup(peerGrpName2).RemovePrivateAs().Config(), oc.Bgp_RemovePrivateAsOption_PRIVATE_AS_REMOVE_ALL) - - t.Log("Private AS numbers should be stripped off while advertising BGP routes into public AS.") - verifyBGPAsPath(t, dut, ate, tc.asSeg, removeASPath) - - topo.StopProtocols(t) - - t.Log("Remove remove-private-AS on DUT.") - gnmi.Delete(t, dut, dutConfPath.Bgp().PeerGroup(peerGrpName2).RemovePrivateAs().Config()) - }) - } -} diff --git a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/metadata.textproto b/feature/experimental/bgp/ate_tests/bgp_remove_private_as/metadata.textproto deleted file mode 100644 index 4a298ab13bd..00000000000 --- a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/metadata.textproto +++ /dev/null @@ -1,24 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "2b4372c2-8827-4624-837c-f44b1a54edf7" -plan_id: "RT-1.11" -description: "BGP remove private AS" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - interface_enabled: true - } -} diff --git a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/README.md b/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/README.md deleted file mode 100644 index 80b76298f1e..00000000000 --- a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# gNMI-1.3: Benchmarking: Drained Configuration Convergence Time - -## Summary - -Measure performance of drained configuration being applied. - -## Procedure - -Configure DUT with maximum number of IS-IS adjacencies, and BGP -peers - with physical interfaces between ATE and DUT for IS-IS -peers. - -First port is used as ingress port to send routes from ATE to DUT. - -For each of the following configurations, generate complete device -configuration and measure time for the operation to complete (as -defined in the case): - * TODO: IS-IS overload: - * At t=0, send Set to DUT marking IS-IS overload bit. - * Measure time between t=0 and all IS-IS sessions on ATE to - report DUT as overloaded. - * IS-IS metric change: - * At t=0, send Set to DUT marking IS-IS metric as changed for - all IS-IS interfaces. - * Measure time between t=0 and all IS-IS sessions on ATE to - report changed metric. - * BGP AS_PATH prepend: - * At t=0, send Set to DUT changing BGP policy for each session - to prepend AS_PATH. - * Measure time between t=0 and all BGP received routes on ATE - to report change in as path. - * TODO: BGP MED manipulation. - * At t=0, send Set to DUT changing BGP policy for each session to - set MED to non-default value. - * Measure time between t=0 and all BGP received routes on ATE to - report changed metric. - -## Config Parameter coverage - - * BGP - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/as-number - - * ISIS - * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric - * /network-instances/network-instance/protocols/protocol/isis/global/lsp-bit/overload-bit/state/set-bit - -## Telemetry Parameter coverage - - * ISIS - * /interfaces/interfaces/levels/level/adjacencies/adjacency/state/adjacency-state - * BGP - * /afi-safis/afi-safi/state/prefixes/sent - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor diff --git a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go b/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go deleted file mode 100644 index 925e9149c55..00000000000 --- a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright 2023 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. - -// drained_configuration_convergence_time_test is used to verify bgp test scenarios -// as given in gnmi1.3 testcase. -package drained_configuration_convergence_time_test - -import ( - "net" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/openconfig/featureprofiles/feature/experimental/system/gnmi/benchmarking/internal/setup" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygnmi/ygnmi" - "github.com/openconfig/ygot/ygot" -) - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -const ( - asPathRepeatValue = 3 - aclStatement2 = "20" - aclStatement3 = "30" - setASpathPrependPolicy = "SET-ASPATH-PREPEND" - setMEDPolicy = "SET-MED" - setALLOWPolicy = "ALLOW" - bgpMED = 25 -) - -// setAllow is used to configure ALLOW routing policy on DUT. -func setAllow(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root) { - - // Configure Allow Policy on DUT. - rp := d.GetOrCreateRoutingPolicy() - pd := rp.GetOrCreatePolicyDefinition(setALLOWPolicy) - st, err := pd.AppendNewStatement("id-1") - if err != nil { - t.Fatal(err) - } - st.GetOrCreateActions().PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE - - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) -} - -// setMED is used to configure routing policy to set BGP MED on DUT. -func setMED(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root) { - - // Configure SetMED on DUT. - rp := d.GetOrCreateRoutingPolicy() - pdef5 := rp.GetOrCreatePolicyDefinition(setMEDPolicy) - stmt, err := pdef5.AppendNewStatement(aclStatement3) - if err != nil { - t.Fatal(err) - } - actions5 := stmt.GetOrCreateActions() - setMedBGP := actions5.GetOrCreateBgpActions() - setMedBGP.SetMed = oc.UnionUint32(bgpMED) - actions5.PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE - if deviations.BGPSetMedRequiresEqualOspfSetMetric(dut) { - actions5.GetOrCreateOspfActions().GetOrCreateSetMetric().SetMetric(bgpMED) - } - - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) -} - -// setASPath is used to configure route policy set-as-path prepend on DUT. -func setASPath(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root) { - - // Configure SetASPATH routing policy on DUT. - rp := d.GetOrCreateRoutingPolicy() - pdef5 := rp.GetOrCreatePolicyDefinition(setASpathPrependPolicy) - stmt, err := pdef5.AppendNewStatement(aclStatement2) - if err != nil { - t.Fatal(err) - } - actions5 := stmt.GetOrCreateActions() - actions5.PolicyResult = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE - aspend := actions5.GetOrCreateBgpActions().GetOrCreateSetAsPathPrepend() - aspend.Asn = ygot.Uint32(setup.DUTAs) - aspend.RepeatN = ygot.Uint8(asPathRepeatValue) - - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) - - netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - bgp := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() - pg := bgp.GetOrCreatePeerGroup(setup.PeerGrpName) - rpl := pg.GetOrCreateApplyPolicy() - rpl.SetImportPolicy([]string{setALLOWPolicy}) - - gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).Config(), pg) - -} - -func setPolicyPeerGroup(t *testing.T, dut *ondatra.DUTDevice, d *oc.Root, policy []string) { - - // Set BGP Import policy - netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - bgp := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() - pg := bgp.GetOrCreatePeerGroup(setup.PeerGrpName) - pg.PeerAs = ygot.Uint32(setup.ATEAs) - pg.PeerGroupName = ygot.String(setup.PeerGrpName) - afipg := pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - afipg.Enabled = ygot.Bool(true) - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - pgpolicy := pg.GetOrCreateApplyPolicy() - pgpolicy.ImportPolicy = policy - gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).Config(), pg) - - } else { - pgpolicy := afipg.GetOrCreateApplyPolicy() - pgpolicy.ImportPolicy = policy - gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).Config(), pg) - - } -} - -// isConverged function is used to check if ATE has received all the prefixes. -func isConverged(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice, ap *ondatra.Port) { - - // Add 10 second timer for BGP update to propagate - time.Sleep(10 * time.Second) - // Check if all prefixes are learned at ATE. - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). - Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() -prefixLoop: - for repeat := 4; repeat > 0; repeat-- { - prefixesv4 := statePath.Neighbor(setup.ATEIPList[ap.ID()].String()). - AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Prefixes() - gotSent := gnmi.Get(t, dut, prefixesv4.Sent().State()) - switch { - case gotSent == setup.RouteCount: - t.Logf("Prefixes sent from ingress port are learnt at ATE dst port : %v are %v", setup.ATEIPList[ap.ID()].String(), setup.RouteCount) - break prefixLoop - case repeat > 0 && gotSent < setup.RouteCount: - t.Logf("All the prefixes are not learnt , wait for 5 secs before retry.. got %v, want %v", gotSent, setup.RouteCount) - time.Sleep(time.Second * 5) - case repeat == 0 && gotSent < setup.RouteCount: - t.Errorf("sent prefixes from DUT to neighbor %v is mismatch: got %v, want %v", setup.ATEIPList[ap.ID()].String(), gotSent, setup.RouteCount) - } - } - -} - -// verifyBGPAsPath is to Validate AS Path attribute using bgp rib telemetry on ATE. -func verifyBGPAsPath(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { - - // Start the timer. - start := time.Now() - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). - Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). - PeerGroup(setup.PeerGrpName).ApplyPolicy().ExportPolicy() - - gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setASpathPrependPolicy}) - } else { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). - Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). - PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() - gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setASpathPrependPolicy}) - } - t.Run("BGP-AS-PATH Verification", func(t *testing.T) { - at := gnmi.OC() - for _, ap := range ate.Ports() { - if ap.ID() == "port1" { - // port1 is ingress, skip verification on ingress port. - continue - } - - // Validate if all prefixes are received by ATE. - isConverged(t, dut, ate, ap) - - rib := at.NetworkInstance(ap.Name()).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "0").Bgp().Rib() - prefixPath := rib.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast(). - NeighborAny().AdjRibInPre().RouteAny().WithPathId(0).Prefix() - - gnmi.WatchAll(t, ate, prefixPath.State(), time.Minute, func(v *ygnmi.Value[string]) bool { - _, present := v.Val() - return present - }).Await(t) - - singlepath := []uint32{setup.DUTAs, setup.DUTAs, setup.DUTAs, setup.DUTAs, setup.ATEAs2} - _, ok := gnmi.WatchAll(t, ate, rib.AttrSetAny().AsSegmentMap().State(), 5*time.Minute, func(v *ygnmi.Value[map[uint32]*oc.NetworkInstance_Protocol_Bgp_Rib_AttrSet_AsSegment]) bool { - val, present := v.Val() - if present { - for _, as := range val { - if cmp.Equal(as.Member, singlepath) { - return true - } - } - } - return false - }).Await(t) - if !ok { - t.Errorf("Obtained AS path on ATE is not as expected") - } - } - }) - - // End the timer and calculate time. - elapsed := time.Since(start) - t.Logf("Duration taken to apply as path prepend policy is %v", elapsed) -} - -// verifyBGPSetMED is to Validate MED attribute using bgp rib telemetry on ATE. -func verifyBGPSetMED(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { - - // Build wantSetMED to compare the diff. - var wantSetMED []uint32 - for i := 0; i < setup.RouteCount; i++ { - wantSetMED = append(wantSetMED, bgpMED) - } - - // Start the timer. - start := time.Now() - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). - Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). - PeerGroup(setup.PeerGrpName).ApplyPolicy().ExportPolicy() - gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setMEDPolicy}) - } else { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)). - Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp(). - PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy().ExportPolicy() - gnmi.Replace(t, dut, dutPolicyConfPath.Config(), []string{setMEDPolicy}) - } - - t.Run("BGP-MED-Verification", func(t *testing.T) { - at := gnmi.OC() - for _, ap := range ate.Ports() { - if ap.ID() == "port1" { - continue - } - - // Validate if all prefixes are received by ATE. - isConverged(t, dut, ate, ap) - rib := at.NetworkInstance(ap.Name()).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "0").Bgp().Rib() - routeP := rib.AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast(). - NeighborAny().AdjRibInPre().RouteAny().WithPathId(0) - routes := gnmi.GetAll(t, ate, routeP.State()) - attrs := gnmi.GetAll(t, ate, rib.AttrSetAny().State()) - mask := net.IPv4Mask(255, 255, 255, 0) - masked := net.ParseIP(setup.AdvertiseBGPRoutesv4).Mask(mask) - var gotSetMED []uint32 - var pref []string - for _, route := range routes { - ip, _, _ := net.ParseCIDR(route.GetPrefix()) - pref = append(pref, route.GetPrefix()) - if ip.Mask(mask).Equal(masked) { - idx := route.GetAttrIndex() - if idx >= uint64(len(attrs)) { - t.Errorf("Invalid attr-index %d for prefix: %s", idx, route.GetPrefix()) - continue - } - gotSetMED = append(gotSetMED, attrs[idx].GetMed()) - } - } - if diff := cmp.Diff(wantSetMED, gotSetMED); diff != "" { - t.Errorf("obtained MED on ATE is not as expected, got %v, want %v, Prefixes %v", gotSetMED, wantSetMED, pref) - } - } - }) - // End the timer and calculate time taken to apply setMED. - elapsed := time.Since(start) - t.Logf("Duration taken to apply setMed routing policy is %v", elapsed) -} - -// TestEstablish is to configure Interface, BGP and ISIS configurations on DUT -// using gnmi set request. It also verifies for bgp and isis adjacencies. -func TestEstablish(t *testing.T) { - - dut := ondatra.DUT(t, "dut") - dutConfigPath := gnmi.OC() - - t.Log("Configure Network Instance type to DEFAULT on DUT.") - fptest.ConfigureDefaultNetworkInstance(t, dut) - - t.Log("Build Benchmarking BGP and ISIS test configs.") - dutBenchmarkConfig := setup.BuildBenchmarkingConfig(t) - if !deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.LogQuery(t, "Benchmarking configs to configure on DUT", dutConfigPath.Config(), dutBenchmarkConfig) - } - // Apply benchmarking configs on dut - gnmi.Update(t, dut, dutConfigPath.Config(), dutBenchmarkConfig) - - t.Log("Configure ATE with Interfaces, BGP, ISIS configs.") - ate := ondatra.ATE(t, "ate") - setup.ConfigureATE(t, ate) - - t.Log("Verify BGP Session state , should be in ESTABLISHED State.") - setup.VerifyBgpTelemetry(t, dut) - - t.Log("Verify ISIS adjacency state, should be UP.") - setup.VerifyISISTelemetry(t, dut) -} - -// TestBGPBenchmarking is test time taken to apply set as path prepend and set med routing -// policies on routes in bgp rib. Verification of routing policy is done on ATE using bgp -// rib table. -func TestBGPBenchmarking(t *testing.T) { - - d := &oc.Root{} - dut := ondatra.DUT(t, "dut") - ate := ondatra.ATE(t, "ate") - // Cleanup existing policy details. - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).ApplyPolicy() - gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) - gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) - } else { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() - gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) - gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) - } - gnmi.Delete(t, dut, gnmi.OC().RoutingPolicy().Config()) - - t.Logf("Configure Allow policy.") - setAllow(t, dut, d) - - t.Logf("Configure MED routing policy.") - setMED(t, dut, d) - - t.Logf("Configure Allow Import routing policy in BGP.") - setPolicyPeerGroup(t, dut, d, []string{setALLOWPolicy}) - - t.Logf("Verify time taken to apply MED to all routes in bgp rib.") - verifyBGPSetMED(t, dut, ate) - - // Cleanup existing policy details. - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).ApplyPolicy() - gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) - gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) - } else { - dutPolicyConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp().PeerGroup(setup.PeerGrpName).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() - gnmi.Delete(t, dut, dutPolicyConfPath.ExportPolicy().Config()) - gnmi.Delete(t, dut, dutPolicyConfPath.ImportPolicy().Config()) - } - gnmi.Delete(t, dut, gnmi.OC().RoutingPolicy().Config()) - - t.Logf("Configure SET-AS-PATH routing policy.") - setASPath(t, dut, d) - - t.Logf("Configure Allow Import routing policy in BGP.") - setPolicyPeerGroup(t, dut, d, []string{setALLOWPolicy}) - - t.Logf("Verify time taken to apply SET-AS-PATH to all routes in bgp rib.") - verifyBGPAsPath(t, dut, ate) -} diff --git a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go b/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go deleted file mode 100644 index e14f163c63f..00000000000 --- a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2023 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. - -// drained_configuration_convergence_time_test is used to verify isis test scenarios -// as given in gnmi 1.3 testcase -package drained_configuration_convergence_time_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/feature/experimental/system/gnmi/benchmarking/internal/setup" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygnmi/ygnmi" -) - -// setISISOverloadBit is used to configure isis overload bit to true. -func setISISOverloadBit(t *testing.T, dut *ondatra.DUTDevice) { - - // ISIS Configs to set Overload Bit to true. - dutISISPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, setup.ISISInstance).Isis() - lspBit := dutISISPath.Global().LspBit().OverloadBit() - gnmi.Replace(t, dut, lspBit.SetBit().Config(), true) -} - -// setISISMetric is used to configure metric on isis interfaces. -func setISISMetric(t *testing.T, dut *ondatra.DUTDevice) { - - dutISISPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, setup.ISISInstance).Isis() - t.Logf("Configure ISIS metric to %v", setup.ISISMetric) - for _, dp := range dut.Ports() { - intfName := dp.Name() - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - intfName = dp.Name() + ".0" - } - dutISISPathIntfAF := dutISISPath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST) - if deviations.ISISRequireSameL1MetricWithL2Metric(dut) { - b := &gnmi.SetBatch{} - gnmi.BatchReplace(b, dutISISPathIntfAF.Metric().Config(), setup.ISISMetric) - l1AF := dutISISPath.Interface(intfName).Level(1).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST) - gnmi.BatchReplace(b, l1AF.Metric().Config(), setup.ISISMetric) - b.Set(t, dut) - } else { - gnmi.Replace(t, dut, dutISISPathIntfAF.Metric().Config(), setup.ISISMetric) - } - } -} - -// verifyISISMetric is used to verify on ATE to see how much time it -// has taken to apply changes in metric -func verifyISISMetric(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { - - t.Run("ISIS Metric verification", func(t *testing.T) { - at := gnmi.OC() - for _, ap := range ate.Ports() { - if ap.ID() == "port1" { - // Port1 is ingress, skip verification on ingress port - continue - } - - const want = oc.Interface_OperStatus_UP - - if got := gnmi.Get(t, ate, at.Interface(ap.Name()).OperStatus().State()); got != want { - t.Errorf("%s oper-status got %v, want %v", ap, got, want) - } - is := at.NetworkInstance(ap.Name()).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, "0").Isis() - lsps := is.LevelAny().LspAny() - - _, ok := gnmi.WatchAll(t, ate, lsps.Tlv(oc.IsisLsdbTypes_ISIS_TLV_TYPE_EXTENDED_IPV4_REACHABILITY).ExtendedIpv4Reachability().PrefixAny().Metric().State(), 5*time.Minute, func(v *ygnmi.Value[uint32]) bool { - val, present := v.Val() - return present && val == setup.ISISMetric - }).Await(t) - if !ok { - t.Errorf("Obtained Metric on ATE is not as expected") - } - } - }) -} - -// verifyISISOverloadBit is used to verify on ATE to see how much time it -// has taken to apply overload bit on isis adjacencies. -func verifyISISOverloadBit(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) { - - t.Run("ISIS Overload bit verification", func(t *testing.T) { - at := gnmi.OC() - for _, ap := range ate.Ports() { - if ap.ID() == "port1" { - // port1 is ingress, skip verification on ingress port - continue - } - - const want = oc.Interface_OperStatus_UP - - if got := gnmi.Get(t, ate, at.Interface(ap.Name()).OperStatus().State()); got != want { - t.Errorf("%s oper-status got %v, want %v", ap, got, want) - } - // TODO: SetBit retrieval is not working in ATE. - // Ref: https://github.com/openconfig/featureprofiles/issues/1176 - // Below code will be uncommented once above issue is resolved. - - // is := at.NetworkInstance(ap.Name()).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, "0").Isis() - // lsps := is.LevelAny().LspAny() - // gotIsisSetBit := gnmi.GetAll(t, ate, lsps.Tlv(oc.IsisLsdbTypes_ISIS_TLV_TYPE_EXTENDED_IPV4_REACHABILITY).ExtendedIpv4Reachability().PrefixAny().SBit().State()) - // if diff := cmp.Diff(setup.ISISSetBitList, gotIsisSetBit); diff != "" { - // t.Errorf("obtained setBit on ATE is not as expected, got %v, want %v", gotIsisSetBit, setup.ISISSetBitList) - // } - } - }) -} - -// TestISISBenchmarking is to test ISIS overload bit and metric change -// applied on all isis sessions. -func TestISISBenchmarking(t *testing.T) { - - dut := ondatra.DUT(t, "dut") - ate := ondatra.ATE(t, "ate") - t.Log("Start timer for ISIS overload bit verification test.") - start := time.Now() - t.Log("Configure ISIS overload bit on DUT.") - setISISOverloadBit(t, dut) - t.Log("Verify on ATE if ISIS overload bit is reflected on ATE.") - verifyISISOverloadBit(t, dut, ate) - t.Log("End the timer and calculate time taken to apply ISIS overload bit.") - elapsed := time.Since(start) - t.Logf("Duration taken to apply overload bit: %v", elapsed) - - t.Log("Start timer for ISIS Metric test.") - start = time.Now() - t.Log("Configure ISIS Metric on DUT.") - setISISMetric(t, dut) - t.Log("Verify on ATE if ISIS Metric changes are reflected.") - verifyISISMetric(t, dut, ate) - t.Log("End the timer and calculate time taken to apply ISIS Metric.") - elapsed = time.Since(start) - t.Logf("Duration taken to apply isis metric: %v", elapsed) -} diff --git a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/metadata.textproto b/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/metadata.textproto deleted file mode 100644 index e6104d7837a..00000000000 --- a/feature/experimental/system/gnmi/benchmarking/ate_tests/drained_configuration_convergence_time/metadata.textproto +++ /dev/null @@ -1,43 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "44ec09b1-d985-4188-9f4a-ae542ad9d3a2" -plan_id: "gNMI-1.3" -description: "Benchmarking: Drained Configuration Convergence Time" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - isis_global_authentication_not_required: true - isis_explicit_level_authentication_config: true - missing_isis_interface_afi_safi_enable: true - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - isis_level_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - route_policy_under_afi_unsupported: true - interface_enabled: true - default_network_instance: "default" - missing_isis_interface_afi_safi_enable: true - isis_interface_afi_unsupported: true - isis_require_same_l1_metric_with_l2_metric: true - bgp_set_med_requires_equal_ospf_set_metric: true - isis_instance_enabled_required: true - } -} From 98dfdcfda23dcdf3da4abb5ec1dde52f6ccecbd5 Mon Sep 17 00:00:00 2001 From: karthick-gunasekaran-arista <161495828+karthick-gunasekaran-arista@users.noreply.github.com> Date: Thu, 25 Apr 2024 10:19:26 +0530 Subject: [PATCH 94/97] Added sleep for Linecards to be properly up post power disable/enable and added a check to skip validation on unused FAPs which does not have any interface up (#2875) --- .../sampled_backplane_capacity_counters_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/sampled_backplane_capacity_counters_test.go b/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/sampled_backplane_capacity_counters_test.go index 4c1c707c0c6..3e7f39995df 100644 --- a/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/sampled_backplane_capacity_counters_test.go +++ b/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/sampled_backplane_capacity_counters_test.go @@ -129,7 +129,8 @@ func TestOnChangeBackplaneCapacityCounters(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Component(f).Fabric().PowerAdminState().Config(), oc.Platform_ComponentPowerType_POWER_DISABLED) gnmi.Await(t, dut, gnmi.OC().Component(f).Fabric().PowerAdminState().State(), time.Minute, oc.Platform_ComponentPowerType_POWER_DISABLED) } - + t.Logf("Waiting for 90s after power disable...") + time.Sleep(90 * time.Second) ts2, tocs2, apct2 := getBackplaneCapacityCounters(t, dut, ics) for _, f := range fabrics[:fc] { @@ -145,7 +146,8 @@ func TestOnChangeBackplaneCapacityCounters(t *testing.T) { t.Errorf("Component %s oper-status after POWER_ENABLED, got: %v, want: %v", f, oper, oc.PlatformTypes_COMPONENT_OPER_STATUS_ACTIVE) } } - + t.Logf("Waiting for 90s after power enable...") + time.Sleep(90 * time.Second) ts3, tocs3, apct3 := getBackplaneCapacityCounters(t, dut, ics) for _, ic := range ics { @@ -184,7 +186,7 @@ func TestOnChangeBackplaneCapacityCounters(t *testing.T) { switch { case !ok1 || !ok2 || !ok3: t.Errorf("BackplaneFacingCapacity AvailablePct not present: ok1 %t, ok2 %t, ok3 %t", ok1, ok2, ok3) - case v1 <= v2 || v1 != v3: + case v1 != 0 && (v1 <= v2 || v1 != v3): t.Errorf("BackplaneFacingCapacity AvailablePct are not valid: v1 %d, v2 %d, v3 %d", v1, v2, v3) } }) From 64388db0ea85c18ed6e556324dc8f2dcc643ddfb Mon Sep 17 00:00:00 2001 From: Nachikethas AJ Date: Thu, 25 Apr 2024 16:30:57 -0700 Subject: [PATCH 95/97] [TE-16.3] Test specification for encap FRR with REPAIR (#2919) * [TE-16.3] Test specification for encap FRR with REPAIR * [TE-16.3] Add test case for missing encap entries * [TE-16.3] Add details for DSCP and static route --------- Co-authored-by: Xiao Wang <39514181+xw-g@users.noreply.github.com> --- .../encap_frr_with_repair_vrf/README.md | 617 ++++++++++++++++++ 1 file changed, 617 insertions(+) create mode 100644 feature/gribi/otg_tests/encap_frr_with_repair_vrf/README.md diff --git a/feature/gribi/otg_tests/encap_frr_with_repair_vrf/README.md b/feature/gribi/otg_tests/encap_frr_with_repair_vrf/README.md new file mode 100644 index 00000000000..3298b85d563 --- /dev/null +++ b/feature/gribi/otg_tests/encap_frr_with_repair_vrf/README.md @@ -0,0 +1,617 @@ +# TE-16.3: encapsulation FRR scenarios + +## Summary + +Test FRR behaviors with encapsulation scenarios. + +## Topology + +- ATE port-1 <------> port-1 DUT +- DUT port-2 <------> port-2 ATE +- DUT port-3 <------> port-3 ATE +- DUT port-4 <------> port-4 ATE +- DUT port-5 <------> port-5 ATE +- DUT port-6 <------> port-6 ATE +- DUT port-7 <------> port-7 ATE +- DUT port-8 <------> port-8 ATE + +## Baseline setup + +* Apply the following vrf selection policy to DUT port-1 + +``` +# DSCP value that will be matched to ENCAP_TE_VRF_A +* dscp_encap_a_1 = 10 +* dscp_encap_a_2 = 18 + +# DSCP value that will be matched to ENCAP_TE_VRF_B +* dscp_encap_b_1 = 20 +* dscp_encap_b_2 = 28 + +# DSCP value that will NOT be matched to any VRF for encapsulation. +* dscp_encap_no_match = 30 + +# Magic source IP addresses used in VRF selection policy +* ipv4_outer_src_111 = 198.51.100.111 +* ipv4_outer_src_222 = 198.51.100.222 + +# Magic destination MAC address +* magic_mac = 02:00:00:00:00:01` +``` + +``` +network-instances { + network-instance { + name: DEFAULT + policy-forwarding { + policies { + policy { + policy-id: "vrf_selection_policy_c" + rules { + rule { + sequence-id: 1 + ipv4 { + protocol: 4 + dscp-set: [dscp_encap_a_1, dscp_encap_a_2] + source-address: "ipv4_outer_src_222" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_A" + decap-fallback-network-instance: "TE_VRF_222" + } + } + rule { + sequence-id: 2 + ipv4 { + protocol: 41 + dscp-set: [dscp_encap_a_1, dscp_encap_a_2] + source-address: "ipv4_outer_src_222" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_A" + decap-fallback-network-instance: "TE_VRF_222" + } + } + rule { + sequence-id: 3 + ipv4 { + protocol: 4 + dscp-set: [dscp_encap_a_1, dscp_encap_a_2] + source-address: "ipv4_outer_src_111" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_A" + decap-fallback-network-instance: "TE_VRF_111" + } + } + rule { + sequence-id: 4 + ipv4 { + protocol: 41 + dscp-set: [dscp_encap_a_1, dscp_encap_a_2] + source-address: "ipv4_outer_src_111" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_A" + decap-fallback-network-instance: "TE_VRF_111" + } + } + rule { + sequence-id: 5 + ipv4 { + protocol: 4 + dscp-set: [dscp_encap_b_1, dscp_encap_b_2] + source-address: "ipv4_outer_src_222" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_B" + decap-fallback-network-instance: "TE_VRF_222" + } + } + rule { + sequence-id: 6 + ipv4 { + protocol: 41 + dscp-set: [dscp_encap_b_1, dscp_encap_b_2] + source-address: "ipv4_outer_src_222" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_B" + decap-fallback-network-instance: "TE_VRF_222" + } + } + rule { + sequence-id: 7 + ipv4 { + protocol: 4 + dscp-set: [dscp_encap_b_1, dscp_encap_b_2] + source-address: "ipv4_outer_src_111" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_B" + decap-fallback-network-instance: "TE_VRF_111" + } + } + rule { + sequence-id: 8 + ipv4 { + protocol: 41 + dscp-set: [dscp_encap_b_1, dscp_encap_b_2] + source-address: "ipv4_outer_src_111" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "ENCAP_TE_VRF_B" + decap-fallback-network-instance: "TE_VRF_111" + } + } + rule { + sequence-id: 9 + ipv4 { + protocol: 4 + source-address: "ipv4_outer_src_222" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "DEFAULT" + decap-fallback-network-instance: "TE_VRF_222" + } + } + rule { + sequence-id: 10 + ipv4 { + protocol: 41 + source-address: "ipv4_outer_src_222" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "DEFAULT" + decap-fallback-network-instance: "TE_VRF_222" + } + } + rule { + sequence-id: 11 + ipv4 { + protocol: 4 + source-address: "ipv4_outer_src_111" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "DEFAULT" + decap-fallback-network-instance: "TE_VRF_111" + } + } + rule { + sequence-id: 12 + ipv4 { + protocol: 41 + source-address: "ipv4_outer_src_111" + } + action { + decap-network-instance: "DECAP_TE_VRF" + post-network-instance: "DEFAULT" + decap-fallback-network-instance: "TE_VRF_111" + } + } + rule { + sequence-id: 13 + ipv4 { + dscp-set: [dscp_encap_a_1, dscp_encap_a_2] + } + action { + network-instance: "ENCAP_TE_VRF_A" + } + } + rule { + sequence-id: 14 + ipv6 { + dscp-set: [dscp_encap_a_1, dscp_encap_a_2] + } + action { + network-instance: "ENCAP_TE_VRF_A" + } + } + rule { + sequence-id: 15 + ipv4 { + dscp-set: [dscp_encap_b_1, dscp_encap_b_2] + } + action { + network-instance: "ENCAP_TE_VRF_B" + } + } + rule { + sequence-id: 16 + ipv6 { + dscp-set: [dscp_encap_b_1, dscp_encap_b_2] + } + action { + network-instance: "ENCAP_TE_VRF_B" + } + } + rule { + sequence-id: 17 + action { + network-instance: "DEFAULT" + } + } + } + } + } + } + } +} +``` + +* Using gRIBI, install the following gRIBI AFTs, and validate the specified + behavior. + +``` +IPv4Entry {138.0.11.0/24 (ENCAP_TE_VRF_A)} -> NHG#101 (DEFAULT VRF) -> { + {NH#101, DEFAULT VRF, weight:1}, + {NH#102, DEFAULT VRF, weight:3}, + backup_next_hop_group: 2001 // fallback to DEFAULT VRF +} + +NHG#2001 (DEFAULT VRF) { + {NH#2001, DEFAULT VRF} +} +NH#2001 -> { + network_instance: "DEFAULT" +} + +NH#101 -> { + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.0.113.1" + src_ip: "ipv4_outer_src_111" + } + network_instance: "TE_VRF_111" +} +NH#102 -> { + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.0.113.2" + src_ip: "ipv4_outer_src_111" + } + network_instance: "TE_VRF_111" +} + + +IPv4Entry {203.0.113.1/32 (TE_VRF_111)} -> NHG#1 (DEFAULT VRF) -> { + {NH#1, DEFAULT VRF, weight:1,ip_address=192.0.2.101}, + {NH#2, DEFAULT VRF, weight:3,ip_address=192.0.2.102}, + backup_next_hop_group: 3000 // Go to REPAIR VRF +} +IPv4Entry {192.0.2.101/32 (DEFAULT VRF)} -> NHG#11 (DEFAULT VRF) -> { + {NH#11, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-2-interface}, + {NH#12, DEFAULT VRF, weight:3,mac_address:magic_mac, interface-ref:dut-port-3-interface}, +} +IPv4Entry {192.0.2.102/32 (DEFAUlT VRF)} -> NHG#12 (DEFAULT VRF) -> { + {NH#13, DEFAULT VRF, weight:2,mac_address:magic_mac, interface-ref:dut-port-4-interface}, +} + +NHG#3000 (DEFAULT VRF) { + {NH#3000, DEFAULT VRF} +} +NH#3000 -> { + network_instance: "REPAIR" +} + +IPv4Entry {203.0.113.1/32 (REPAIR)} -> NHG#1000 (DEFAULT VRF) -> { + {NH#1000, DEFAULT VRF} + backup_next_hop_group: 2000 // decap and fallback to DEFAULT VRF +} +NH#1000 -> { + decapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.0.113.100" + src_ip: "ipv4_outer_src_222" + } + network_instance: "TE_VRF_222" +} + +IPv4Entry {203.0.113.100/32 (TE_VRF_222)} -> NHG#2 (DEFAULT VRF) -> { + {NH#3, DEFAULT VRF, weight:1,ip_address=192.0.2.103}, + backup_next_hop_group: 2000 // decap and fallback to DEFAULT VRF +} +IPv4Entry {192.0.2.103/32 (DEFAULT VRF)} -> NHG#13 (DEFAULT VRF) -> { + {NH#14, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-5-interface}, +} + +// 203.0.113.2 is the tunnel IP address. Note that the NHG#3 is different than NHG#1. + +IPv4Entry {203.0.113.2/32 (TE_VRF_111)} -> NHG#3 (DEFAULT VRF) -> { + {NH#4, DEFAULT VRF, weight:1,ip_address=192.0.2.104}, + backup_next_hop_group: 3000 // Go to REPAIR VRF +} + +IPv4Entry {192.0.2.104/32 (DEFAULT VRF)} -> NHG#14 (DEFAULT VRF) -> { + {NH#15, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-6-interface}, +} + +IPv4Entry {203.0.113.2/32 (REPAIR)} -> NHG#1001 (DEFAULT VRF) -> { + {NH#1001, DEFAULT VRF} + backup_next_hop_group: 2000 // decap and fallback to DEFAULT VRF +} +NHG#1001 (DEFAULT VRF) { + {NH#1001, DEFAULT VRF} +} +NH#1001 -> { + decapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.0.113.101" + src_ip: "ipv4_outer_src_222" + } + network_instance: "TE_VRF_222" +} + +IPv4Entry {203.0.113.101/32 (TE_VRF_222)} -> NHG#4 (DEFAULT VRF) -> { + {NH#5, DEFAULT VRF, weight:1,ip_address=192.0.2.105}, + backup_next_hop_group: 2000 // decap and fallback to DEFAULT VRF +} +IPv4Entry {192.0.2.105/32 (DEFAULT VRF)} -> NHG#15 (DEFAULT VRF) -> { + {NH#16, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-7-interface}, +} + +NHG#2000 (DEFAULT VRF) { + {NH#2000, DEFAULT VRF} +} +NH#2000 -> { + decapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + network_instance: "DEFAULT" +} +``` + +* Install a BGP route resolved by ISIS in default VRF to route 138.0.11.8 + traffic out of DUT port-8. + +## Procedure + +At the start of each of the following scenarios, ensure: + +* All ports are up and baseline is reset as above. +* Send packets to DUT port-1. The outer v4 header has the destination + addresses 138.0.11.8. +* Validate that traffic is encapsulated to 203.0.113.1 and 203.0.113.2, and is + distributed per the hierarchical weights. + +Unless otherwise specified, all the tests below should use traffic with +`dscp_encap_a_1`. + +#### Test-1, primary encap unviable but backup encap viable for single tunnel + +Tests that if the primary NHG for an encap tunnel is unviable, then the traffic +for that tunnel is re-encaped into its specified backup tunnel. + +1. Shutdown DUT port-2, port-3, and port-4. +2. Validate that corresponding traffic that was encapped to 203.0.113.1 should + now be encapped with 203.0.113.100. + +#### Test-2, primary and backup encap unviable for single tunnel + +Tests that if the primary NHGs of both the encap tunnel and its backup tunnel +are unviable, then the traffic for that tunnel is not encapped. Instead, that +fraction of traffic should be forwarded according to the BGP/IS-IS routes in the +DEFAULT VRF. + +1. Shutdown DUT port-2, port-3, port-4 and port-5. +2. Validate that corresponding traffic (25% of the total traffic) that was + encapped to 203.0.113.1 are no longer encapped, and forwarded per BGP-ISIS + routes (in the default VRF) out of DUT port-8. + +#### Test-3, primary encap unviable with backup to routing for single tunnel + +Tests that if the primary NHGs of both the encap tunnel is unviable, and its +backup specifies fallback to routing, then the traffic for that tunnel is not +encapped. Instead, that fraction of traffic should be forwarded according to the +BGP/IS-IS routes in the DEFAULT VRF. + +1. Update `NHG#1000` to the following: + +``` +NHG#1000 (Default VRF) { + {NH#1000, DEFAULT VRF} +} +NH#1000 -> { + decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 + network_instance: "DEFAULT" +} +``` + +1. Validate that all traffic is distributed per the hierarchical weights. +2. Shutdown DUT port-2, port-3, and port-4. +3. Validate that corresponding traffic (25% of the total traffic) that was + encapped to 203.0.113.1 are no longer encapped, and forwarded per BGP-ISIS + routes (in the default VRF) out of DUT port-8. + +#### Test-4, primary encap unviable but backup encap viable for all tunnels + +Tests that if the primary NHG for all encap tunnels are unviable, then the +traffic is re-encaped into the specified backup tunnels. This test ensures that +the device does not withdraw this IPv4Entry and sends this traffic to routing. + +1. Shutdown DUT port-2, port-3, port-4 and port-6. +2. Validate that traffic is encapsulated to 203.0.113.100 and 203.0.113.101 per + the weights. + +#### Test-5, primary and backup encap unviable for all tunnels + +Tests that if the primary NHGs of both the encap tunnel and its backup tunnel +are unviable for all tunnels in the encap NHG, then the traffic for that cluster +prefix is not encapped. Instead, that traffic should be forwarded according to +the BGP/IS-IS routes in the DEFAULT VRF. This stresses the double failure +handling, and ensures that the fallback to DEFAULT is activated through the +backup NHGs of the tunnels instead of withdrawing the IPv4Entry. + +1. Shutdown DUT port-2, port-3, port-4, port-5, port-6 and port-7. +2. Validate that all traffic is no longer encapsulated, and is all egressing + out of DUT port-8 per the BGP-ISIS routes in the default VRF. + +#### Test-6, primary encap unviable with backup to routing for all tunnels + +Tests that if the primary NHGs of both the encap tunnel is unviable, and its +backup specifies fallback to routing, for all tunnels in the encap NHG, then the +traffic for that cluster prefix is not encapped. Instead, that traffic should be +forwarded according to the BGP/IS-IS routes in the DEFAULT VRF. This stresses +the double failure handling, and ensures that the fallback to DEFAULT is +activated through the backup NHGs of the tunnels instead of withdrawing the +IPv4Entry. + +1. Update `NHG#1000` and `NHG#1001` to the following: + +``` +NHG#1000 (Default VRF) { {NH#1000, DEFAULT VRF} } + +NH#1000 -> { + decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 + network_instance: "DEFAULT" +} + +NHG#1001 (Default VRF) { {NH#1001, DEFAULT VRF} } + +NH#1001 -> { + decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 + network_instance: "DEFAULT" +} +``` + +1. Validate that all traffic is distributed per the hierarchical weights. +2. Shutdown DUT port-2, port-3, and port-4, and port-6. +3. Validate that all traffic is no longer encapsulated, and is all egressing + out of DUT port-8 per the BGP-ISIS routes in the default VRF. + +#### Test-7, no match in encap VRF + +Test that if there is no lookup match in the encap VRF, then the traffic should +be routed to the DEFAULT VRF for further lookup. + +1. In `ENCAP_TE_VRF_A`, Add an 0/0 static route pointing to the DEFAULT VRF + using gNMI. +2. Send traffic with destination address 20.0.0.1, which should produce no + match in `ENCAP_TE_VRF_A`. +3. Validate that the traffic is routed per the BGP-ISIS routes (in the DEFAULT + VR) out of DUT port-8. + +#### Test-8, no match in TE_VRF_222 + +Tests that if the re-encaps point to tunnels that do not exist, then the traffic +should be routed to the `DEFAULT` VRF for further lookup. + +1. Update `NHG#1000` and `NHG#1001` to the following: + +``` +NHG#1000 (Default VRF) { {NH#1000, DEFAULT VRF} } + +NH#1000 -> { + decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.100.113.100" // This route does not exist in TE_VRF_222 + src_ip: "ipv4_outer_src_222" + } + network_instance: "TE_VRF_222" +} + +NHG#1001 (Default VRF) { {NH#1001, DEFAULT VRF} } + +NH#1001 -> { + decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.100.113.101" // This route does not exist in TE_VRF_222 + src_ip: "ipv4_outer_src_222" + } + network_instance: "TE_VRF_222" +} +``` + +1. Validate that all traffic is distributed per the hierarchical weights. +2. Shutdown DUT port-2, port-3, and port-4, and port-6. +3. Validate that all traffic is no longer encapsulated, and is all egressing + out of DUT port-8 per the BGP-ISIS routes in the default VRF. + +#### Test-8, no match in TE_VRF_111 + +Tests that if the primary encaps point to tunnels that do not exist, then the +traffic should be routed to the `DEFAULT` VRF for further lookup. + +1. Validate that all traffic is distributed per the hierarchical weights. +2. Update NHG#101 to the following: + +``` +NHG#101 (DEFAULT VRF) -> { + {NH#101, DEFAULT VRF, weight:1}, + {NH#102, DEFAULT VRF, weight:3}, + backup_next_hop_group: 2001 // fallback to DEFAULT VRF +} + +NH#101 -> { + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.100.113.1" // This route does not exist in TE_VRF_111 + src_ip: "ipv4_outer_src_111" + } + network_instance: "TE_VRF_111" +} +NH#102 -> { + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "203.100.113.2" // This route does not exist in TE_VRF_111 + src_ip: "ipv4_outer_src_111" + } + network_instance: "TE_VRF_111" +} +``` + +1. Validate that all traffic is no longer encapsulated, and is all egressing + out of DUT port-8 per the BGP-ISIS routes in the default VRF. + +## Config Parameter Coverage + +* network-instances/network-instance/name +* network-instances/network-instance/policy-forwarding/policies/policy/policy-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/sequence-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/protocol +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/dscp-set +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/protocol +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/dscp-set +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-network-instance +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/post-network-instance +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-fallback-network-instance + +## Telemetry Parameter Coverage + +* network-instances/network-instance/name +* network-instances/network-instance/policy-forwarding/policies/policy/policy-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/sequence-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/protocol +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/dscp-set +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/protocol +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/dscp-set +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-network-instance +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/post-network-instance +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-fallback-network-instance + +## Protocol/RPC Parameter Coverage + +* gRIBI: + * Modify + * ModifyRequest + +## Required DUT platform + +- vRX From f380440fc92a4799668d26821fcb66bce2a333e0 Mon Sep 17 00:00:00 2001 From: NishaSadhasivam-work Date: Mon, 29 Apr 2024 11:32:33 +0530 Subject: [PATCH 96/97] Addressing regex change (#2930) * DCGATE: [RT-7.11] BGP import/export policy - multifacet match and actions - Test Automation * Addressed review comments * addressing review comments * Validate Accept all traffic modification * Update import_export_multi.go fixing static analysis failure * Update import_export_multi.go static analysis failure * Modified multi policy configuration * static analysis failure update * removed default policy * fixing static analysis failure * fixing go fmt issues * re-arranging PD1 and PD2 * Update import_export_multi.go * Addressing the change as per b/336180917 --- .../otg_tests/import_export_multi/import_export_multi.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go index e4ade0a930b..c5132e21189 100644 --- a/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go +++ b/feature/bgp/policybase/otg_tests/import_export_multi/import_export_multi.go @@ -136,7 +136,7 @@ func configureImportExportAcceptAllBGPPolicy(t *testing.T, dut *ondatra.DUTDevic func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ondatra.DUTDevice, ipv4 string, ipv6 string) { rejectCommunities := []string{"10:1"} acceptCommunities := []string{"20:1"} - regexCommunities := []string{"^30:.*$"} + regexCommunities := []string{"(^|\\s)30:[0-9]+($|\\s)"} addCommunitiesRefs := []string{"40:1", "40:2"} addCommunitiesSetRefsAction := []string{"add-communities"} setCommunitySetRefs := []string{"add_comm_60", "add_comm_70"} @@ -156,7 +156,7 @@ func configureImportExportMultifacetMatchActionsBGPPolicy(t *testing.T, dut *ond t.Fatalf("AppendNewStatement(%s) failed: %v", callPolicyStatement, err) } - // Configure regex_community:["^30:.*$"] to match_community_regex statement + // Configure regex_community:["(^|\\s)30:[0-9]+($|\\s)"] to match_community_regex statement communitySetRegex := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(regexCommunitySet) pd2cs1 := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} From 87f3397bc322ec35e34a470cd793b070db882e63 Mon Sep 17 00:00:00 2001 From: Cheedella Akhil <161872540+cakhil45@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:10:14 +0530 Subject: [PATCH 97/97] System-1: System testing: Updates to g_protocol_test.go (#2855) * added encoding type to gnmi get request to avoid get request error * handled precondition error for gnsi get request --------- Co-authored-by: Ram --- .../tests/system_base_test/g_protocol_test.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/feature/system/tests/system_base_test/g_protocol_test.go b/feature/system/tests/system_base_test/g_protocol_test.go index baf1e745196..8e901db64e0 100644 --- a/feature/system/tests/system_base_test/g_protocol_test.go +++ b/feature/system/tests/system_base_test/g_protocol_test.go @@ -24,6 +24,8 @@ import ( "github.com/openconfig/ondatra" "github.com/openconfig/ondatra/binding/introspect" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" gpb "github.com/openconfig/gnmi/proto/gnmi" spb "github.com/openconfig/gnoi/system" @@ -56,7 +58,7 @@ func TestGNMIClient(t *testing.T) { dut := ondatra.DUT(t, "dut") conn := dialConn(t, dut, introspect.GNMI, 9339) c := gpb.NewGNMIClient(conn) - if _, err := c.Get(context.Background(), &gpb.GetRequest{}); err != nil { + if _, err := c.Get(context.Background(), &gpb.GetRequest{Encoding: gpb.Encoding_JSON_IETF, Path: []*gpb.Path{{Elem: []*gpb.PathElem{}}}}); err != nil { t.Fatalf("gnmi.Get failed: %v", err) } } @@ -76,9 +78,16 @@ func TestGNSIClient(t *testing.T) { dut := ondatra.DUT(t, "dut") conn := dialConn(t, dut, introspect.GNSI, 9339) c := authzpb.NewAuthzClient(conn) - if _, err := c.Get(context.Background(), &authzpb.GetRequest{}); err != nil { - t.Fatalf("gnsi.authz.Get failed: %v", err) + rsp, err := c.Get(context.Background(), &authzpb.GetRequest{}) + if err != nil { + statusError, _ := status.FromError(err) + if statusError.Code() == codes.FailedPrecondition { + t.Logf("Expected error FAILED_PRECONDITION seen for authz Get Request.") + } else { + t.Errorf("Unexpected error during authz Get Request.") + } } + t.Logf("gNSI authz get response is %s", rsp) } // TestGRIBIClient validates that the DUT listens on standard gRIBI Port.