From 6101863135ef14a2ed53b60df67d56c7ec9ae0ca Mon Sep 17 00:00:00 2001 From: snaragund Date: Thu, 7 Nov 2024 17:25:05 +0530 Subject: [PATCH 1/9] RT-1.28: Fixed script with additional deviations - Added new deviation EnableTableConnections & other required deviation. - Used `bgp_community_member_is_a_string: true` with ref to https://partnerissuetracker.corp.google.com/issues/376799780#comment2 - Match-Community-Set under bgp-conditions configuration moved under policy-defitions as its configuration is deprecated under bgp-defined-sets. - Under nonMatchingCommunityRoutePolicy(both v4 & v6) changed gnmi.Replace to gnmi.Update to avoid precondition error of failing to delete AllowAll route-policy. "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_isis_redistribution_test.go | 88 ++++++++++++++++--- .../metadata.textproto | 12 +++ 2 files changed, 88 insertions(+), 12 deletions(-) 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 00ff8bae5f0..4ab62441e45 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 @@ -15,6 +15,8 @@ package bgp_isis_redistribution_test import ( + "context" + "encoding/json" "fmt" "net" "strconv" @@ -28,6 +30,7 @@ import ( "github.com/openconfig/featureprofiles/internal/helpers" "github.com/openconfig/featureprofiles/internal/isissession" "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" @@ -197,6 +200,7 @@ func TestBGPToISISRedistribution(t *testing.T) { checkTraffic(t, ts, v4FlowName) } else { createFlowV6(t, ts) + //time.Sleep(3 * time.Second) checkTraffic(t, ts, v6FlowName) } } @@ -307,7 +311,9 @@ func nonMatchingPrefixRoutePolicy(t *testing.T, dut *ondatra.DUTDevice) { } prefixSet := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(v4PrefixSet) - prefixSet.SetMode(oc.PrefixSet_Mode_IPV4) + if !deviations.SkipPrefixSetMode(dut) { + prefixSet.SetMode(oc.PrefixSet_Mode_IPV4) + } prefixSet.GetOrCreatePrefix(nonAdvertisedIPv4.cidr(t), maskLenExact) if !deviations.SkipSetRpMatchSetOptions(dut) { @@ -350,14 +356,16 @@ func nonMatchingCommunityRoutePolicy(t *testing.T, dut *ondatra.DUTDevice) { communitySet := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(v4CommunitySet) communitySet.SetCommunityMember([]oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{oc.UnionString(fmt.Sprintf("%d:%d", dummyAS, 200))}) - communitySet.SetMatchSetOptions(oc.BgpPolicy_MatchSetOptionsType_ANY) if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + communitySet.SetMatchSetOptions(oc.BgpPolicy_MatchSetOptionsType_ANY) stmt.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(v4CommunitySet) } else { - stmt.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(v4CommunitySet) + ref1 := stmt.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet() + ref1.SetCommunitySet(v4CommunitySet) + ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_ANY) } - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) } } @@ -397,8 +405,10 @@ func verifyNonMatchingPrefixTelemetry(t *testing.T, dut *ondatra.DUTDevice, ate if pName := prefixSet.GetName(); pName != v4PrefixSet { t.Errorf("Prefix set name: %s, want: %s", pName, v4PrefixSet) } - if pMode := prefixSet.GetMode(); pMode != oc.PrefixSet_Mode_IPV4 { - t.Errorf("Prefix set mode: %s, want: %s", pMode, oc.PrefixSet_Mode_IPV4) + if !deviations.SkipPrefixSetMode(dut) { + if pMode := prefixSet.GetMode(); pMode != oc.PrefixSet_Mode_IPV4 { + t.Errorf("Prefix set mode: %s, want: %s", pMode, oc.PrefixSet_Mode_IPV4) + } } if prefix := prefixSet.GetPrefix(nonAdvertisedIPv4.cidr(t), maskLenExact); prefix == nil { t.Errorf("Prefix is nil, want: %s", nonAdvertisedIPv4.cidr(t)) @@ -523,7 +533,9 @@ func nonMatchingPrefixRoutePolicyV6(t *testing.T, dut *ondatra.DUTDevice) { } prefixSet := rp.GetOrCreateDefinedSets().GetOrCreatePrefixSet(v6PrefixSet) - prefixSet.SetMode(oc.PrefixSet_Mode_IPV6) + if !deviations.SkipPrefixSetMode(dut) { + prefixSet.SetMode(oc.PrefixSet_Mode_IPV6) + } prefixSet.GetOrCreatePrefix(nonAdvertisedIPv6.cidr(t), maskLenExact) if !deviations.SkipSetRpMatchSetOptions(dut) { @@ -566,14 +578,16 @@ func nonMatchingCommunityRoutePolicyV6(t *testing.T, dut *ondatra.DUTDevice) { communitySet := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets().GetOrCreateCommunitySet(v6CommunitySet) communitySet.SetCommunityMember([]oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{oc.UnionString(fmt.Sprintf("%d:%d", dummyAS, 200))}) - communitySet.SetMatchSetOptions(oc.BgpPolicy_MatchSetOptionsType_ANY) if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + communitySet.SetMatchSetOptions(oc.BgpPolicy_MatchSetOptionsType_ANY) stmt.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(v6CommunitySet) } else { - stmt.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet().SetCommunitySet(v6CommunitySet) + ref1 := stmt.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet() + ref1.SetCommunitySet(v6CommunitySet) + ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_ANY) } - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) } } @@ -613,8 +627,11 @@ func verifyNonMatchingPrefixTelemetryV6(t *testing.T, dut *ondatra.DUTDevice, at if pName := prefixSet.GetName(); pName != v6PrefixSet { t.Errorf("Prefix set name: %s, want: %s", pName, v6PrefixSet) } - if pMode := prefixSet.GetMode(); pMode != oc.PrefixSet_Mode_IPV6 { - t.Errorf("Prefix set mode: %s, want: %s", pMode, oc.PrefixSet_Mode_IPV6) + + if !deviations.SkipPrefixSetMode(dut) { + if pMode := prefixSet.GetMode(); pMode != oc.PrefixSet_Mode_IPV6 { + t.Errorf("Prefix set mode: %s, want: %s", pMode, oc.PrefixSet_Mode_IPV6) + } } if prefix := prefixSet.GetPrefix(nonAdvertisedIPv6.cidr(t), maskLenExact); prefix == nil { t.Errorf("Prefix is nil, want: %s", nonAdvertisedIPv6.cidr(t)) @@ -725,6 +742,12 @@ func verifyMatchingCommunityTelemetryV6(t *testing.T, dut *ondatra.DUTDevice, at func bgpISISRedistribution(t *testing.T, dut *ondatra.DUTDevice) { dni := deviations.DefaultNetworkInstance(dut) root := &oc.Root{} + + if deviations.EnableTableConnections(dut) { + state := "enable" + configEnableTbNative(t, dut, state) + } + tableConn := root.GetOrCreateNetworkInstance(dni).GetOrCreateTableConnection(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, oc.Types_ADDRESS_FAMILY_IPV4) if !deviations.SkipSettingDisableMetricPropagation(dut) { tableConn.SetDisableMetricPropagation(false) @@ -812,6 +835,47 @@ func configureBGPTablePolicyWithSetTag(t *testing.T, prefixSetName, prefixSetAdd } } +func configEnableTbNative(t testing.TB, d *ondatra.DUTDevice, state string) { + t.Helper() + switch d.Vendor() { + case ondatra.NOKIA: + //value := state + adminEnable, err := json.Marshal(state) + 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: "table-connections"}, + {Name: "admin-state"}, + }, + }, + Val: &gpb.TypedValue{ + Value: &gpb.TypedValue_JsonIetfVal{ + JsonIetfVal: adminEnable, + }, + }, + }, + }, + } + + gnmiClient := d.RawAPIs().GNMI(t) + if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { + t.Fatalf("Unexpected error updating SRL static-route tag-set: %v", err) + } + default: + t.Fatalf("Unsupported vendor %s for deviation 'UseVendorNativeACLConfiguration'", d.Vendor()) + } +} + func configureRoutePolicyAllow(t *testing.T, dut *ondatra.DUTDevice, name string, pr oc.E_RoutingPolicy_PolicyResultType) { d := &oc.Root{} rp := d.GetOrCreateRoutingPolicy() 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 f4552e8cdf0..5ead442c232 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 @@ -45,3 +45,15 @@ platform_exceptions: { default_route_policy_unsupported: true } } +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_interface_in_default_vrf: true + interface_enabled: true + skip_prefix_set_mode: true + enable_table_connections: true + bgp_community_member_is_a_string: true + } +} From 16404a0129557ac2e5112a6b1fd9f711fe960326 Mon Sep 17 00:00:00 2001 From: snaragund Date: Thu, 7 Nov 2024 18:04:06 +0530 Subject: [PATCH 2/9] -Removed 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_isis_redistribution_test/bgp_isis_redistribution_test.go | 1 - 1 file changed, 1 deletion(-) 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 4ab62441e45..c69b20cbe5e 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 @@ -200,7 +200,6 @@ func TestBGPToISISRedistribution(t *testing.T) { checkTraffic(t, ts, v4FlowName) } else { createFlowV6(t, ts) - //time.Sleep(3 * time.Second) checkTraffic(t, ts, v6FlowName) } } From 1b139d5498fdd6e4fb3d94cd234f297e6b66bb83 Mon Sep 17 00:00:00 2001 From: snaragund Date: Thu, 7 Nov 2024 23:02:08 +0530 Subject: [PATCH 3/9] -Adding changes to deviations.go, metadata.proto & metadata.pb.go for EnableTableConnections. "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." --- internal/deviations/deviations.go | 5 ++ proto/metadata.proto | 3 + proto/metadata_go_proto/metadata.pb.go | 101 ++++++++++++++----------- 3 files changed, 64 insertions(+), 45 deletions(-) diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index a2935bcbad8..48512507a0e 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -1201,3 +1201,8 @@ func BgpSessionStateIdleInPassiveMode(dut *ondatra.DUTDevice) bool { func EnableMultipathUnderAfiSafi(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetEnableMultipathUnderAfiSafi() } + +// Admin Enable Table Connections in SRL native +func EnableTableConnections(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetEnableTableConnections() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 34bab43fa57..3c8323ba584 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -641,6 +641,9 @@ message Metadata { // CISCO: b/376241033 // CISCO: b/340859662 bool enable_multipath_under_afi_safi = 230; + // Nokia; b/304493065 comment#7 SRL native admin_enable for table-connections + bool enable_table_connections = 231; + // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19, 36, 35, 40, 173; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 492051766c2..07bbdb354cd 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.34.1 -// protoc v3.21.12 +// protoc-gen-go v1.27.1 +// protoc v3.12.4 // source: metadata.proto package metadata_go_proto @@ -684,8 +684,7 @@ type Metadata_Deviations struct { // 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 - // - // Nokia: partnerissuetracker.corp.google.com/issues/323251581 + // 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. // Juniper: b/307258544 @@ -922,6 +921,8 @@ type Metadata_Deviations struct { // CISCO: b/376241033 // CISCO: b/340859662 EnableMultipathUnderAfiSafi bool `protobuf:"varint,230,opt,name=enable_multipath_under_afi_safi,json=enableMultipathUnderAfiSafi,proto3" json:"enable_multipath_under_afi_safi,omitempty"` + // Nokia; b/304493065 comment#7 SRL native admin_enable for table-connections + EnableTableConnections bool `protobuf:"varint,231,opt,name=enable_table_connections,json=enableTableConnections,proto3" json:"enable_table_connections,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -2419,6 +2420,13 @@ func (x *Metadata_Deviations) GetEnableMultipathUnderAfiSafi() bool { return false } +func (x *Metadata_Deviations) GetEnableTableConnections() bool { + if x != nil { + return x.EnableTableConnections + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2482,7 +2490,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, 0xef, 0x81, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaa, 0x82, 0x01, 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, @@ -2516,7 +2524,7 @@ var file_metadata_proto_rawDesc = []byte{ 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, 0xc2, 0x79, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xfd, 0x79, 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, @@ -3483,46 +3491,49 @@ var file_metadata_proto_rawDesc = []byte{ 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x18, 0xe6, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x74, 0x68, 0x55, - 0x6e, 0x64, 0x65, 0x72, 0x41, 0x66, 0x69, 0x53, 0x61, 0x66, 0x69, 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, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x4a, 0x04, 0x08, 0x23, 0x10, 0x24, 0x4a, 0x04, 0x08, - 0x28, 0x10, 0x29, 0x4a, 0x06, 0x08, 0xad, 0x01, 0x10, 0xae, 0x01, 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, + 0x6e, 0x64, 0x65, 0x72, 0x41, 0x66, 0x69, 0x53, 0x61, 0x66, 0x69, 0x12, 0x39, 0x0a, 0x18, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 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, 0x4a, 0x04, 0x08, 0x24, + 0x10, 0x25, 0x4a, 0x04, 0x08, 0x23, 0x10, 0x24, 0x4a, 0x04, 0x08, 0x28, 0x10, 0x29, 0x4a, 0x06, + 0x08, 0xad, 0x01, 0x10, 0xae, 0x01, 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, + 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 f41b14ae757fc5367b892b30427150bcb4612744 Mon Sep 17 00:00:00 2001 From: snaragund Date: Wed, 27 Nov 2024 16:43:30 +0530 Subject: [PATCH 4/9] -Resolving conflicts "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." --- .github/CODEOWNERS | 2 +- .../aft_base/otg_tests/afts_base/README.md | 177 ++++++ .../otg_tests/afts_prefix_counters/README.md | 178 ++++++ .../route_summary_counters_test/README.md | 0 .../metadata.textproto | 0 .../route_summary_counters_test.go | 0 .../otg_tests/scale_aft_summary/README.md | 39 ++ .../scale_aft_summary/metadata.textproto | 54 ++ .../otg_tests/scale_aft_summary/route_test.go | 566 ++++++++++++++++++ ...bgp_override_as_path_split_horizon_test.go | 22 +- .../link_bandwidth_test.go | 332 ++++++---- .../otg_tests/encap_decap_scale/README.md | 4 +- .../encap_decap_scale_test.go | 4 +- .../otg_tests/weighted_ecmp_test/README.md | 49 +- .../metadata.textproto | 11 + .../zr_logical_channels_test.go | 270 ++++++--- .../tests/zr_pm_test/metadata.textproto | 11 + .../tests/zr_pm_test/zr_pm_test.go | 26 +- .../large_set_consistency_test/README.md | 10 + .../large_set_consistency_test.go | 58 +- .../metadata.textproto | 8 + .../set/tests/gnmi_set_test/gnmi_set_test.go | 192 +----- internal/deviations/README.md | 192 ++++-- internal/deviations/deviations.go | 11 + internal/fptest/config.go | 205 +++++++ internal/security/acctz/acctz.go | 34 +- proto/metadata.proto | 7 +- proto/metadata_go_proto/metadata.pb.go | 120 ++-- testregistry.textproto | 22 +- tools/nosimage/validate/validate.go | 7 +- 30 files changed, 2001 insertions(+), 610 deletions(-) create mode 100644 feature/aft/aft_base/otg_tests/afts_base/README.md create mode 100644 feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md rename feature/aft/{aft_summary => afts_summary}/otg_tests/route_summary_counters_test/README.md (100%) rename feature/aft/{aft_summary => afts_summary}/otg_tests/route_summary_counters_test/metadata.textproto (100%) rename feature/aft/{aft_summary => afts_summary}/otg_tests/route_summary_counters_test/route_summary_counters_test.go (100%) create mode 100644 feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md create mode 100644 feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto create mode 100644 feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go create mode 100644 internal/fptest/config.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index df375ba3436..82423e81a15 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -12,7 +12,7 @@ # /feature folders each have owners who are auto requested for review and may merge PR's /feature/acl/ @alokmtri-g -/feature/aft/ @sudhinj +/feature/aft/ @sudhinj @yunjie-lu /feature/bgp/ @dplore /feature/dhcp/ @alokmtri-g /feature/ethernet/ @ram-mac diff --git a/feature/aft/aft_base/otg_tests/afts_base/README.md b/feature/aft/aft_base/otg_tests/afts_base/README.md new file mode 100644 index 00000000000..b2e0d5a2792 --- /dev/null +++ b/feature/aft/aft_base/otg_tests/afts_base/README.md @@ -0,0 +1,177 @@ +# AFT-1.1: AFTs Base + +## Summary + +IPv4/IPv6 unicast routes next hop group and next hop. + +## Testbed + +* atedut_4.testbed + +## Test Setup + +### Generate DUT and ATE Configuration + +Configure DUT:port1,port2,port3 for IS-IS session with ATE:port1,port2,port3 +* IS-IS must be level 2 only with wide metric. +* IS-IS must be point to point. +* Send 1000 ipv4 and 1000 ipv6 IS-IS prefixes from ATE:port3 to DUT:port3. + + +Establish eBGP sessions between ATE:port1,port2 and DUT:port1,port2 and another between ATE:port3 and DUT:port3. +* Configure eBGP over the interface ip. +* eBGP must be multipath. +* Advertise 1000 ipv4,ipv6 prefixes from ATE port1,port2 observe received prefixes at DUT. +* Validate total number of entries of AFT for IPv4 and IPv6. +* Each prefix must have 2 next hops pointing to ATE port1,port2. +* Advertise 100 ipv4,ipv6 from ATE port3 observe received prefixes at DUT. + +Establish RSVP Sessions between ATE:port3 and SUT:port3. +* Configure mpls and rsvp sessions. +* Configure 2 ingress TE tunnels from DUT:port3 to ATE:port3. +* Tunnel destination is interface ip of ATE:port3. +* Configure explicit null and ipv6 tunneling. +* BGP advertised routes from ATE:port3 must be pointing to the 2 tunnels in the DUT. + +### Procedure + +* Use gNMI.Set with REPLACE option to push the Test Setup configuration to the DUT. +* ATE configuration must be pushed. + +### Verifications + +* BGP route advertised from ATE:port1,port2 must have 2 nexthops. +* IS-IS route advertised from ATE:port3 must have one next hop. +* BGP route advertised from ATE:port3 must have 2 next hops pointing to tunnels. +* Use gnmi Subscribe with ON_CHANGE option to /network-instances/network-instance/afts. +* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. +* Verify afts prefix advertised by BGP,ISIS. +* Verify its next hop group, number of next hop and its interfaces. +* Verify the number of next hop is same as expected. +* Verify all other leaves mentioned in the path section. + + +## AFT-1.1.1: AFT Base Link Down scenario 1 + +### Procedure + +Bring down the link between ATE:port2 and DUT:port2 using OTG api. + +### Verifications + +* BGP routes advertised from ATE:port1,port2 must have 1 nexthop. +* IS-IS routes advertised from ATE:port3 must have one next hop. +* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. +* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. +* Verify afts prefix advertised by BGP,ISIS. +* Verify its next hop group, number of next hop and its interfaces. +* Verify the number of next hop is same as expected. + +## AFT-1.1.2: AFT Base Link Down scenario 2 + +### Procedure + +Bring down both links between ATE:port1,port2 and DUT:port1,port2 using OTG api. + +### Verifications + +* BGP routes advertised from ATE:port1,port2 must be removed from RIB,FIB of the DUT, query results nil. +* IS-IS routes advertised from ATE:port3 must have one next hop. +* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. +* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. +* Verify afts prefix advertised by BGP,ISIS. +* Verify its next hop group, number of next hop and its interfaces. +* Verify the number of next hop is same as expected. + +## AFT-1.1.3: AFT Base Link Up scenario 1 + +### Procedure + +Bring up link between ATE:port1 and DUT:port1 using OTG api. + +### Verifications + +* BGP routes advertised from ATE:port1,port2 must have one next hop. +* IS-IS routes advertised from ATE:port3 must have one next hop. +* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. +* Verify afts prefix advertised by BGP,ISIS. +* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. +* Verify its next hop group, number of next hop and its interfaces. +* Verify the number of next hop is same as expected. + +## AFT-1.1.4: AFT Base Link Up scenario 2 + +### Procedure + +Bring up both link between ATE:port1,port2 and DUT:port1,port2 using OTG api. + +### Verifications + +* BGP routes advertised from ATE:port1,port2 must have 2 next hops. +* IS-IS routes advertised from ATE:port3 must have one next hop. +* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. +* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. +* Verify afts prefix advertised by BGP,ISIS. +* Verify its next hop group, number of next hop and its interfaces. +* Verify the number of next hop is same as expected. + +## 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 +paths: + ## Config Paths ## + + + ## State Paths ## + + /network-instances/network-instance/afts/ethernet/mac-entry/state/next-hop-group: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/origin-protocol: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/origin-protocol: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix: + /network-instances/network-instance/afts/aft-summaries/ipv4-unicast/protocols/protocol/state/origin-protocol: + /network-instances/network-instance/afts/aft-summaries/ipv6-unicast/protocols/protocol/state/origin-protocol: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/id: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/index: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/index: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/backup-next-hop-group: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/id: + /network-instances/network-instance/afts/next-hops/next-hop/index: + /network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/interface: + /network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/subinterface: + /network-instances/network-instance/afts/next-hops/next-hop/state/encapsulate-header: + /network-instances/network-instance/afts/next-hops/next-hop/state/index: + /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address: + /network-instances/network-instance/afts/next-hops/next-hop/state/mac-address: + /network-instances/network-instance/afts/next-hops/next-hop/state/origin-protocol: + /network-instances/network-instance/afts/state-synced/state/ipv4-unicast: + /network-instances/network-instance/afts/state-synced/state/ipv6-unicast: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/entry-metadata: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group-network-instance: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/origin-network-instance: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/entry-metadata: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group-network-instance: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/origin-network-instance: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/prefix: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/prefix: + +rpcs: + gnmi: + gNMI.Subscribe: +``` + +## Control Protocol Coverage + +BGP +IS-IS +RSVP +MPLS + +## Minimum DUT Platform Requirement + +vRX diff --git a/feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md b/feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md new file mode 100644 index 00000000000..9fce154e4a1 --- /dev/null +++ b/feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md @@ -0,0 +1,178 @@ +# AFT-2.1: AFTs Prefix Counters + +## Summary + +IPv4/IPv6 prefix counters + +## Testbed + +* atedut_2.testbed + +## Test Setup + +### Generate DUT and ATE Configuration + +Configure DUT:port1 for IS-IS session with ATE:port1 +* IS-IS must be level 2 only with wide metric. +* IS-IS must be point to point. +* Send 1000 ipv4 and 1000 ipv6 IS-IS prefixes from ATE:port1 to DUT:port1. + +Establish eBGP sessions between ATE:port1 and DUT:port1. +* Configure eBGP over the interface ip. +* Advertise 1000 ipv4,ipv6 prefixes from ATE port1 observe received prefixes at DUT. + +### Procedure + +* Gnmi set with REPLACE option to push the configuration DUT. +* ATE configuration must be pushed. + +### verifications + +* BGP routes advertised from ATE:port1 must have 1 nexthop. +* IS-IS routes advertised from ATE:port1 must have one next hop. +* Use gnmi Subscribe with ON_CHANGE option to /network-instances/network-instance/afts. +* Verify afts prefix entries using the following paths with in a timeout of 30s. + +/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix, +/network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix + + + +## AFT-2.1.1: AFT Prefix Counters ipv4 packets forwarded, ipv4 octets forwarded IS-IS route. + +### Procedure + +From ATE:port2 send 10000 packets to one of the ipv4 prefix advertise by IS-IS. + +### Verifications + +* Before the traffic measure the initial counter value. +* After the traffic measure the final counter value. +* The difference between final and initial value must match with the counter value in ATE then the test is marked as passed. +* Verify afts ipv4 forwarded packets and ipv4 forwarded octets counter entries using the path mentioned in the paths section of this test plan. + +## AFT-2.1.2: AFT Prefix Counters ipv4 packets forwarded, ipv4 octets forwarded BGP route. + +### Procedure + +From ATE:port2 send 10000 packets to one of the ipv4 prefix advertise by BGP. + +### Verifications + +* Before the traffic measure the initial counter value. +* After the traffic measure the final counter value. +* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. +* Verify afts ipv4 forwarded packets and ipv4 forwarded octets counter entries using the path mentioned in the paths section of this test plan. + + +## AFT-2.1.3: AFT Prefix Counters ipv6 packets forwarded, ipv6 octets forwarded IS-IS route. + +### Procedure + +From ATE:port2 send 10000 packets to one of the ipv6 prefix advertise by IS-IS. + +### Verifications + +* Before the traffic measure the initial counter value. +* After the traffic measure the final counter value. +* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. +* Verify afts ipv6 forwarded packets and ipv6 forwarded octets counter entries using the path mentioned in the paths section of this test plan. + +## AFT-2.1.4: AFT Prefix Counters ipv6 packets forwarded, ipv6 octets forwarded BGP route. + +### Procedure + +From ATE:port2 send 10000 packets to one of the ipv6 prefix advertise by BGP. + +### Verifications + +* Before the traffic measure the initial counter value. +* After the traffic measure the final counter value. +* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. +* Verify afts ipv6 forwarded packets and ipv6 forwarded octets counter entries using the path mentioned in the paths section of this test plan. + +## AFT-2.1.5: AFT Prefix Counters withdraw the ipv4 prefix. + +### Procedure + +* From ATE:port1 withdraw some prefixes of BGP and IS-IS. +* Send 10000 packets from ATE:port2 to DUT:port2 for one of the withdrawn ipv4 prefix. +* The traffic must blackhole. + +### Verifications + +* The counters must not send incremental value as the prefix is not present in RIB/FIB. The test fails if the counter shows incremental values. +* Verify afts ipv4 forwarded packet counter entries using the path mentioned in the paths section of this test plan. + +## AFT-2.1.6: AFT Prefix Counters add the ipv4 prefix back. + +### Procedure + +* From ATE:port1 add the prefixes of BGP and IS-IS back. +* Send 10000 packets from ATE:port2 to DUT:port2 for one of the added ipv4 prefix. +* The traffic must flow end to end. + +### Verifications + +* Before the traffic measure the initial counter value. +* After the traffic measure the final counter value. +* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. +* Verify afts counter entries using the path mentioned in the paths section of this test plan. + +## AFT-2.1.7: AFT Prefix Counters withdraw the ipv6 prefix. + +### Procedure + +* From ATE:port1 withdraw some prefixes of BGP and IS-IS. +* Send 10000 packets from ATE:port2 to DUT:port2 for one of the withdrawn ipv6 prefix. +* The traffic must blackhole. + +### Verifications + +* The counters must not send incremental value as the prefix is not present in RIB/FIB. The test fails if the counter shows incremental values. +* Verify afts counter entries using the path mentioned in the paths section of this test plan. + +## AFT-2.1.8: AFT Prefix Counters add the ipv6 prefix back. + +### Procedure + +* From ATE:port1 add the prefixes of BGP and IS-IS back. +* Send 10000 packets from ATE:port2 to DUT:port2 for one of the added ipv6 prefix. +* The traffic must flow end to end. + +### Verifications + +* Before the traffic measure the initial counter value. +* After the traffic measure the final counter value. +* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. +* Verify afts counter entries using the path mentioned in the paths section of this test plan. + +## 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 +paths: + ## Config Paths ## + + ## State Paths ## + + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/counters/octets-forwarded: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/counters/packets-forwarded: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/counters/octets-forwarded: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/counters/packets-forwarded: + + +rpcs: + gnmi: + gNMI.Subscribe: +``` + +## Control Protocol Coverage + +BGP +IS-IS + +## Minimum DUT Platform Requirement + +vRX \ No newline at end of file diff --git a/feature/aft/aft_summary/otg_tests/route_summary_counters_test/README.md b/feature/aft/afts_summary/otg_tests/route_summary_counters_test/README.md similarity index 100% rename from feature/aft/aft_summary/otg_tests/route_summary_counters_test/README.md rename to feature/aft/afts_summary/otg_tests/route_summary_counters_test/README.md diff --git a/feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto b/feature/aft/afts_summary/otg_tests/route_summary_counters_test/metadata.textproto similarity index 100% rename from feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto rename to feature/aft/afts_summary/otg_tests/route_summary_counters_test/metadata.textproto diff --git a/feature/aft/aft_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go b/feature/aft/afts_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go similarity index 100% rename from feature/aft/aft_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go rename to feature/aft/afts_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go diff --git a/feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md b/feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md new file mode 100644 index 00000000000..e7e416b40e7 --- /dev/null +++ b/feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md @@ -0,0 +1,39 @@ +# RT-4.11: AFTs Route Summary + +## Summary + +IPv4/IPv6 scale unicast AFTs route summary for ISIS and BGP protocol + +## Procedure + +* Configure DUT:port1 for an IS-IS session with ATE:port1 +* Establish eBGP sessions between ATE:port1 and DUT:port1 and another between ATE:port2 and DUT:port2 +* Configure Route-policy under BGP peer-group address-family +* Advertise scale prefixes from ATE port-1, port-2 observe received prefixes at DUT for IPv4 and IPv6 +* Validate total number of entries of AFT for IPv4 and IPv6 + +## 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 +paths: + ## Config Paths ## + + ## State Paths ## + /network-instances/network-instance/afts/aft-summaries/ipv4-unicast/protocols/protocol/state/counters/aft-entries: + /network-instances/network-instance/afts/aft-summaries/ipv6-unicast/protocols/protocol/state/counters/aft-entries: + +rpcs: + gnmi: + gNMI.Subscribe: +``` + +## Control Protocol Coverage + +BGP +IS-IS + +## Minimum DUT Platform Requirement + +vRX diff --git a/feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto b/feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto new file mode 100644 index 00000000000..d61d4590b2b --- /dev/null +++ b/feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto @@ -0,0 +1,54 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "89da0b4c-9a16-44f8-9757-d98ccdd6aaf4" +plan_id: "RT-4.11" +description: "AFTs Route Summary" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + isis_multi_topology_unsupported: true + isis_interface_level1_disable_required: true + missing_isis_interface_afi_safi_enable: true + isis_restart_suppress_unsupported: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + missing_value_for_defaults: true + interface_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + ipv4_missing_enabled: true + isis_interface_level1_disable_required: true + isis_single_topology_required: true + } +} +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + isis_level_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + missing_value_for_defaults: true + interface_enabled: true + default_network_instance: "default" + isis_instance_enabled_required: true + isis_interface_afi_unsupported: true + route_policy_under_afi_unsupported: true + } +} diff --git a/feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go b/feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go new file mode 100644 index 00000000000..e283663711e --- /dev/null +++ b/feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go @@ -0,0 +1,566 @@ +// 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 route_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/isissession" + "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 2001:db8::192:0:2:0/126 +// * Destination: dut:port2 -> ate:port2 subnet 192.0.2.4/30 2001:db8::192:0:2:4/126 +// +// 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 ( + advertisedRoutesv4Prefix = 32 + advertisedRoutesv6Prefix = 128 + dutAS = 65501 + ate1AS = 64501 + ate2AS = 200 + plenIPv4 = 30 + plenIPv6 = 126 + rplType = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE + rplName = "ALLOW" + peerGrpNamev4 = "BGP-PEER-GROUP-V4" + peerGrpNamev6 = "BGP-PEER-GROUP-V6" + peerGrpNamev4P1 = "BGP-PEER-GROUP-V4-P1" + peerGrpNamev6P1 = "BGP-PEER-GROUP-V6-P1" + peerGrpNamev4P2 = "BGP-PEER-GROUP-V4-P2" + peerGrpNamev6P2 = "BGP-PEER-GROUP-V6-P2" + isisRoute = "199.0.0.1" + bgpRoute = "203.0.113.0" + isisRoutev6 = "2001:db8::203:0:113:1" + bgpRoutev6 = "2001:DB8:2::1" + RouteCount = uint32(1000) +) + +var ( + dutP1 = attrs.Attributes{ + Desc: "DUT to ATE source", + IPv4: "192.0.2.1", + IPv6: "2001:db8::1", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + ateP1 = attrs.Attributes{ + Name: "ateP1", + MAC: "02:00:01:01:01:01", + IPv4: "192.0.2.2", + IPv6: "2001:db8::2", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + + dutP2 = attrs.Attributes{ + Desc: "DUT to ATE destination", + IPv4: "192.0.2.5", + IPv6: "2001:db8::5", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + + ateP2 = attrs.Attributes{ + Name: "ateP2", + MAC: "02:00:02:01:01:01", + IPv4: "192.0.2.6", + IPv6: "2001:db8::6", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } +) + +// configureDUT configures all the interfaces and BGP on the DUT. +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + dc := gnmi.OC() + p1 := dut.Port(t, "port1").Name() + i1 := dutP1.NewOCInterface(p1, dut) + gnmi.Replace(t, dut, dc.Interface(p1).Config(), i1) + + p2 := dut.Port(t, "port2").Name() + i2 := dutP2.NewOCInterface(p2, dut) + gnmi.Replace(t, dut, dc.Interface(p2).Config(), i2) + + // Configure Network instance type on DUT + t.Log("Configure/update Network Instance") + 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, p1, deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, p2, deviations.DefaultNetworkInstance(dut), 0) + } + configureRoutePolicy(t, dut, rplName, rplType) + + dutConfPath := dc.NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + dutConf := createBGPNeighborP1(dutAS, ate1AS, dut) + gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) + dutConf = createBGPNeighborP2(dutAS, ate2AS, dut) + gnmi.Update(t, dut, dutConfPath.Config(), dutConf) + ts := isissession.MustNew(t).WithISIS() + ts.ConfigISIS(func(isis *oc.NetworkInstance_Protocol_Isis) { + global := isis.GetOrCreateGlobal() + global.HelloPadding = oc.Isis_HelloPaddingType_DISABLE + + if deviations.ISISSingleTopologyRequired(ts.DUT) { + afv6 := global.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST) + afv6.GetOrCreateMultiTopology().SetAfiName(oc.IsisTypes_AFI_TYPE_IPV4) + afv6.GetOrCreateMultiTopology().SetSafiName(oc.IsisTypes_SAFI_TYPE_UNICAST) + } + }) + ts.ATEIntf1.Isis().Advanced().SetEnableHelloPadding(false) + ts.PushAndStart(t) +} + +type BGPNeighbor struct { + as uint32 + neighborip string + isV4 bool +} + +func createBGPNeighborP1(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { + nbrs := []*BGPNeighbor{ + {as: peerAs, neighborip: ateP1.IPv4, isV4: true}, + {as: peerAs, neighborip: ateP1.IPv6, isV4: false}, + } + + 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(localAs) + global.RouterId = ygot.String(dutP1.IPv4) + + 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. + pgv4 := bgp.GetOrCreatePeerGroup(peerGrpNamev4P1) + pgv4.PeerAs = ygot.Uint32(peerAs) + pgv4.PeerGroupName = ygot.String(peerGrpNamev4P1) + pgv6 := bgp.GetOrCreatePeerGroup(peerGrpNamev6P1) + pgv6.PeerAs = ygot.Uint32(peerAs) + pgv6.PeerGroupName = ygot.String(peerGrpNamev6P1) + + for _, nbr := range nbrs { + if nbr.isV4 { + nv4 := bgp.GetOrCreateNeighbor(nbr.neighborip) + nv4.PeerAs = ygot.Uint32(nbr.as) + nv4.Enabled = ygot.Bool(true) + nv4.PeerGroup = ygot.String(peerGrpNamev4P1) + afisafi := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + afisafi.Enabled = ygot.Bool(true) + nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(false) + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + rpl := pgv4.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + } else { + pgafv4 := pgv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + pgafv4.Enabled = ygot.Bool(true) + rpl := pgafv4.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + } + } else { + nv6 := bgp.GetOrCreateNeighbor(nbr.neighborip) + nv6.PeerAs = ygot.Uint32(nbr.as) + nv6.Enabled = ygot.Bool(true) + nv6.PeerGroup = ygot.String(peerGrpNamev6P1) + afisafi6 := nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + afisafi6.Enabled = ygot.Bool(true) + nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(false) + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + rpl := pgv6.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + } else { + pgafv6 := pgv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + pgafv6.Enabled = ygot.Bool(true) + rpl := pgafv6.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + + } + } + } + return niProto +} + +func createBGPNeighborP2(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { + nbrs := []*BGPNeighbor{ + {as: peerAs, neighborip: ateP2.IPv4, isV4: true}, + {as: peerAs, neighborip: ateP2.IPv6, isV4: false}, + } + + 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(localAs) + global.RouterId = ygot.String(dutP1.IPv4) + + 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. + pgv4 := bgp.GetOrCreatePeerGroup(peerGrpNamev4P2) + pgv4.PeerAs = ygot.Uint32(peerAs) + pgv4.PeerGroupName = ygot.String(peerGrpNamev4P2) + pgv6 := bgp.GetOrCreatePeerGroup(peerGrpNamev6P2) + pgv6.PeerAs = ygot.Uint32(peerAs) + pgv6.PeerGroupName = ygot.String(peerGrpNamev6P2) + + for _, nbr := range nbrs { + if nbr.isV4 { + nv4 := bgp.GetOrCreateNeighbor(nbr.neighborip) + nv4.PeerAs = ygot.Uint32(nbr.as) + nv4.Enabled = ygot.Bool(true) + nv4.PeerGroup = ygot.String(peerGrpNamev4P2) + afisafi := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + afisafi.Enabled = ygot.Bool(true) + nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(false) + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + rpl := pgv4.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + } else { + pgafv4 := pgv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + pgafv4.Enabled = ygot.Bool(true) + rpl := pgafv4.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + } + } else { + nv6 := bgp.GetOrCreateNeighbor(nbr.neighborip) + nv6.PeerAs = ygot.Uint32(nbr.as) + nv6.Enabled = ygot.Bool(true) + nv6.PeerGroup = ygot.String(peerGrpNamev6P2) + afisafi6 := nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + afisafi6.Enabled = ygot.Bool(true) + nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(false) + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + rpl := pgv6.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + } else { + pgafv6 := pgv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + pgafv6.Enabled = ygot.Bool(true) + rpl := pgafv6.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{rplName} + rpl.ExportPolicy = []string{rplName} + + } + } + } + return niProto +} + +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) + } + st.GetOrCreateActions().PolicyResult = pr + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) +} + +func waitForBGPSession(t *testing.T, dut *ondatra.DUTDevice, wantEstablished bool) { + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + nbrPath := statePath.Neighbor(ateP2.IPv4) + nbrPathv6 := statePath.Neighbor(ateP2.IPv6) + compare := func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + if ok { + if wantEstablished { + t.Logf("BGP session state: %s", state.String()) + return state == oc.Bgp_Neighbor_SessionState_ESTABLISHED + } + return state == oc.Bgp_Neighbor_SessionState_IDLE + } + return false + } + + _, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), 2*time.Minute, compare).Await(t) + if !ok { + fptest.LogQuery(t, "BGP reported state", nbrPath.State(), gnmi.Get(t, dut, nbrPath.State())) + if wantEstablished { + t.Fatal("No BGP neighbor formed...") + } else { + t.Fatal("BGPv4 session didn't teardown.") + } + } + _, ok = gnmi.Watch(t, dut, nbrPathv6.SessionState().State(), 2*time.Minute, compare).Await(t) + if !ok { + fptest.LogQuery(t, "BGPv6 reported state", nbrPathv6.State(), gnmi.Get(t, dut, nbrPathv6.State())) + if wantEstablished { + t.Fatal("No BGPv6 neighbor formed...") + } else { + t.Fatal("BGPv6 session didn't teardown.") + } + } +} + +func verifyBGPTelemetry(t *testing.T, dut *ondatra.DUTDevice) { + t.Log("Waiting for BGPv4 neighbor to establish...") + waitForBGPSession(t, dut, true) + +} + +func configureATE(t *testing.T) gosnappi.Config { + ate := ondatra.ATE(t, "ate") + ap1 := ate.Port(t, "port1") + ap2 := ate.Port(t, "port2") + config := gosnappi.NewConfig() + // add ports + p1 := config.Ports().Add().SetName(ap1.ID()) + p2 := config.Ports().Add().SetName(ap2.ID()) + // add devices + d1 := config.Devices().Add().SetName("p1.d1") + d2 := config.Devices().Add().SetName("p2.d1") + // Configuration on port1. + d1Eth1 := d1.Ethernets(). + Add(). + SetName("p1.d1.eth1"). + SetMac("00:00:02:02:02:02"). + SetMtu(1500) + d1Eth1. + Connection(). + SetPortName(p1.Name()) + + d1ipv41 := d1Eth1. + Ipv4Addresses(). + Add(). + SetName("p1.d1.eth1.ipv4"). + SetAddress("192.0.2.2"). + SetGateway("192.0.2.1"). + SetPrefix(30) + + d1ipv61 := d1Eth1. + Ipv6Addresses(). + Add(). + SetName("p1.d1.eth1.ipv6"). + SetAddress("2001:db8::2"). + SetGateway("2001:db8::1"). + SetPrefix(126) + + // isis router + d1isis := d1.Isis(). + SetName("p1.d1.isis"). + SetSystemId("650000000001") + d1isis.Basic(). + SetIpv4TeRouterId(d1ipv41.Address()). + SetHostname("ixia-c-port1") + d1isis.Advanced().SetAreaAddresses([]string{"49"}) + d1isisint := d1isis.Interfaces(). + Add(). + SetName("p1.d1.isis.intf"). + SetEthName(d1Eth1.Name()). + SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). + SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2). + SetMetric(10) + d1isisint.TrafficEngineering().Add().PriorityBandwidths() + d1isisint.Advanced().SetAutoAdjustMtu(true).SetAutoAdjustArea(true).SetAutoAdjustSupportedProtocols(true) + + d1IsisRoute1 := d1isis.V4Routes().Add().SetName("p1.d1.isis.rr1") + d1IsisRoute1.Addresses(). + Add(). + SetAddress(isisRoute). + SetPrefix(32).SetCount(RouteCount) + + d1IsisRoute1v6 := d1isis.V6Routes().Add().SetName("p1.d1.isis.rr1.v6") + d1IsisRoute1v6.Addresses(). + Add(). + SetAddress(isisRoutev6). + SetPrefix(126).SetCount(RouteCount) + + configureBGPDev(d1, d1ipv41, d1ipv61, ate1AS) + + // configuration on port2 + d2Eth1 := d2.Ethernets(). + Add(). + SetName("p2.d1.eth1"). + SetMac("00:00:03:03:03:03"). + SetMtu(1500) + d2Eth1. + Connection(). + SetPortName(p2.Name()) + d2ipv41 := d2Eth1.Ipv4Addresses(). + Add(). + SetName("p2.d1.eth1.ipv4"). + SetAddress("192.0.2.6"). + SetGateway("192.0.2.5"). + SetPrefix(30) + + d2ipv61 := d2Eth1. + Ipv6Addresses(). + Add(). + SetName("p2.d1.eth1.ipv6"). + SetAddress("2001:db8::6"). + SetGateway("2001:db8::5"). + SetPrefix(126) + + // isis router + d2isis := d2.Isis(). + SetName("p2.d1.isis"). + SetSystemId("650000000001") + d2isis.Basic(). + SetIpv4TeRouterId(d2ipv41.Address()). + SetHostname("ixia-c-port2") + d2isis.Advanced().SetAreaAddresses([]string{"49"}) + d2isisint := d2isis.Interfaces(). + Add(). + SetName("p2.d1.isis.intf"). + SetEthName(d2Eth1.Name()). + SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). + SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2). + SetMetric(10) + d2isisint.TrafficEngineering().Add().PriorityBandwidths() + d2isisint.Advanced().SetAutoAdjustMtu(true).SetAutoAdjustArea(true).SetAutoAdjustSupportedProtocols(true) + + d2IsisRoute1 := d2isis.V4Routes().Add().SetName("p2.d1.isis.rr1") + d2IsisRoute1.Addresses(). + Add(). + SetAddress(isisRoute). + SetPrefix(32). + SetCount(RouteCount) + + d2IsisRoute1V6 := d2isis.V6Routes().Add().SetName("p2.d1.isis.rr1.v6") + d2IsisRoute1V6.Addresses(). + Add(). + SetAddress(isisRoutev6). + SetPrefix(126). + SetCount(RouteCount) + + configureBGPDev(d2, d2ipv41, d2ipv61, ate2AS) + + return config +} + +// configureBGPDev configures the BGP on the OTG dev +func configureBGPDev(dev gosnappi.Device, Ipv4 gosnappi.DeviceIpv4, Ipv6 gosnappi.DeviceIpv6, as int) { + + Bgp := dev.Bgp().SetRouterId(Ipv4.Address()) + Bgp4Peer := Bgp.Ipv4Interfaces().Add().SetIpv4Name(Ipv4.Name()).Peers().Add().SetName(dev.Name() + ".BGP4.peer") + Bgp4Peer.SetPeerAddress(Ipv4.Gateway()).SetAsNumber(uint32(as)).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + Bgp6Peer := Bgp.Ipv6Interfaces().Add().SetIpv6Name(Ipv6.Name()).Peers().Add().SetName(dev.Name() + ".BGP6.peer") + Bgp6Peer.SetPeerAddress(Ipv6.Gateway()).SetAsNumber(uint32(as)).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + + configureBGPv4Routes(Bgp4Peer, Ipv4.Address(), Bgp4Peer.Name()+"v4route", bgpRoute, RouteCount) + configureBGPv6Routes(Bgp6Peer, Ipv6.Address(), Bgp6Peer.Name()+"v6route", bgpRoutev6, RouteCount) + +} + +func configureBGPv4Routes(peer gosnappi.BgpV4Peer, ipv4 string, name string, prefix string, count uint32) { + routes := peer.V4Routes().Add().SetName(name) + routes.SetNextHopIpv4Address(ipv4). + SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). + SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) + routes.Addresses().Add(). + SetAddress(prefix). + SetPrefix(advertisedRoutesv4Prefix). + SetCount(count) +} + +func configureBGPv6Routes(peer gosnappi.BgpV6Peer, ipv6 string, name string, prefix string, count uint32) { + routes := peer.V6Routes().Add().SetName(name) + routes.SetNextHopIpv6Address(ipv6). + SetNextHopAddressType(gosnappi.BgpV6RouteRangeNextHopAddressType.IPV6). + SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) + routes.Addresses().Add(). + SetAddress(prefix). + SetPrefix(advertisedRoutesv6Prefix). + SetCount(count) +} +func VerifyDUT(t *testing.T, dut *ondatra.DUTDevice) { + + dni := deviations.DefaultNetworkInstance(dut) + if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv4Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { + t.Errorf("ipv4 BGP entries, got: %d, want: %d", got, RouteCount) + } else { + t.Logf("Test case Passed: ipv4 BGP entries, got: %d, want: %d", got, RouteCount) + } + if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv6Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { + t.Errorf("ipv6 BGP entries, got: %d, want: %d", got, RouteCount) + } else { + t.Logf("Test case Passed:ipv6 BGP entries, got: %d, want: %d", got, RouteCount) + } + + if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv4Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { + t.Errorf("ipv4 isis entries, got: %d, want: %d", got, RouteCount) + } else { + t.Logf("Test case Passed: ipv4 isis entries, got: %d, want: %d", got, RouteCount) + + } + + if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv6Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { + t.Errorf("ipv6 isis entries, got: %d, want: %d", got, RouteCount) + } else { + t.Logf("Test case Passed: ipv6 isis entries, got: %d, want: %d", got, RouteCount) + } +} + +func TestBGP(t *testing.T) { + + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + // DUT Configuration + t.Log("Start DUT interface Config") + configureDUT(t, dut) + // ATE Configuration. + t.Log("Start ATE Config") + config := configureATE(t) + ate.OTG().PushConfig(t, config) + time.Sleep(time.Second * 20) + ate.OTG().StartProtocols(t) + time.Sleep(time.Second * 20) + verifyBGPTelemetry(t, dut) + VerifyDUT(t, dut) +} diff --git a/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go b/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go index d40b62036ec..bdecdb40c3b 100644 --- a/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go +++ b/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go @@ -112,6 +112,8 @@ func bgpCreateNbr(t *testing.T, dut *ondatra.DUTDevice) *oc.NetworkInstance_Prot global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutPort2.IPv4) global.As = ygot.Uint32(dutGlobalAS) + 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. @@ -122,6 +124,7 @@ func bgpCreateNbr(t *testing.T, dut *ondatra.DUTDevice) *oc.NetworkInstance_Prot pg.PeerAs = ygot.Uint32(nbr.PeerAS) pg.LocalAs = ygot.Uint32(nbr.LocalAS) pg.PeerGroupName = ygot.String(nbr.PeerGrp) + pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) nv4 := bgp.GetOrCreateNeighbor(nbr.Neighborip) nv4.PeerGroup = ygot.String(nbr.PeerGrp) @@ -218,6 +221,7 @@ func advBGPRouteFromOTG(t *testing.T, args *otgTestArgs, asSeg []uint32) { // sent and received IPv4 prefixes. func verifyPrefixesTelemetry(t *testing.T, dut *ondatra.DUTDevice, nbr string, wantInstalled, wantSent uint32) { t.Helper() + time.Sleep(15 * time.Second) 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 { @@ -232,15 +236,15 @@ func verifyPrefixesTelemetry(t *testing.T, dut *ondatra.DUTDevice, nbr string, w 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") + pdef := rp.GetOrCreatePolicyDefinition(name) + stmt, err := pdef.AppendNewStatement(name) if err != nil { - t.Fatal(err) + t.Fatalf("AppendNewStatement(%s) failed: %v", name, 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) + stmt.GetOrCreateActions().PolicyResult = pr + // stmt.GetOrCreateConditions().InstallProtocolEq = oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + } // verifyOTGPrefixTelemetry is to Validate prefix received on OTG por2. @@ -325,7 +329,6 @@ func testSplitHorizonAllowOwnAs3(t *testing.T, args *otgTestArgs) { t.Log("Validate session state and capabilities received on DUT using telemetry.") cfgplugins.VerifyDUTBGPEstablished(t, args.dut) cfgplugins.VerifyBGPCapabilities(t, args.dut, []*cfgplugins.BgpNeighbor{nbr1, nbr2}) - t.Log("Verify that the DUT accepts the route.") verifyPrefixesTelemetry(t, args.dut, nbr1.Neighborip, 1, 0) verifyPrefixesTelemetry(t, args.dut, nbr2.Neighborip, 0, 1) @@ -440,8 +443,7 @@ func TestBGPOverrideASPathSplitHorizon(t *testing.T) { }) t.Run("Configure DEFAULT network instance", func(t *testing.T) { - dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) - gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) + fptest.ConfigureDefaultNetworkInstance(t, dut) }) dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") diff --git a/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go b/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go index c7031776efc..a1205cfa0c0 100644 --- a/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go +++ b/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go @@ -123,7 +123,7 @@ var ( "linkbw_any": "^.*:.*$", } - CommunitySet = map[string]string{ + communitySet = map[string]string{ "regex_match_comm100": "^100:.*$", } ) @@ -182,35 +182,65 @@ func TestBGPLinkBandwidth(t *testing.T) { } baseSetupConfigAndVerification(t, td) configureExtCommunityRoutingPolicy(t, dut) - if deviations.BgpExplicitExtendedCommunityEnable(dut) { - enableExtCommunityCLIConfig(t, dut) - } + enableExtCommunityCLIConfig(t, dut) + testCases := []testCase{ { - name: "Policy set not_match_100_set_linkbw_1M", + name: "ImportPolicy 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:23456:0"}, + applyPolicy: applyImportPolicyDut, + validate: validateImportPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "link-bandwidth:23456:1000000", prefixSet2Comm: "100:100", prefixSet3Comm: "link-bandwidth:23456:1000000"}, localPerf: false, validateRouteCommunityV4: validateRouteCommunityV4, validateRouteCommunityV6: validateRouteCommunityV6, }, { - name: "Policy set match_100_set_linkbw_2G", + name: "ExportPolicy set not_match_100_set_linkbw_1M", + policyName: "not_match_100_set_linkbw_1M", + applyPolicy: applyExportPolicyDut, + validate: validateExportPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "link-bandwidth:23456:1000000", prefixSet2Comm: "100:100", prefixSet3Comm: "link-bandwidth:23456:1000000"}, + localPerf: false, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + { + name: "ImportPolicy set match_100_set_linkbw_2G", policyName: "match_100_set_linkbw_2G", - applyPolicy: applyPolicyDut, - validate: validatPolicyDut, - routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "link-bandwidth:23456:2000000000", prefixSet3Comm: "link-bandwidth:23456:0"}, + applyPolicy: applyImportPolicyDut, + validate: validateImportPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "link-bandwidth:23456:2000000000", prefixSet3Comm: "link-bandwidth:23456:1000"}, localPerf: false, validateRouteCommunityV4: validateRouteCommunityV4, validateRouteCommunityV6: validateRouteCommunityV6, }, + { - name: "Policy set del_linkbw", + name: "ExportPolicy set match_100_set_linkbw_2G", + policyName: "match_100_set_linkbw_2G", + applyPolicy: applyExportPolicyDut, + validate: validateExportPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "link-bandwidth:23456:2000000000", prefixSet3Comm: "link-bandwidth:23456:1000"}, + localPerf: false, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + { + name: "ImportPolicy set del_linkbw", policyName: "del_linkbw", - applyPolicy: applyPolicyDut, - validate: validatPolicyDut, + applyPolicy: applyImportPolicyDut, + validate: validateImportPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "none"}, + localPerf: false, + validateRouteCommunityV4: validateRouteCommunityV4, + validateRouteCommunityV6: validateRouteCommunityV6, + }, + { + name: "ExportPolicy set del_linkbw", + policyName: "del_linkbw", + applyPolicy: applyExportPolicyDut, + validate: validateExportPolicyDut, routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "none"}, localPerf: false, validateRouteCommunityV4: validateRouteCommunityV4, @@ -229,25 +259,41 @@ func TestBGPLinkBandwidth(t *testing.T) { } func enableExtCommunityCLIConfig(t *testing.T, dut *ondatra.DUTDevice) { - var extCommunityEnableCLIConfig string - switch dut.Vendor() { - case ondatra.CISCO: - extCommunityEnableCLIConfig = fmt.Sprintf("router bgp %v instance BGP neighbor-group %v \n ebgp-recv-extcommunity-dmz \n ebgp-send-extcommunity-dmz\n", dutAS, cfgplugins.BGPPeerGroup1) - default: - t.Fatalf("Unsupported vendor %s for deviation 'BgpExplicitExtendedCommunityEnable'", dut.Vendor()) - } - helpers.GnmiCLIConfig(t, dut, extCommunityEnableCLIConfig) + if deviations.BgpExplicitExtendedCommunityEnable(dut) { + var extCommunityEnableCLIConfig string + switch dut.Vendor() { + case ondatra.CISCO: + extCommunityEnableCLIConfig = fmt.Sprintf("router bgp %v instance BGP neighbor-group %v \n ebgp-recv-extcommunity-dmz \n ebgp-send-extcommunity-dmz\n", dutAS, cfgplugins.BGPPeerGroup1) + default: + t.Fatalf("Unsupported vendor %s for deviation 'BgpExplicitExtendedCommunityEnable'", dut.Vendor()) + } + helpers.GnmiCLIConfig(t, dut, extCommunityEnableCLIConfig) + } } -func applyPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { - // Apply ipv4 policy to bgp neighbour. +func removeImportAndExportPolicy(t *testing.T, dut *ondatra.DUTDevice) { + dni := deviations.DefaultNetworkInstance(dut) + + bd := &gnmi.SetBatch{} + path1 := 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() + path2 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort2.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + path3 := 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() + path4 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort2.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + gnmi.BatchDelete(bd, path1.Config()) + gnmi.BatchDelete(bd, path2.Config()) + gnmi.BatchDelete(bd, path3.Config()) + gnmi.BatchDelete(bd, path4.Config()) + bd.Set(t, dut) +} + +func applyImportPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { 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() + removeImportAndExportPolicy(t, dut) - 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() + // Apply ipv4 policy to bgp neighbour. + 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) @@ -269,13 +315,70 @@ func applyPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config(), niProto) } -func validatPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { +func applyExportPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { + root := &oc.Root{} + dni := deviations.DefaultNetworkInstance(dut) + removeImportAndExportPolicy(t, dut) + + // Apply ipv4 policy to bgp neighbour. + path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort2.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort2.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() + policy.SetExportPolicy([]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(atePort2.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() + policy = root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort2.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() + policy.SetExportPolicy([]string{policyName}) + gnmi.Replace(t, dut, path.Config(), policy) + + ni := root.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + niProto := ni.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() + bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + bgpNbrV4 := bgp.GetOrCreateNeighbor(atePort1.IPv4) + bgpNbrV4.PeerGroup = ygot.String(cfgplugins.BGPPeerGroup1) + bgpNbrV6 := bgp.GetOrCreateNeighbor(atePort1.IPv6) + bgpNbrV6.PeerGroup = ygot.String(cfgplugins.BGPPeerGroup1) + gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config(), niProto) +} + +func validateImportPolicyDut(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}) + _, ok := gnmi.Watch(t, dut, path.State(), 30*time.Second, func(v *ygnmi.Value[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy]) bool { + value, ok := v.Val() + if !ok { + return false + } + importPolicies := value.GetImportPolicy() + if len(importPolicies) != 1 || importPolicies[0] != policyName { + return false + } + return true + }).Await(t) + if !ok { + t.Fatalf("invalid import policy") + } +} + +func validateExportPolicyDut(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(atePort2.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() + _, ok := gnmi.Watch(t, dut, path.State(), 30*time.Second, func(v *ygnmi.Value[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy]) bool { + value, ok := v.Val() + if !ok { + return false + } + exportPolicies := value.GetExportPolicy() + if len(exportPolicies) != 1 || exportPolicies[0] != policyName { + return false + } + return true + }).Await(t) + if !ok { + t.Fatalf("invalid export policy") } } @@ -325,20 +428,19 @@ func validateRouteCommunityV4Prefix(t *testing.T, td testData, community, v4Pref for _, ec := range bgpPrefix.ExtendedCommunity { lbSubType := ec.Structured.NonTransitive_2OctetAsType.LinkBandwidthSubtype listCommunity := strings.Split(community, ":") - Bandwidth := listCommunity[2] + bandwidth := listCommunity[2] if lbSubType.GetGlobal_2ByteAs() != 23456 && lbSubType.GetGlobal_2ByteAs() != 32002 && lbSubType.GetGlobal_2ByteAs() != 32001 { t.Errorf("ERROR AS number should be 23456 or %d got %d", ateAS, lbSubType.GetGlobal_2ByteAs()) return } - if Bandwidth == "0" { - if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 0 { - t.Errorf("ERROR lb Bandwidth want 0, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } - } else { - if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { - t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } + if bandwidth == "1000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) == 0 { + t.Errorf("ERROR lb Bandwidth want 1000, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } else if bandwidth == "1000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 125000 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 1000000 { + t.Errorf("ERROR lb Bandwidth want :1M, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } else if bandwidth == "2000000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { + t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) } + if !deviations.BgpExtendedCommunityIndexUnsupported(td.dut) { verifyExtCommunityIndexV4(t, td, v4Prefix) } @@ -361,7 +463,6 @@ func validateRouteCommunityV6(t *testing.T, td testData, ec extCommunity) { } func validateRouteCommunityV6Prefix(t *testing.T, td testData, community, v6Prefix string) { - // This function to verify received route communities on ATE ports. _, ok := gnmi.WatchAll(t, td.ate.OTG(), @@ -396,19 +497,17 @@ func validateRouteCommunityV6Prefix(t *testing.T, td testData, community, v6Pref for _, ec := range bgpPrefix.ExtendedCommunity { lbSubType := ec.Structured.NonTransitive_2OctetAsType.LinkBandwidthSubtype listCommunity := strings.Split(community, ":") - Bandwidth := listCommunity[2] + bandwidth := listCommunity[2] if lbSubType.GetGlobal_2ByteAs() != 23456 && lbSubType.GetGlobal_2ByteAs() != 32002 && lbSubType.GetGlobal_2ByteAs() != 32001 { t.Errorf("ERROR AS number should be 23456 or %d got %d", ateAS, lbSubType.GetGlobal_2ByteAs()) return } - if Bandwidth == "0" { - if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 0 { - t.Errorf("ERROR lb Bandwidth want 0, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } - } else { - if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { - t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } + if bandwidth == "1000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) == 0 { + t.Errorf("ERROR lb Bandwidth want 1000, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } else if bandwidth == "1000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 125000 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 1000000 { + t.Errorf("ERROR lb Bandwidth want :1M, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } else if bandwidth == "2000000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { + t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) } if !deviations.BgpExtendedCommunityIndexUnsupported(td.dut) { verifyExtCommunityIndexV6(t, td, v6Prefix) @@ -419,6 +518,7 @@ func validateRouteCommunityV6Prefix(t *testing.T, td testData, community, v6Pref } } } + func configureImportRoutingPolicyAllowAll(t *testing.T, dut *ondatra.DUTDevice) { root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() @@ -509,26 +609,10 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { root := &oc.Root{} var communitySetCLIConfig string var extCommunitySetCLIConfig string - switch dut.Vendor() { - case ondatra.CISCO: - extCommunitySet = extCommunitySetCisco - default: - t.Logf("extCommunitySet = %v", extCommunitySet) - } - if !deviations.BgpExtendedCommunitySetUnsupported(dut) { - 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) - } - } else { + if deviations.BgpExtendedCommunitySetUnsupported(dut) { switch dut.Vendor() { case ondatra.CISCO: + extCommunitySet = extCommunitySetCisco for name, community := range extCommunitySet { if name == "linkbw_any" && deviations.CommunityMemberRegexUnsupported(dut) { communitySetCLIConfig = fmt.Sprintf("community-set %v \n dfa-regex '%v' \n end-set", name, community) @@ -541,45 +625,55 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { default: t.Fatalf("Unsupported vendor %s for native command support for deviation 'BgpExtendedCommunitySetUnsupported'", dut.Vendor()) } - } - - if !(deviations.CommunityMemberRegexUnsupported(dut)) { - for name, community := range CommunitySet { + } else { + for name, community := range extCommunitySet { rp := root.GetOrCreateRoutingPolicy() pdef := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets() - stmt, err := pdef.NewCommunitySet(name) + stmt, err := pdef.NewExtCommunitySet(name) if err != nil { - t.Fatalf("NewCommunitySet failed: %v", err) + t.Fatalf("NewExtCommunitySet failed: %v", err) } - cs := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} - cs = append(cs, oc.UnionString(community)) - stmt.SetCommunityMember(cs) + stmt.SetExtCommunityMember([]string{community}) gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) } - } else { + } + + if deviations.CommunityMemberRegexUnsupported(dut) { switch dut.Vendor() { case ondatra.CISCO: - for name, community := range CommunitySet { + for name, community := range communitySet { communitySetCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v' \n end-set", name, community) helpers.GnmiCLIConfig(t, dut, communitySetCLIConfig) } default: t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'CommunityMemberRegexUnsupported'", dut.Vendor()) } + } else { + for name, community := range communitySet { + rp := root.GetOrCreateRoutingPolicy() + pdef := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets() + stmt, err := pdef.NewCommunitySet(name) + if err != nil { + t.Fatalf("NewCommunitySet failed: %v", err) + } + cs := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + cs = append(cs, oc.UnionString(community)) + stmt.SetCommunityMember(cs) + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) + } } // 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") + pdef2Stmt1, err := pdef2.AppendNewStatement("regex_match_comm100_rm_lbw") if err != nil { - t.Fatalf("AppendNewStatement 1-megabit-match failed: %v", err) + t.Fatalf("AppendNewStatement regex_match_comm100_rm_lbw failed: %v", err) } - if !deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { ref := pdef2Stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() - ref.GetOrCreateReference().SetExtCommunitySetRefs([]string{"linkbw_1M"}) - ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + ref.GetOrCreateReference().SetExtCommunitySetRefs([]string{"linkbw_any"}) + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_REMOVE) ref.SetMethod(oc.SetCommunity_Method_REFERENCE) } if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { @@ -608,25 +702,51 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { if !deviations.SkipSettingStatementForPolicy(dut) { pdef2Stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) } - pdef2Stmt2, err := pdef2.AppendNewStatement("accept_all_routes") + + pdef2Stmt2, err := pdef2.AppendNewStatement("regex_match_comm100_add_lbw") if err != nil { - t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) + t.Fatalf("AppendNewStatement regex_match_comm100_add_lbw failed: %v", err) } - pdef2Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) - if !deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpNotMatch) + ref := pdef2Stmt2.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() + ref.GetOrCreateReference().SetExtCommunitySetRefs([]string{"linkbw_1M"}) + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) + ref.SetMethod(oc.SetCommunity_Method_REFERENCE) + } + if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { + switch dut.Vendor() { + case ondatra.ARISTA: + ref1 := pdef2Stmt2.GetOrCreateConditions().GetOrCreateBgpConditions() + ref1.SetCommunitySet("regex_match_comm100_deviation1") + } } else { + ref1 := pdef2Stmt2.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet() + ref1.SetCommunitySet("regex_match_comm100") + ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_INVERT) + } + if !deviations.SkipSettingStatementForPolicy(dut) { + pdef2Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) + } + + pdef2Stmt3, err := pdef2.AppendNewStatement("accept_all_routes") + if err != nil { + t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) + } + pdef2Stmt3.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + + if deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { switch dut.Vendor() { case ondatra.CISCO: var communityCLIConfig string - communityCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match invert \n end-set", "regex_match_comm100", CommunitySet["regex_match_comm100"]) + communityCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match invert \n end-set", "regex_match_comm100", communitySet["regex_match_comm100"]) policySetCLIConfig := fmt.Sprintf("route-policy %v \n #statement-1 1-megabit-match \n if community is-empty then \n pass \n elseif community in %v then \n set extcommunity bandwidth %v \n endif \n pass \n #statement-2 accept_all_routes \n done \n end-policy", "not_match_100_set_linkbw_1M", "regex_match_comm100", "linkbw_1M") helpers.GnmiCLIConfig(t, dut, communityCLIConfig) helpers.GnmiCLIConfig(t, dut, policySetCLIConfig) default: t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'BgpSetExtCommunitySetRefsUnsupported'", dut.Vendor()) } + } else { + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpNotMatch) } // Configure routing policy match_100_set_linkbw_2G. @@ -661,7 +781,7 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { ref1.SetCommunitySet("regex_match_comm100_deviation2") } } else { - ref1 := pdef3Stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetMatchCommunitySet() + ref1 := pdef3Stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet() ref1.SetCommunitySet("regex_match_comm100") ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_ANY) } @@ -673,18 +793,18 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) } pdef3Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) - if !deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpMatch) - } else { + if deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { switch dut.Vendor() { case ondatra.CISCO: - communitySetCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match any \n end-set", "regex_match_any_comm100", CommunitySet["regex_match_comm100"]) + communitySetCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match any \n end-set", "regex_match_any_comm100", communitySet["regex_match_comm100"]) helpers.GnmiCLIConfig(t, dut, communitySetCLIConfig) communitySetCLIConfig = fmt.Sprintf("route-policy %v \n #statement-1 2-gigabit-match \n if community in %v then \n set extcommunity bandwidth %v \n endif \n pass \n #statement-2 accept_all_routes \n done \n end-policy", "match_100_set_linkbw_2G", "regex_match_any_comm100", "linkbw_2G") helpers.GnmiCLIConfig(t, dut, communitySetCLIConfig) default: t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'BgpSetExtCommunitySetRefsUnsupported' and 'BGPConditionsMatchCommunitySetUnsupported' and 'SkipSettingStatementForPolicy'", dut.Vendor()) } + } else { + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpMatch) } // Configure routing policy del_linkbw. @@ -708,9 +828,7 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) } pdef4Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) - if !deviations.BgpDeleteLinkBandwidthUnsupported(dut) { - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpDelLinkbw) - } else { + if deviations.BgpDeleteLinkBandwidthUnsupported(dut) { var delLinkbwCLIConfig string switch dut.Vendor() { case ondatra.CISCO: @@ -719,7 +837,11 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'BgpDeleteLinkBandwidthUnsupported'", dut.Vendor()) } helpers.GnmiCLIConfig(t, dut, delLinkbwCLIConfig) + } else { + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpDelLinkbw) } + + fptest.LogQuery(t, "", gnmi.OC().RoutingPolicy().Config(), root) } func createFlow(t *testing.T, td testData, fc flowConfig) { @@ -801,7 +923,7 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { nV42 := bgp.GetOrCreateNeighbor(atePort2.IPv4) nV42.SetPeerAs(dutAS) if !deviations.SkipBgpSendCommunityType(td.dut) { - nV42.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_BOTH}) + nV42.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_STANDARD, oc.Bgp_CommunityType_EXTENDED}) } nV42.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) nV61 := bgp.GetOrCreateNeighbor(atePort1.IPv6) @@ -810,7 +932,7 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { nV62 := bgp.GetOrCreateNeighbor(atePort2.IPv6) nV62.SetPeerAs(dutAS) if !deviations.SkipBgpSendCommunityType(td.dut) { - nV62.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_BOTH}) + nV62.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_STANDARD, oc.Bgp_CommunityType_EXTENDED}) } 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) @@ -849,12 +971,12 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { netv43.Addresses().Add().SetAddress(advertisedIPv43.address).SetPrefix(advertisedIPv43.prefix) extcommv4 := netv43.ExtendedCommunities().Add().NonTransitive2OctetAsType().LinkBandwidthSubtype() extcommv4.SetGlobal2ByteAs(23456) - extcommv4.SetBandwidth(0) + extcommv4.SetBandwidth(1000) 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(23456) - extcommv6.SetBandwidth(0) + extcommv6.SetBandwidth(1000) // Configure iBGP on OTG port2. ipv42 := td.otgP2.Ethernets().Items()[0].Ipv4Addresses().Items()[0] diff --git a/feature/gribi/otg_tests/encap_decap_scale/README.md b/feature/gribi/otg_tests/encap_decap_scale/README.md index 050b8bae94a..def619ebb79 100644 --- a/feature/gribi/otg_tests/encap_decap_scale/README.md +++ b/feature/gribi/otg_tests/encap_decap_scale/README.md @@ -326,7 +326,7 @@ network-instances { * Add 1 VRF for decapsulation, `DECAP_TE_VRF`. * Add 2 Tunnel VRFs, `TE_VRF_111` and `TE_VRF_222`. * Inject 5000 IPv4Entry-ies and 5000 IPv6Entry-ies to each of the 4 encap VRFs. - * The entries in the encap VRFs should point to NextHopGroups in the `DEFAULT` VRF. Inject 200 such NextHopGroups in the DEFAULT VRF. + * The entries in the encap VRFs should point to NextHopGroups in the `DEFAULT` VRF. Inject 800 such NextHopGroups in the DEFAULT VRF. * Each NextHopGroup should have 8 NextHops where each NextHop points to a tunnel in the `TE_VRF_111`. In addition, the weights specified in the NextHopGroup should be co-prime and the sum of the weights should be 16. * Inject `48` entries in the DECAP_TE_VRF where the entries have a mix of prefix lengths /22, /24, /26, and /28. @@ -395,7 +395,7 @@ network-instances { * outer_src: `ipv4_outer_src_111` * outer_dst: `ipv4_outer_decap_match` * dscp: `dscp_encap_d` - * proto: `41` + * proto: `41` ``` 3. Send traffic to DUT-1, covering all the installed v4 and v6 entries in the decap and encap VRFs. Validate that all traffic are all decapped per the DECAP VRFs and then encapsulated per the ENCAP VRFs and received as encapsulated packet by ATE. diff --git a/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go b/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go index 22b731e0879..886a2554e2e 100644 --- a/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go +++ b/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go @@ -107,7 +107,7 @@ const ( teVrf111TunnelCount = 1600 teVrf222TunnelCount = 1600 encapNhCount = 1600 - encapNhgcount = 200 + encapNhgcount = 800 encapIPv4Count = 5000 encapIPv6Count = 5000 decapIPv4Count = 48 @@ -368,7 +368,7 @@ func createIPv6Entries(startIP string, count uint64) []string { // pushEncapEntries pushes IP entries in a specified Encap VRFs and tunnel VRFs. // The entries in the encap VRFs should point to NextHopGroups in the DEFAULT VRF. -// Inject 200 such NextHopGroups in the DEFAULT VRF. Each NextHopGroup should have +// Inject 800 such NextHopGroups in the DEFAULT VRF. Each NextHopGroup should have // 8 NextHops where each NextHop points to a tunnel in the TE_VRF_111. // In addition, the weights specified in the NextHopGroup should be co-prime and the // sum of the weights should be 16. diff --git a/feature/isis/otg_tests/weighted_ecmp_test/README.md b/feature/isis/otg_tests/weighted_ecmp_test/README.md index dee5ca53f52..8a5bdf8448a 100644 --- a/feature/isis/otg_tests/weighted_ecmp_test/README.md +++ b/feature/isis/otg_tests/weighted_ecmp_test/README.md @@ -29,23 +29,25 @@ 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 +### Test environment setup + +* Configure 1 aggregate interface with 2 100GE ports between DUT and ATE1 +* Configure 3 aggregate interfaces, each with 2 100GE ports between DUT and ATE2. +* Configure IPv4 and IPv6 L2 adjacencies between DUT and ATE aggregate interfaces. + Therefore, DUT will have + * 1xIS-IS adjacency with ATE1 DUT:LAG1<->ATE1:LAG1, + * 3xIS-IS adjacencies between DUT and ATE2 + * DUT:LAG2<->ATE2:LAG1 + * DUT:LAG3<->ATE2:LAG2 + * DUT:LAG4<->ATE2:LAG3 + + * Set ISIS parameters as + * /network-instances/network-instance/protocols/protocol/isis/global/ + * afi-safi/af/config/afi-name: IPV4, IPV6 + * afi-safi/af/config/safi-name: UNICAST + * afi-safi/af/config/enabled: true + * config/level-capability = LEVEL_2 + * /network-instances/network-instance/protocols/protocol/isis/levels/level/config/metric-style = 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. @@ -74,7 +76,7 @@ In the topology above, * /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 +## RT-2.13.1: Equal distribution of traffic * Start 1024 flows from IPv4 addresses in 100.0.2.0/24 to 100.0.1.0/24 @@ -114,7 +116,7 @@ In the topology above, * /interfaces/interface/state/counters/in-pkts -## RT-9.2: Unequal distribution of traffic +## RT-2.13.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. @@ -142,17 +144,8 @@ In the topology above, * /interfaces/interface/state/counters/in-pkts -### Config paths - -### Telemetry Parameter 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. - -TODO(OCPATH): Container path originally part of spec that needs to be separated -into leaves: /routing-policy/defined-sets/prefix-sets/prefix-set: - ```yaml paths: ## Config Paths ## diff --git a/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto b/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto index caa9410e80a..fb942581ff5 100644 --- a/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto @@ -14,3 +14,14 @@ platform_exceptions: { missing_port_to_optical_channel_component_mapping: true } } +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + otn_channel_trib_unsupported: true + eth_channel_ingress_parameters_unsupported: true + eth_channel_assignment_cisco_numbering: true + otn_channel_assignment_cisco_numbering: true + } +} \ No newline at end of file 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 06dca4f91ed..fdf5d9220e8 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 @@ -1,6 +1,8 @@ package zr_logical_channels_test import ( + "flag" + "strings" "testing" "time" @@ -8,6 +10,7 @@ import ( "github.com/openconfig/featureprofiles/internal/attrs" "github.com/openconfig/featureprofiles/internal/cfgplugins" "github.com/openconfig/featureprofiles/internal/components" + "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/samplestream" "github.com/openconfig/ondatra" @@ -18,7 +21,6 @@ import ( const ( targetOutputPower = -9 frequency = 193100000 - dp16QAM = 1 samplingInterval = 10 * time.Second timeout = 10 * time.Minute otnIndex1 = uint32(4001) @@ -33,21 +35,32 @@ var ( IPv4: "192.0.2.1", IPv4Len: 30, } - dutPort2 = attrs.Attributes{ Desc: "dutPort2", IPv4: "192.0.2.5", IPv4Len: 30, } + operationalModeFlag = flag.Int("operational_mode", 1, "vendor-specific operational-mode for the channel") + operationalMode uint16 ) +type testcase struct { + desc string + got any + want any +} + func TestMain(m *testing.M) { fptest.RunTests(m) } func Test400ZRLogicalChannels(t *testing.T) { dut := ondatra.DUT(t, "dut") - + if operationalModeFlag != nil { + operationalMode = uint16(*operationalModeFlag) + } else { + t.Fatalf("Please specify the vendor-specific operational-mode flag") + } p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") @@ -61,10 +74,10 @@ func Test400ZRLogicalChannels(t *testing.T) { tr1 := gnmi.Get(t, dut, gnmi.OC().Interface(p1.Name()).Transceiver().State()) tr2 := gnmi.Get(t, dut, gnmi.OC().Interface(p2.Name()).Transceiver().State()) - cfgplugins.ConfigOpticalChannel(t, dut, oc1, frequency, targetOutputPower, dp16QAM) + cfgplugins.ConfigOpticalChannel(t, dut, oc1, frequency, targetOutputPower, operationalMode) cfgplugins.ConfigOTNChannel(t, dut, oc1, otnIndex1, ethernetIndex1) cfgplugins.ConfigETHChannel(t, dut, p1.Name(), tr1, otnIndex1, ethernetIndex1) - cfgplugins.ConfigOpticalChannel(t, dut, oc2, frequency, targetOutputPower, dp16QAM) + cfgplugins.ConfigOpticalChannel(t, dut, oc2, frequency, targetOutputPower, operationalMode) cfgplugins.ConfigOTNChannel(t, dut, oc2, otnIndex2, ethernetIndex2) cfgplugins.ConfigETHChannel(t, dut, p2.Name(), tr2, otnIndex2, ethernetIndex2) @@ -80,13 +93,13 @@ func Test400ZRLogicalChannels(t *testing.T) { gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) - validateEthernetChannelTelemetry(t, otnIndex1, ethernetIndex1, ethChan1) - validateEthernetChannelTelemetry(t, otnIndex2, ethernetIndex2, ethChan2) - validateOTNChannelTelemetry(t, otnIndex1, ethernetIndex1, oc1, otnChan1) - validateOTNChannelTelemetry(t, otnIndex2, ethernetIndex2, oc2, otnChan2) + validateEthernetChannelTelemetry(t, dut, otnIndex1, ethernetIndex1, ethChan1) + validateEthernetChannelTelemetry(t, dut, otnIndex2, ethernetIndex2, ethChan2) + validateOTNChannelTelemetry(t, dut, otnIndex1, ethernetIndex1, oc1, otnChan1) + validateOTNChannelTelemetry(t, dut, otnIndex2, ethernetIndex2, oc2, otnChan2) } -func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { +func validateEthernetChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx, ethernetChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { 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") @@ -95,11 +108,7 @@ func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint if !ok { t.Fatalf("Ethernet Channel telemetry stream empty in last 10 seconds") } - tcs := []struct { - desc string - got any - want any - }{ + tcs := []testcase{ { desc: "Index", got: ec.GetIndex(), @@ -120,32 +129,64 @@ func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint got: ec.GetTribProtocol().String(), want: oc.TransportTypes_TRIBUTARY_PROTOCOL_TYPE_PROT_400GE.String(), }, - { - desc: "Assignment: Index", - got: ec.GetAssignment(0).GetIndex(), - want: uint32(0), - }, - { - desc: "Assignment: Logical Channel", - got: ec.GetAssignment(0).GetLogicalChannel(), - want: otnChIdx, - }, - { - desc: "Assignment: Description", - got: ec.GetAssignment(0).GetDescription(), - want: "ETH to OTN", - }, - { - desc: "Assignment: Allocation", - got: ec.GetAssignment(0).GetAllocation(), - want: float64(400), - }, - { - desc: "Assignment: Type", - got: ec.GetAssignment(0).GetAssignmentType().String(), - want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), - }, } + var assignmentIndexTestcases []testcase + + if deviations.EthChannelAssignmentCiscoNumbering(dut) { + assignmentIndexTestcases = []testcase{ + { + desc: "Assignment: Index", + got: ec.GetAssignment(1).GetIndex(), + want: uint32(1)}, + { + desc: "Assignment: Logical Channel", + got: ec.GetAssignment(1).GetLogicalChannel(), + want: otnChIdx, + }, + { + desc: "Assignment: Description", + got: ec.GetAssignment(1).GetDescription(), + want: "ETH to OTN", + }, + { + 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(), + }} + } else { + assignmentIndexTestcases = []testcase{ + { + desc: "Assignment: Index", + got: ec.GetAssignment(0).GetIndex(), + want: uint32(0), + }, + { + desc: "Assignment: Logical Channel", + got: ec.GetAssignment(0).GetLogicalChannel(), + want: otnChIdx, + }, + { + desc: "Assignment: Description", + got: ec.GetAssignment(0).GetDescription(), + want: "ETH to OTN", + }, + { + desc: "Assignment: Allocation", + got: ec.GetAssignment(0).GetAllocation(), + want: float64(400), + }, + { + desc: "Assignment: Type", + got: ec.GetAssignment(0).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), + }} + } + tcs = append(tcs, assignmentIndexTestcases...) for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { if diff := cmp.Diff(tc.got, tc.want); diff != "" { @@ -155,7 +196,7 @@ func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint } } -func validateOTNChannelTelemetry(t *testing.T, otnChIdx uint32, ethChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { +func validateOTNChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx uint32, ethChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { val := stream.Next() // value received in the gnmi subscription within 10 seconds if val == nil { t.Fatalf("OTN Channel telemetry stream not received in last 10 seconds") @@ -164,11 +205,7 @@ func validateOTNChannelTelemetry(t *testing.T, otnChIdx uint32, ethChIdx uint32, if !ok { t.Fatalf("OTN Channel telemetry stream empty in last 10 seconds") } - tcs := []struct { - desc string - got any - want any - }{ + tcs := []testcase{ { desc: "Description", got: cc.GetDescription(), @@ -184,56 +221,97 @@ func validateOTNChannelTelemetry(t *testing.T, otnChIdx uint32, ethChIdx uint32, got: cc.GetLogicalChannelType().String(), want: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_OTN.String(), }, - { - desc: "Optical Channel Assignment: Index", - got: cc.GetAssignment(0).GetIndex(), - want: uint32(0), - }, - { - desc: "Optical Channel Assignment: Optical Channel", - got: cc.GetAssignment(0).GetOpticalChannel(), - want: opticalChannel, - }, - { - desc: "Optical Channel Assignment: Description", - got: cc.GetAssignment(0).GetDescription(), - want: "OTN to Optical Channel", - }, - { - desc: "Optical Channel Assignment: Allocation", - got: cc.GetAssignment(0).GetAllocation(), - want: float64(400), - }, - { - desc: "Optical Channel Assignment: Type", - got: cc.GetAssignment(0).GetAssignmentType().String(), - want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(), - }, - { - desc: "Ethernet Assignment: Index", - got: cc.GetAssignment(1).GetIndex(), - want: uint32(1), - }, - { - desc: "Ethernet Assignment: Logical Channel", - got: cc.GetAssignment(1).GetLogicalChannel(), - want: ethChIdx, - }, - { - desc: "Ethernet Assignment: Description", - got: cc.GetAssignment(1).GetDescription(), - want: "OTN to ETH", - }, - { - desc: "Ethernet Assignment: Allocation", - got: cc.GetAssignment(1).GetAllocation(), - want: float64(400), - }, - { - desc: "Ethernet Assignment: Type", - got: cc.GetAssignment(1).GetAssignmentType().String(), - want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), - }, + } + var opticalChannelAssignmentIndexTestcases []testcase + + if deviations.OTNChannelAssignmentCiscoNumbering(dut) { + ciscoOpticalChannelFormat := strings.ReplaceAll(opticalChannel, "/", "_") // Ex: OpticalChannel0_0_0_18 + opticalChannelAssignmentIndexTestcases = []testcase{ + { + desc: "Assignment: Index", + got: cc.GetAssignment(1).GetIndex(), + want: uint32(1), + }, + { + desc: "Optical Channel Assignment: Optical Channel", + got: cc.GetAssignment(1).GetOpticalChannel(), + want: ciscoOpticalChannelFormat, + }, + { + desc: "Optical Channel Assignment: Description", + got: cc.GetAssignment(1).GetDescription(), + want: "OTN to Optical Channel", + }, + { + desc: "Optical Channel Assignment: Allocation", + got: cc.GetAssignment(1).GetAllocation(), + want: float64(400), + }, + { + desc: "Optical Channel Assignment: Type", + got: cc.GetAssignment(1).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(), + }, + } + } else { + opticalChannelAssignmentIndexTestcases = []testcase{ + { + desc: "Assignment: Index", + got: cc.GetAssignment(0).GetIndex(), + want: uint32(0)}, + { + desc: "Optical Channel Assignment: Optical Channel", + got: cc.GetAssignment(0).GetOpticalChannel(), + want: opticalChannel, + }, + { + desc: "Optical Channel Assignment: Description", + got: cc.GetAssignment(0).GetDescription(), + want: "OTN to Optical Channel", + }, + { + desc: "Optical Channel Assignment: Allocation", + got: cc.GetAssignment(0).GetAllocation(), + want: float64(400), + }, + { + desc: "Optical Channel Assignment: Type", + got: cc.GetAssignment(0).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(), + }, + } + } + tcs = append(tcs, opticalChannelAssignmentIndexTestcases...) + + if !deviations.OTNChannelTribUnsupported(dut) { + logicalChannelAssignmentTestcases := []testcase{ + { + desc: "Ethernet Assignment: Index", + got: cc.GetAssignment(1).GetIndex(), + want: uint32(1), + }, + { + desc: "Ethernet Assignment: Logical Channel", + got: cc.GetAssignment(1).GetLogicalChannel(), + want: ethChIdx, + }, + { + desc: "Ethernet Assignment: Description", + got: cc.GetAssignment(1).GetDescription(), + want: "OTN to ETH", + }, + { + desc: "Ethernet Assignment: Allocation", + got: cc.GetAssignment(1).GetAllocation(), + want: float64(400), + }, + { + desc: "Ethernet Assignment: Type", + got: cc.GetAssignment(1).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), + }, + } + tcs = append(tcs, logicalChannelAssignmentTestcases...) } for _, tc := range tcs { diff --git a/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto b/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto index 91557f86ff6..e7ad71ae9dd 100644 --- a/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto @@ -13,3 +13,14 @@ platform_exceptions: { default_network_instance: "default" } } +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + otn_channel_trib_unsupported: true + eth_channel_ingress_parameters_unsupported: true + eth_channel_assignment_cisco_numbering: true + cisco_pre_fec_ber_inactive_value: true + } + } \ No newline at end of file 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 455bf38a6cf..4ffd98c8287 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 @@ -1,10 +1,12 @@ package zr_pm_test import ( + "flag" "testing" "time" "github.com/openconfig/featureprofiles/internal/cfgplugins" + "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/samplestream" "github.com/openconfig/ondatra" @@ -14,7 +16,6 @@ import ( ) const ( - dp16QAM = uint16(1) samplingInterval = 10 * time.Second minAllowedQValue = 7.0 maxAllowedQValue = 14.0 @@ -26,7 +27,6 @@ const ( inactivePreFECBER = 0.0 inactiveESNR = 0.0 timeout = 10 * time.Minute - flapInterval = 30 * time.Second otnIndexBase = uint32(4000) ethernetIndexBase = uint32(40000) ) @@ -34,6 +34,8 @@ const ( var ( frequencies = []uint64{191400000, 196100000} targetOpticalPowers = []float64{-9, -13} + operationalModeFlag = flag.Int("operational_mode", 1, "vendor-specific operational-mode for the channel") + operationalMode uint16 ) func TestMain(m *testing.M) { @@ -42,7 +44,11 @@ func TestMain(m *testing.M) { func TestPM(t *testing.T) { dut := ondatra.DUT(t, "dut") - + if operationalModeFlag != nil { + operationalMode = uint16(*operationalModeFlag) + } else { + t.Fatalf("Please specify the vendor-specific operational-mode flag") + } fptest.ConfigureDefaultNetworkInstance(t, dut) var ( @@ -71,7 +77,7 @@ func TestPM(t *testing.T) { for _, targetOpticalPower := range targetOpticalPowers { // Configure OCH component and OTN and ETH logical channels. for _, p := range dut.Ports() { - cfgplugins.ConfigOpticalChannel(t, dut, ochs[p.Name()], frequency, targetOpticalPower, dp16QAM) + cfgplugins.ConfigOpticalChannel(t, dut, ochs[p.Name()], frequency, targetOpticalPower, operationalMode) cfgplugins.ConfigOTNChannel(t, dut, ochs[p.Name()], otnIndexes[p.Name()], ethIndexes[p.Name()]) cfgplugins.ConfigETHChannel(t, dut, p.Name(), trs[p.Name()], otnIndexes[p.Name()], ethIndexes[p.Name()]) } @@ -135,7 +141,7 @@ func validateAllSamples(t *testing.T, dut *ondatra.DUTDevice, isEnabled bool, in if valIndex >= len(otnStreams[p.Name()].All()) { break } - operStatus := validateSampleStream(t, interfaceStreams[p.Name()].All()[valIndex], otnStreams[p.Name()].All()[valIndex], p.Name()) + operStatus := validateSampleStream(t, dut, interfaceStreams[p.Name()].All()[valIndex], otnStreams[p.Name()].All()[valIndex], p.Name()) switch operStatus { case oc.Interface_OperStatus_UP: if !isEnabled { @@ -151,7 +157,7 @@ func validateAllSamples(t *testing.T, dut *ondatra.DUTDevice, isEnabled bool, in } // validateSampleStream validates the stream data. -func validateSampleStream(t *testing.T, interfaceData *ygnmi.Value[*oc.Interface], terminalDeviceData *ygnmi.Value[*oc.TerminalDevice_Channel], portName string) oc.E_Interface_OperStatus { +func validateSampleStream(t *testing.T, dut *ondatra.DUTDevice, interfaceData *ygnmi.Value[*oc.Interface], terminalDeviceData *ygnmi.Value[*oc.TerminalDevice_Channel], portName string) oc.E_Interface_OperStatus { if interfaceData == nil { t.Errorf("Data not received for port %v.", portName) return oc.Interface_OperStatus_UNSET @@ -179,7 +185,11 @@ func validateSampleStream(t *testing.T, interfaceData *ygnmi.Value[*oc.Interface if b := otn.GetPreFecBer(); b == nil { t.Errorf("PreFECBER data is empty for port %v", portName) } else { - validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, inactivePreFECBER, operStatus) + if deviations.CiscoPreFECBERInactiveValue(dut) { + validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, 0.5, operStatus) + } else { + validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, inactivePreFECBER, operStatus) + } } if e := otn.GetEsnr(); e == nil { t.Errorf("ESNR data is empty for port %v", portName) @@ -203,7 +213,7 @@ func validatePMValue(t *testing.T, portName, pm string, instant, min, max, avg, return } case oc.Interface_OperStatus_DOWN: - if instant != inactiveValue { + if instant > 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 } diff --git a/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md b/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md index 51ac7dab893..e0b5b2ba32b 100644 --- a/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md +++ b/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md @@ -40,3 +40,13 @@ dut.testbed ## Minimum DUT platform FFF + +## OpenConfig Path and RPC Coverage + +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Subscribe: + +``` \ No newline at end of file diff --git a/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go b/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go index 84b7e7af943..5dbc85b2572 100644 --- a/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go +++ b/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go @@ -49,57 +49,6 @@ func TestMain(m *testing.M) { fptest.RunTests(m) } -// getDeviceConfig gets a full config from a device but refurbishes it enough so it can be -// pushed out again -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) - - for cname, component := range config.Component { - // Keep the port components in order to preserve the breakout-mode config. - if component.GetPort() == nil { - delete(config.Component, cname) - continue - } - // Need to prune subcomponents that may have a leafref to a component that was - // pruned. - component.Subcomponent = nil - } - - for iname, iface := range config.Interface { - if iface.GetEthernet() == nil { - continue - } - // 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) - } - ygot.PruneConfigFalse(oc.SchemaTree["Interface_Ethernet"], e) - if e.PortSpeed != 0 && e.PortSpeed != oc.IfEthernet_ETHERNET_SPEED_SPEED_UNKNOWN { - iface.Ethernet = e - } - } - - if config.Lldp != nil { - config.Lldp.ChassisId = nil - config.Lldp.ChassisIdType = oc.Lldp_ChassisIdType_UNSET - } - - config.Qos = nil - - for _, ni := range config.NetworkInstance { - ni.Fdb = nil - } - - fptest.WriteQuery(t, "Touched", gnmi.OC().Config(), config) - return config -} - // setEthernetFromBase merges the ethernet config from the interfaces in base config into // the destination config. func setEthernetFromBase(t testing.TB, config *oc.Root) { @@ -244,8 +193,7 @@ func checkMetadata1(t *testing.T, gnmiClient gpb.GNMIClient, dut *ondatra.DUTDev t.Helper() got, getRespTimeStamp := extractMetadataAnnotation(t, gnmiClient, dut) want := metadata1 - t.Logf("getResp: %v ", getRespTimeStamp) - if got != want && done.Load() == 0 { + if got != want && getRespTimeStamp < done.Load() { t.Errorf("extractMetadataAnnotation: got %v, want %v", got, want) } } @@ -268,13 +216,15 @@ func TestLargeSetConsistency(t *testing.T) { p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") + fptest.ConfigureDefaultNetworkInstance(t, dut) + // 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) - baselineConfig := getDeviceConfig(t, dut) + baselineConfig := fptest.GetDeviceConfig(t, dut) setEthernetFromBase(t, baselineConfig) gnmiClient := dut.RawAPIs().GNMI(t) 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 cae8c3c1a46..c346a8d5da2 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 @@ -13,4 +13,12 @@ platform_exceptions: { default_network_instance: "default" } } +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + skip_macaddress_check: true + } +} 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 8152a803887..d169ecec2f9 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 @@ -45,22 +45,8 @@ var ( skipContainerOp = flag.Bool("skip_container_op", false, "Skip ContainerOp test cases.") skipItemOp = flag.Bool("skip_item_op", false, "Skip ItemOp test cases.") - // The following experimental flags fine-tune the RootOp and ContainerOp behavior. Some - // devices require the config to be pruned for these to work. We are still undecided - // whether they should be deviations; pending OpenConfig clarifications. - pruneComponents = flag.Bool("prune_components", true, "Prune components that are not ports. Use this to preserve the breakout-mode settings.") - pruneLLDP = flag.Bool("prune_lldp", true, "Prune LLDP config.") - setEthernetFromState = flag.Bool("set_ethernet_from_state", true, "Set interface/ethernet config from state, mostly to get the port-speed settings correct.") - - // This has no known effect except to reduce logspam while debugging. - 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. - 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.") + cannotDeleteVRF = flag.Bool("cannot_delete_vrf", true, "Device cannot delete VRF.") // See "Note about cannotDeleteVRF" below. ) var ( @@ -236,10 +222,6 @@ 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) @@ -840,7 +822,7 @@ func forEachPushOp( f func(t *testing.T, op pushOp, config *oc.Root), ) { baselineConfigOnce.Do(func() { - baselineConfig = getDeviceConfig(t, dut) + baselineConfig = fptest.GetDeviceConfig(t, dut) }) for _, op := range []pushOp{ @@ -850,154 +832,12 @@ func forEachPushOp( if op.shouldSkip() { t.Skip() } - o, err := ygot.DeepCopy(baselineConfig) - if err != nil { - t.Fatalf("Cannot copy baseConfig: %v", err) - } - config := o.(*oc.Root) + config := fptest.CopyDeviceConfig(t, dut, baselineConfig) f(t, op, config) }) } } -// getDeviceConfig gets a full config from a device but refurbishes it enough so it can be -// pushed out again. Ideally, we should be able to push the config we get from the same -// device without modification, but this is not explicitly defined in OpenConfig. -func getDeviceConfig(t testing.TB, dev gnmi.DeviceOrOpts) *oc.Root { - t.Helper() - - // Gets all the config (read-write) paths from root, not the state (read-only) paths. - 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. - if component.GetPort() == nil { - delete(config.Component, cname) - continue - } - // Need to prune subcomponents that may have a leafref to a component that was - // pruned. - component.Subcomponent = nil - } - } - - if *setEthernetFromState { - for iname, iface := range config.Interface { - if iface.GetEthernet() == nil { - continue - } - // 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()) - e := intf.GetEthernet() - 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 - } - } - - if *pruneLLDP && config.Lldp != nil { - config.Lldp.ChassisId = nil - config.Lldp.ChassisIdType = oc.Lldp_ChassisIdType_UNSET - } - - if *pruneQoS { - config.Qos = nil - } - - pruneUnsupportedPaths(config) - - fptest.WriteQuery(t, "Touched", gnmi.OC().Config(), config) - return config -} - -func pruneUnsupportedPaths(config *oc.Root) { - for _, ni := range config.NetworkInstance { - ni.Fdb = nil - } -} - // pushScope describe the config scope that the test case wants to modify. This is for // itemOp only; rootOp and containerOp ignore this. type pushScope struct { @@ -1012,23 +852,6 @@ type pushOp interface { push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, scope *pushScope) } -// setEthernetFromBase merges the ethernet config from the interfaces in base config into -// the destination config. -func setEthernetFromBase(t testing.TB, base *oc.Root, config *oc.Root) { - t.Helper() - - for iname, iface := range config.Interface { - eb := base.GetInterface(iname).GetEthernet() - ec := iface.GetOrCreateEthernet() - if eb == nil || ec == nil { - continue - } - if err := ygot.MergeStructInto(ec, eb); err != nil { - t.Errorf("Cannot merge %s ethernet: %v", iname, err) - } - } -} - // rootOp pushes config using replace at root. type rootOp struct{ base *oc.Root } @@ -1037,9 +860,6 @@ func (rootOp) shouldSkip() bool { return *skipRootOp } func (op rootOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, _ *pushScope) { t.Helper() - if *setEthernetFromState { - setEthernetFromBase(t, op.base, config) - } fptest.WriteQuery(t, "RootOp", gnmi.OC().Config(), config) dut := ondatra.DUT(t, "dut") if deviations.AddMissingBaseConfigViaCli(dut) { @@ -1060,9 +880,6 @@ func (containerOp) shouldSkip() bool { return *skipContainerOp } func (op containerOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, _ *pushScope) { t.Helper() - if *setEthernetFromState { - setEthernetFromBase(t, op.base, config) - } fptest.WriteQuery(t, "ContainerOp", gnmi.OC().Config(), config) batch := &gnmi.SetBatch{} @@ -1095,9 +912,6 @@ func (itemOp) shouldSkip() bool { return *skipItemOp } func (op itemOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, scope *pushScope) { t.Helper() - if *setEthernetFromState { - setEthernetFromBase(t, op.base, config) - } fptest.WriteQuery(t, "ItemOp", gnmi.OC().Config(), config) batch := &gnmi.SetBatch{} diff --git a/internal/deviations/README.md b/internal/deviations/README.md index 670bdbe9226..a42d37cfd59 100644 --- a/internal/deviations/README.md +++ b/internal/deviations/README.md @@ -1,21 +1,57 @@ -## Guidelines to add deviations to FNT tests +# Guidelines to add deviations to FNT tests -### Adding Deviations +## When to use deviations -* Add the deviation to the `Deviations` message in the [proto/metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) file. +1. Deviations may be created to use alternate OC or use CLI instead of OC to + achieve the operational intent described in the README. +2. Deviations should not be created which change the operational intent. See + below for guidance on changing operational intent. +3. Deviations may be created to change which OC path is used for telemetry or + use an implementation's native yang path.  Deviations for telemetry + should not introduce a depedency on CLI output. +4. As with any pull request (PR), the CODEOWNERs must review and approve (or + delegate if appropriate). +5. The CODEOWNERs must ensure the README and code reflects the agreed to + operational support goal.  This may be done via offline discussions or + directly via approvals in the github PR. - ``` +See [Deviation Examples](#deviation-examples) for more information. + +## When not to use a deviation + +Deviations should not be used to skip configuration or skip validations. If the +feature is not supported and there is no workaround to achieve +the functionality, then the test should fail for that platform. + +If the README is in error, the README can be updated and code can be changed +(without introducing deviation) with approval from the CODEOWNERs. + +If the intent of the README needs to be changed (not due to an error, but a +change in the feature request), the CODEOWNER must ensure all parties are +notified. The CODEOWNER must determine if the change is late or early in the +development cycle. If late (development is underway and/or nearly complete), it +is recommended to create a new test which represents the change. If early in +the feature request (development has not started or is very early stage), then +the existing README and code may be updated. + +## Adding Deviations + +* Add the deviation to the `Deviations` message in the + [proto/metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) + file. + +```go message Deviations { ... // Device does not support fragmentation bit for traceroute. bool traceroute_fragmentation = 2; ... } - ``` +``` * Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles root directory to generate the Go code for the added proto fields. - ``` +```shell $ make proto/metadata_go_proto/metadata.pb.go mkdir -p proto/metadata_go_proto # Set directory to hold symlink @@ -30,36 +66,57 @@ go list -f '{{ .Dir }} protobuf-import/{{ .Path }}' -m github.com/openconfig/ondatra | xargs -L1 -- ln -s 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 - ``` - -* Add the accessor function for this deviation to the [internal/deviations/deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) file. This function will need to accept a parameter `dut` of type `*ondatra.DUTDevice` to lookup the deviation value for a specific dut. This accessor function must call `lookupDUTDeviations` and return the deviation value. Test code will use this function to access deviations. - * If the default value of the deviation is the same as the default value for the proto field, the accessor method can directly call the `Get*()` function for the deviation field. For example, the boolean `traceroute_fragmentation` deviation, which has a default value of `false`, will have an accessor method with the single line `return lookupDUTDeviations(dut).GetTracerouteFragmentation()`. - - ``` - // TraceRouteFragmentation returns if the device does not support fragmentation bit for traceroute. - // Default value is false. - func TraceRouteFragmentation(dut *ondatra.DUTDevice) bool { - return lookupDUTDeviations(dut).GetTracerouteFragmentation() - } - ``` - - * If the default value of deviation is not the same as the default value of the proto field, the accessor method can add a check and return the required default value. For example, the accessor method for the float `hierarchical_weight_resolution_tolerance` deviation, which has a default value of `0`, will call the `GetHierarchicalWeightResolutionTolerance()` to check the value set in `metadata.textproto` and return the default value `0.2` if applicable. - - ``` - // HierarchicalWeightResolutionTolerance returns the allowed tolerance for BGP traffic flow while comparing for pass or fail conditions. - // Default minimum value is 0.2. Anything less than 0.2 will be set to 0.2. - func HierarchicalWeightResolutionTolerance(dut *ondatra.DUTDevice) float64 { - hwrt := lookupDUTDeviations(dut).GetHierarchicalWeightResolutionTolerance() - if minHWRT := 0.2; hwrt < minHWRT { +``` + +* Add the accessor function for this deviation to the + [internal/deviations/deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) + file. This function will need to accept a parameter `dut` of type + `*ondatra.DUTDevice` to lookup the deviation value for a specific dut. This + accessor function must call `lookupDUTDeviations` and return the deviation + value. Test code will use this function to access deviations. + * If the default value of the deviation is the same as the default value for + the proto field, the accessor method can directly call the `Get*()` function + for the deviation field. For example, the boolean `traceroute_fragmentation` + deviation, which has a default value of `false`, will have an accessor + method with the single line `return + lookupDUTDeviations(dut).GetTracerouteFragmentation()`. + + ```go + // TraceRouteFragmentation returns if the device does not support fragmentation bit for traceroute. + // Default value is false. + func TraceRouteFragmentation(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetTracerouteFragmentation() + } + ``` + + * If the default value of deviation is not the same as the default value of + the proto field, the accessor method can add a check and return the required + default value. For example, the accessor method for the float + `hierarchical_weight_resolution_tolerance` deviation, which has a default + value of `0`, will call the `GetHierarchicalWeightResolutionTolerance()` to + check the value set in `metadata.textproto` and return the default value + `0.2` if applicable. + + ```go + // HierarchicalWeightResolutionTolerance returns the allowed tolerance for BGP traffic flow while comparing for pass or fail conditions. + // Default minimum value is 0.2. Anything less than 0.2 will be set to 0.2. + func HierarchicalWeightResolutionTolerance(dut *ondatra.DUTDevice) float64 { + hwrt := lookupDUTDeviations(dut).GetHierarchicalWeightResolutionTolerance() + if minHWRT := 0.2; hwrt < minHWRT { return minHWRT - } - return hwrt - } - ``` - -* Set the deviation value in the `metadata.textproto` file in the same folder as the test. For example, the deviations used in the test `feature/gnoi/system/tests/traceroute_test/traceroute_test.go` will be set in the file `feature/gnoi/system/tests/traceroute_test/metadata.textproto`. List all the vendor and optionally also hardware model regex that this deviation is applicable for. - - ``` + } + return hwrt + } + ``` + +* Set the deviation value in the `metadata.textproto` file in the same folder as + the test. For example, the deviations used in the test + `feature/gnoi/system/tests/traceroute_test/traceroute_test.go` will be set in + the file `feature/gnoi/system/tests/traceroute_test/metadata.textproto`. List + all the vendor and optionally also hardware model regex that this deviation is + applicable for. + + ```go ... platform_exceptions: { platform: { @@ -73,30 +130,69 @@ ... ``` -* To access the deviation from the test call the accessor function for the deviation. Pass the dut to this accessor. +* To access the deviation from the test call the accessor function for the + deviation. Pass the dut to this accessor. - ``` + ```go if deviations.TraceRouteFragmentation(dut) { ... } ``` -* Example PRs - https://github.com/openconfig/featureprofiles/pull/1649 and - https://github.com/openconfig/featureprofiles/pull/1668 +* Example PRs - and + + +## Removing Deviations -### Removing Deviations +* Once a deviation is no longer required and removed from all tests, delete the + deviation by removing them from the following files: -* Once a deviation is no longer required and removed from all tests, delete the deviation by removing them from the following files: + * metadata.textproto - Remove the deviation field from all metadata.textproto + in all tests. - * metadata.textproto - Remove the deviation field from all metadata.textproto in all tests. + * Remove the accessor method from + [deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) - * [deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) - Remove the accessor method for this deviation. + * Remove the field number from + [metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) + by adding the `reserved n` to the `Deviations` message. Ref: + - * [metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) - Remove the deviation field from the `Deviations` message and reserve the deleted field number by adding the `reserved n` to the `Deviations` message. -Ref: https://protobuf.dev/programming-guides/proto3/#deleting +* Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles + root directory to update the Go code for the removed proto fields. -* Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles root directory to update the Go code for the removed proto fields. +## Deviation examples + +```go +conf := configureDUT(dut) // returns *oc.Root + +if deviations.AlternateOCEnabled(t, dut) { + switch dut.Vendor() { + case ondatra.VENDOR_X: + conf.SetAlternateOC(val) + } +} else { + conf.SetRequiredOC(val) +} +``` + +```go +conf := configureDUT(dut) // returns *oc.Root + +if deviations.RequiredOCNotSupported(t, dut) { + switch dut.Vendor() { + case ondatra.VENDOR_X: + configureDeviceUsingCli(t, dut, vendorXConfig) + } +} +``` ## Notes -* If you run into issues with the `make proto/metadata_go_proto/metadata.pb.go` you may need to check if the `protoc` module is installed in your environment. Also depending on your Go version you may need to update your PATH and GOPATH. -* After running the `make proto/metadata_go_proto/metadata.pb.go` script, a `protobuf-import/` folder will be added in your current directory. Keep an eye out for this in case you use `git add .` to add modified files since this folder should not be part of your PR. + +* If you run into issues with the `make proto/metadata_go_proto/metadata.pb.go` + you may need to check if the `protoc` module is installed in your environment. + Also depending on your Go version you may need to update your PATH and GOPATH. +* After running the `make proto/metadata_go_proto/metadata.pb.go` script, a + `protobuf-import/` folder will be added in your current directory. Keep an eye + out for this in case you use `git add .` to add modified files since this + folder should not be part of your PR. diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 93ef505adb3..13fe41e364b 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -1208,7 +1208,18 @@ func BgpAllowownasDiffDefaultValue(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetBgpAllowownasDiffDefaultValue() } +// OTNChannelAssignmentCiscoNumbering returns true if OTN channel assignment index starts from 1 instead of 0 +func OTNChannelAssignmentCiscoNumbering(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetOtnChannelAssignmentCiscoNumbering() +} + +// CiscoPreFECBERInactiveValue returns true if a non-zero pre-fec-ber value is to be used for Cisco +func CiscoPreFECBERInactiveValue(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetCiscoPreFecBerInactiveValue() +} + // Admin Enable Table Connections in SRL native func EnableTableConnections(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetEnableTableConnections() } + diff --git a/internal/fptest/config.go b/internal/fptest/config.go new file mode 100644 index 00000000000..bb976eea456 --- /dev/null +++ b/internal/fptest/config.go @@ -0,0 +1,205 @@ +package fptest + +import ( + "flag" + "testing" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +var ( + // Some devices require the config to be pruned for these to work. We are still undecided + // whether they should be deviations; pending OpenConfig clarifications. + pruneComponents = flag.Bool("prune_components", true, "Prune components that are not ports. Use this to preserve the breakout-mode settings.") + pruneLLDP = flag.Bool("prune_lldp", true, "Prune LLDP config.") + setEthernetFromState = flag.Bool("set_ethernet_from_state", true, "Set interface/ethernet config from state, mostly to get the port-speed settings correct.") + + // This has no known effect except to reduce logspam while debugging. + pruneQoS = flag.Bool("prune_qos", true, "Prune QoS config.") + + // Experimental flags that will likely become a deviation. + 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.") +) + +// GetDeviceConfig gets a full config from a device but refurbishes it enough so it can be +// pushed out again. Ideally, we should be able to push the config we get from the same +// device without modification, but this is not explicitly defined in OpenConfig. +func GetDeviceConfig(t testing.TB, dev gnmi.DeviceOrOpts) *oc.Root { + t.Helper() + + // Gets all the config (read-write) paths from root, not the state (read-only) paths. + config := gnmi.Get[*oc.Root](t, dev, gnmi.OC().Config()) + 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. + if component.GetPort() == nil { + delete(config.Component, cname) + continue + } + // Need to prune subcomponents that may have a leafref to a component that was + // pruned. + component.Subcomponent = nil + } + } + + if *setEthernetFromState { + for iname, iface := range config.Interface { + if iface.GetEthernet() == nil { + continue + } + // 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()) + e := intf.GetEthernet() + 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 + } + } + + if *pruneLLDP && config.Lldp != nil { + config.Lldp.ChassisId = nil + config.Lldp.ChassisIdType = oc.Lldp_ChassisIdType_UNSET + } + + if *pruneQoS { + config.Qos = nil + } + + pruneUnsupportedPaths(config) + + WriteQuery(t, "Touched", gnmi.OC().Config(), config) + return config +} + +// CopyDeviceConfig returns a deep copy of a device config but refurbishes it enough so it can be +// pushed out again +func CopyDeviceConfig(t testing.TB, dut *ondatra.DUTDevice, config *oc.Root) *oc.Root { + if deviations.SkipMacaddressCheck(dut) { + *setEthernetFromState = false + } + + o, err := ygot.DeepCopy(config) + if err != nil { + t.Fatalf("Cannot copy baseConfig: %v", err) + } + + copy := o.(*oc.Root) + + if *setEthernetFromState { + setEthernetFromBase(t, config, copy) + } + + return copy +} + +func pruneUnsupportedPaths(config *oc.Root) { + for _, ni := range config.NetworkInstance { + ni.Fdb = nil + } +} + +// setEthernetFromBase merges the ethernet config from the interfaces in base config into +// the destination config. +func setEthernetFromBase(t testing.TB, base *oc.Root, config *oc.Root) { + t.Helper() + + for iname, iface := range config.Interface { + eb := base.GetInterface(iname).GetEthernet() + ec := iface.GetOrCreateEthernet() + if eb == nil || ec == nil { + continue + } + if err := ygot.MergeStructInto(ec, eb); err != nil { + t.Errorf("Cannot merge %s ethernet: %v", iname, err) + } + } +} diff --git a/internal/security/acctz/acctz.go b/internal/security/acctz/acctz.go index 6837c82f0bc..6f475e14e1e 100644 --- a/internal/security/acctz/acctz.go +++ b/internal/security/acctz/acctz.go @@ -27,8 +27,8 @@ import ( "testing" "time" - "github.com/openconfig/gnmi/proto/gnmi" - "github.com/openconfig/gnoi/system" + gnmipb "github.com/openconfig/gnmi/proto/gnmi" + systempb "github.com/openconfig/gnoi/system" acctzpb "github.com/openconfig/gnsi/acctz" authzpb "github.com/openconfig/gnsi/authz" cpb "github.com/openconfig/gnsi/credentialz" @@ -113,7 +113,7 @@ func setupUserPassword(t *testing.T, dut *ondatra.DUTDevice, username, password time.Sleep(time.Second) } -func nokiaFailCliRole(t *testing.T) *gnmi.SetRequest { +func nokiaFailCliRole(t *testing.T) *gnmipb.SetRequest { failRoleData, err := json.Marshal([]any{ map[string]any{ "services": []string{"cli"}, @@ -126,22 +126,22 @@ func nokiaFailCliRole(t *testing.T) *gnmi.SetRequest { t.Fatalf("Error with json marshal: %v", err) } - return &gnmi.SetRequest{ - Prefix: &gnmi.Path{ + return &gnmipb.SetRequest{ + Prefix: &gnmipb.Path{ Origin: "native", }, - Replace: []*gnmi.Update{ + Replace: []*gnmipb.Update{ { - Path: &gnmi.Path{ - Elem: []*gnmi.PathElem{ + Path: &gnmipb.Path{ + Elem: []*gnmipb.PathElem{ {Name: "system"}, {Name: "aaa"}, {Name: "authorization"}, {Name: "role", Key: map[string]string{"rolename": failRoleName}}, }, }, - Val: &gnmi.TypedValue{ - Value: &gnmi.TypedValue_JsonIetfVal{ + Val: &gnmipb.TypedValue{ + Value: &gnmipb.TypedValue_JsonIetfVal{ JsonIetfVal: failRoleData, }, }, @@ -157,7 +157,7 @@ func SetupUsers(t *testing.T, dut *ondatra.DUTDevice, configureFailCliRole bool) successUser.SetRole(oc.AaaTypes_SYSTEM_DEFINED_ROLES_SYSTEM_ROLE_ADMIN) failUser := auth.GetOrCreateUser(failUsername) if configureFailCliRole { - var SetRequest *gnmi.SetRequest + var SetRequest *gnmipb.SetRequest // Create failure cli role in native. switch dut.Vendor() { @@ -325,13 +325,13 @@ func SendGnmiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons var records []*acctzpb.RecordResponse grpcConn := dialGrpc(t, target) - gnmiClient := gnmi.NewGNMIClient(grpcConn) + gnmiClient := gnmipb.NewGNMIClient(grpcConn) ctx := context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", failUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", failPassword) // Send an unsuccessful gNMI capabilities request (bad creds in context). - _, err := gnmiClient.Capabilities(ctx, &gnmi.CapabilityRequest{}) + _, err := gnmiClient.Capabilities(ctx, &gnmipb.CapabilityRequest{}) if err != nil { t.Logf("Got expected error fetching capabilities with bad creds, error: %s", err) } else { @@ -364,7 +364,7 @@ func SendGnmiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons ctx = context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", successUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", successPassword) - req := &gnmi.CapabilityRequest{} + req := &gnmipb.CapabilityRequest{} payload, err := anypb.New(req) if err != nil { t.Fatal("Failed creating anypb payload.") @@ -422,14 +422,14 @@ func SendGnoiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons var records []*acctzpb.RecordResponse grpcConn := dialGrpc(t, target) - gnoiSystemClient := system.NewSystemClient(grpcConn) + gnoiSystemClient := systempb.NewSystemClient(grpcConn) ctx := context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", failUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", failPassword) // Send an unsuccessful gNOI system time request (bad creds in context), we don't // care about receiving on it, just want to make the request. - gnoiSystemPingClient, err := gnoiSystemClient.Ping(ctx, &system.PingRequest{ + gnoiSystemPingClient, err := gnoiSystemClient.Ping(ctx, &systempb.PingRequest{ Destination: "127.0.0.1", Count: 1, }) @@ -468,7 +468,7 @@ func SendGnoiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons ctx = context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", successUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", successPassword) - req := &system.PingRequest{ + req := &systempb.PingRequest{ Destination: "127.0.0.1", Count: 1, } diff --git a/proto/metadata.proto b/proto/metadata.proto index 82e022fcec7..3106cf05272 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -643,9 +643,12 @@ message Metadata { // Device have different default value for allow own as. // Juniper : b/373559004 bool bgp_allowownas_diff_default_value = 231; + // Cisco numbering for OTN channel assignment starts from 1 instead of 0 + bool otn_channel_assignment_cisco_numbering = 232; + // Cisco pre-fec-ber inactive value for CISCO-ACACIA vendors + bool cisco_pre_fec_ber_inactive_value = 233; // Nokia; b/304493065 comment#7 SRL native admin_enable for table-connections - bool enable_table_connections = 232; - + bool enable_table_connections = 234; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19, 36, 35, 40, 173; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 5fdcccea5fb..08ec21c158b 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -924,8 +924,12 @@ type Metadata_Deviations struct { // Device have different default value for allow own as. // Juniper : b/373559004 BgpAllowownasDiffDefaultValue bool `protobuf:"varint,231,opt,name=bgp_allowownas_diff_default_value,json=bgpAllowownasDiffDefaultValue,proto3" json:"bgp_allowownas_diff_default_value,omitempty"` + // Cisco numbering for OTN channel assignment starts from 1 instead of 0 + OtnChannelAssignmentCiscoNumbering bool `protobuf:"varint,232,opt,name=otn_channel_assignment_cisco_numbering,json=otnChannelAssignmentCiscoNumbering,proto3" json:"otn_channel_assignment_cisco_numbering,omitempty"` + // Cisco pre-fec-ber inactive value for CISCO-ACACIA vendors + CiscoPreFecBerInactiveValue bool `protobuf:"varint,233,opt,name=cisco_pre_fec_ber_inactive_value,json=ciscoPreFecBerInactiveValue,proto3" json:"cisco_pre_fec_ber_inactive_value,omitempty"` // Nokia; b/304493065 comment#7 SRL native admin_enable for table-connections - EnableTableConnections bool `protobuf:"varint,232,opt,name=enable_table_connections,json=enableTableConnections,proto3" json:"enable_table_connections,omitempty"` + EnableTableConnections bool `protobuf:"varint,234,opt,name=enable_table_connections,json=enableTableConnections,proto3" json:"enable_table_connections,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -2430,6 +2434,20 @@ func (x *Metadata_Deviations) GetBgpAllowownasDiffDefaultValue() bool { return false } +func (x *Metadata_Deviations) GetOtnChannelAssignmentCiscoNumbering() bool { + if x != nil { + return x.OtnChannelAssignmentCiscoNumbering + } + return false +} + +func (x *Metadata_Deviations) GetCiscoPreFecBerInactiveValue() bool { + if x != nil { + return x.CiscoPreFecBerInactiveValue + } + return false +} + func (x *Metadata_Deviations) GetEnableTableConnections() bool { if x != nil { return x.EnableTableConnections @@ -2500,7 +2518,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, 0xf5, 0x82, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x84, 0x01, 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, @@ -2534,7 +2552,7 @@ var file_metadata_proto_rawDesc = []byte{ 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, 0xc8, 0x7a, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xe5, 0x7b, 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, @@ -3506,49 +3524,59 @@ var file_metadata_proto_rawDesc = []byte{ 0x66, 0x66, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xe7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x62, 0x67, 0x70, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x77, 0x6e, 0x61, 0x73, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0xe8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 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, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x4a, 0x04, 0x08, - 0x23, 0x10, 0x24, 0x4a, 0x04, 0x08, 0x28, 0x10, 0x29, 0x4a, 0x06, 0x08, 0xad, 0x01, 0x10, 0xae, - 0x01, 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, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x53, 0x0a, 0x26, 0x6f, 0x74, 0x6e, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x5f, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x18, 0xe8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x6f, 0x74, 0x6e, 0x43, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x69, 0x73, + 0x63, 0x6f, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x46, 0x0a, 0x20, 0x63, + 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x66, 0x65, 0x63, 0x5f, 0x62, 0x65, 0x72, + 0x5f, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0xe9, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x50, 0x72, 0x65, + 0x46, 0x65, 0x63, 0x42, 0x65, 0x72, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xea, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 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, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x4a, 0x04, 0x08, 0x23, 0x10, 0x24, + 0x4a, 0x04, 0x08, 0x28, 0x10, 0x29, 0x4a, 0x06, 0x08, 0xad, 0x01, 0x10, 0xae, 0x01, 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 f3da91c3cfe..412f0a93b7d 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -809,6 +809,13 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_summary/otg_tests/route_summary_counters_test/README.md" exec: " " } +test: { + id: "RT-4.11" + description: " Scale AFTs Route Summary" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_summary/otg_tests/scale_aft_summary/README.md" + exec: " " +} + test: { id: "RT-5.1" description: "Singleton Interface" @@ -1224,7 +1231,8 @@ test: { exec: " " } test: { - id: "TE-9.1: Push MPLS Labels to MPLS payload" + id: "TE-9.1" + description: "Push MPLS Labels to MPLS payload" readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/mpls_compliance/README.md" } test: { @@ -1798,3 +1806,15 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/container/networking/tests/container_connectivity/README.md" exec: " " } +test: { + id: "AFT-1.1" + description: "AFT Streaming" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_base/otg_tests/aft_base/README.md" + exec: " " +} +test: { + id: "AFT-2.1" + description: "AFT Streaming" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_base/otg_tests/aft_prefixcounters/README.md" + exec: " " +} \ No newline at end of file diff --git a/tools/nosimage/validate/validate.go b/tools/nosimage/validate/validate.go index a43203d4e4d..76115528626 100644 --- a/tools/nosimage/validate/validate.go +++ b/tools/nosimage/validate/validate.go @@ -91,7 +91,12 @@ 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 := ocpaths.ClonePublicRepo(config.DownloadPath, "v"+profile.Ocpaths.GetVersion()) + + ocReleaseTag := "" + if profile.Ocpaths.GetVersion() != "" { + ocReleaseTag = "v" + profile.Ocpaths.GetVersion() + } + publicPath, err := ocpaths.ClonePublicRepo(config.DownloadPath, ocReleaseTag) if err != nil { fmt.Println(err) os.Exit(1) From 74348f7db362ffea8871740807e68be94650c9f6 Mon Sep 17 00:00:00 2001 From: trathod Date: Tue, 3 Dec 2024 11:03:42 -0500 Subject: [PATCH 5/9] Revert "-Resolving conflicts" This reverts commit f41b14ae757fc5367b892b30427150bcb4612744. --- .github/CODEOWNERS | 2 +- .../aft_base/otg_tests/afts_base/README.md | 177 ------ .../otg_tests/afts_prefix_counters/README.md | 178 ------ .../route_summary_counters_test/README.md | 0 .../metadata.textproto | 0 .../route_summary_counters_test.go | 0 .../otg_tests/scale_aft_summary/README.md | 39 -- .../scale_aft_summary/metadata.textproto | 54 -- .../otg_tests/scale_aft_summary/route_test.go | 566 ------------------ ...bgp_override_as_path_split_horizon_test.go | 22 +- .../link_bandwidth_test.go | 332 ++++------ .../otg_tests/encap_decap_scale/README.md | 4 +- .../encap_decap_scale_test.go | 4 +- .../otg_tests/weighted_ecmp_test/README.md | 49 +- .../metadata.textproto | 11 - .../zr_logical_channels_test.go | 270 +++------ .../tests/zr_pm_test/metadata.textproto | 11 - .../tests/zr_pm_test/zr_pm_test.go | 26 +- .../large_set_consistency_test/README.md | 10 - .../large_set_consistency_test.go | 58 +- .../metadata.textproto | 8 - .../set/tests/gnmi_set_test/gnmi_set_test.go | 192 +++++- internal/deviations/README.md | 192 ++---- internal/deviations/deviations.go | 11 - internal/fptest/config.go | 205 ------- internal/security/acctz/acctz.go | 34 +- proto/metadata.proto | 7 +- proto/metadata_go_proto/metadata.pb.go | 120 ++-- testregistry.textproto | 22 +- tools/nosimage/validate/validate.go | 7 +- 30 files changed, 610 insertions(+), 2001 deletions(-) delete mode 100644 feature/aft/aft_base/otg_tests/afts_base/README.md delete mode 100644 feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md rename feature/aft/{afts_summary => aft_summary}/otg_tests/route_summary_counters_test/README.md (100%) rename feature/aft/{afts_summary => aft_summary}/otg_tests/route_summary_counters_test/metadata.textproto (100%) rename feature/aft/{afts_summary => aft_summary}/otg_tests/route_summary_counters_test/route_summary_counters_test.go (100%) delete mode 100644 feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md delete mode 100644 feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto delete mode 100644 feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go delete mode 100644 internal/fptest/config.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 82423e81a15..df375ba3436 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -12,7 +12,7 @@ # /feature folders each have owners who are auto requested for review and may merge PR's /feature/acl/ @alokmtri-g -/feature/aft/ @sudhinj @yunjie-lu +/feature/aft/ @sudhinj /feature/bgp/ @dplore /feature/dhcp/ @alokmtri-g /feature/ethernet/ @ram-mac diff --git a/feature/aft/aft_base/otg_tests/afts_base/README.md b/feature/aft/aft_base/otg_tests/afts_base/README.md deleted file mode 100644 index b2e0d5a2792..00000000000 --- a/feature/aft/aft_base/otg_tests/afts_base/README.md +++ /dev/null @@ -1,177 +0,0 @@ -# AFT-1.1: AFTs Base - -## Summary - -IPv4/IPv6 unicast routes next hop group and next hop. - -## Testbed - -* atedut_4.testbed - -## Test Setup - -### Generate DUT and ATE Configuration - -Configure DUT:port1,port2,port3 for IS-IS session with ATE:port1,port2,port3 -* IS-IS must be level 2 only with wide metric. -* IS-IS must be point to point. -* Send 1000 ipv4 and 1000 ipv6 IS-IS prefixes from ATE:port3 to DUT:port3. - - -Establish eBGP sessions between ATE:port1,port2 and DUT:port1,port2 and another between ATE:port3 and DUT:port3. -* Configure eBGP over the interface ip. -* eBGP must be multipath. -* Advertise 1000 ipv4,ipv6 prefixes from ATE port1,port2 observe received prefixes at DUT. -* Validate total number of entries of AFT for IPv4 and IPv6. -* Each prefix must have 2 next hops pointing to ATE port1,port2. -* Advertise 100 ipv4,ipv6 from ATE port3 observe received prefixes at DUT. - -Establish RSVP Sessions between ATE:port3 and SUT:port3. -* Configure mpls and rsvp sessions. -* Configure 2 ingress TE tunnels from DUT:port3 to ATE:port3. -* Tunnel destination is interface ip of ATE:port3. -* Configure explicit null and ipv6 tunneling. -* BGP advertised routes from ATE:port3 must be pointing to the 2 tunnels in the DUT. - -### Procedure - -* Use gNMI.Set with REPLACE option to push the Test Setup configuration to the DUT. -* ATE configuration must be pushed. - -### Verifications - -* BGP route advertised from ATE:port1,port2 must have 2 nexthops. -* IS-IS route advertised from ATE:port3 must have one next hop. -* BGP route advertised from ATE:port3 must have 2 next hops pointing to tunnels. -* Use gnmi Subscribe with ON_CHANGE option to /network-instances/network-instance/afts. -* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. -* Verify afts prefix advertised by BGP,ISIS. -* Verify its next hop group, number of next hop and its interfaces. -* Verify the number of next hop is same as expected. -* Verify all other leaves mentioned in the path section. - - -## AFT-1.1.1: AFT Base Link Down scenario 1 - -### Procedure - -Bring down the link between ATE:port2 and DUT:port2 using OTG api. - -### Verifications - -* BGP routes advertised from ATE:port1,port2 must have 1 nexthop. -* IS-IS routes advertised from ATE:port3 must have one next hop. -* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. -* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. -* Verify afts prefix advertised by BGP,ISIS. -* Verify its next hop group, number of next hop and its interfaces. -* Verify the number of next hop is same as expected. - -## AFT-1.1.2: AFT Base Link Down scenario 2 - -### Procedure - -Bring down both links between ATE:port1,port2 and DUT:port1,port2 using OTG api. - -### Verifications - -* BGP routes advertised from ATE:port1,port2 must be removed from RIB,FIB of the DUT, query results nil. -* IS-IS routes advertised from ATE:port3 must have one next hop. -* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. -* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. -* Verify afts prefix advertised by BGP,ISIS. -* Verify its next hop group, number of next hop and its interfaces. -* Verify the number of next hop is same as expected. - -## AFT-1.1.3: AFT Base Link Up scenario 1 - -### Procedure - -Bring up link between ATE:port1 and DUT:port1 using OTG api. - -### Verifications - -* BGP routes advertised from ATE:port1,port2 must have one next hop. -* IS-IS routes advertised from ATE:port3 must have one next hop. -* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. -* Verify afts prefix advertised by BGP,ISIS. -* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. -* Verify its next hop group, number of next hop and its interfaces. -* Verify the number of next hop is same as expected. - -## AFT-1.1.4: AFT Base Link Up scenario 2 - -### Procedure - -Bring up both link between ATE:port1,port2 and DUT:port1,port2 using OTG api. - -### Verifications - -* BGP routes advertised from ATE:port1,port2 must have 2 next hops. -* IS-IS routes advertised from ATE:port3 must have one next hop. -* BGP routes advertised from ATE:port3 must have 2 next hops pointing to tunnels. -* For verifying prefix, nexthop groups, next hop use the leaves mentioed in the path section. -* Verify afts prefix advertised by BGP,ISIS. -* Verify its next hop group, number of next hop and its interfaces. -* Verify the number of next hop is same as expected. - -## 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 -paths: - ## Config Paths ## - - - ## State Paths ## - - /network-instances/network-instance/afts/ethernet/mac-entry/state/next-hop-group: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/origin-protocol: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/origin-protocol: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix: - /network-instances/network-instance/afts/aft-summaries/ipv4-unicast/protocols/protocol/state/origin-protocol: - /network-instances/network-instance/afts/aft-summaries/ipv6-unicast/protocols/protocol/state/origin-protocol: - /network-instances/network-instance/afts/next-hop-groups/next-hop-group/id: - /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/index: - /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/index: - /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight: - /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/backup-next-hop-group: - /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/id: - /network-instances/network-instance/afts/next-hops/next-hop/index: - /network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/interface: - /network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/subinterface: - /network-instances/network-instance/afts/next-hops/next-hop/state/encapsulate-header: - /network-instances/network-instance/afts/next-hops/next-hop/state/index: - /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address: - /network-instances/network-instance/afts/next-hops/next-hop/state/mac-address: - /network-instances/network-instance/afts/next-hops/next-hop/state/origin-protocol: - /network-instances/network-instance/afts/state-synced/state/ipv4-unicast: - /network-instances/network-instance/afts/state-synced/state/ipv6-unicast: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/entry-metadata: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group-network-instance: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/origin-network-instance: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/entry-metadata: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group-network-instance: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/origin-network-instance: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/prefix: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/prefix: - -rpcs: - gnmi: - gNMI.Subscribe: -``` - -## Control Protocol Coverage - -BGP -IS-IS -RSVP -MPLS - -## Minimum DUT Platform Requirement - -vRX diff --git a/feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md b/feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md deleted file mode 100644 index 9fce154e4a1..00000000000 --- a/feature/aft/aft_base/otg_tests/afts_prefix_counters/README.md +++ /dev/null @@ -1,178 +0,0 @@ -# AFT-2.1: AFTs Prefix Counters - -## Summary - -IPv4/IPv6 prefix counters - -## Testbed - -* atedut_2.testbed - -## Test Setup - -### Generate DUT and ATE Configuration - -Configure DUT:port1 for IS-IS session with ATE:port1 -* IS-IS must be level 2 only with wide metric. -* IS-IS must be point to point. -* Send 1000 ipv4 and 1000 ipv6 IS-IS prefixes from ATE:port1 to DUT:port1. - -Establish eBGP sessions between ATE:port1 and DUT:port1. -* Configure eBGP over the interface ip. -* Advertise 1000 ipv4,ipv6 prefixes from ATE port1 observe received prefixes at DUT. - -### Procedure - -* Gnmi set with REPLACE option to push the configuration DUT. -* ATE configuration must be pushed. - -### verifications - -* BGP routes advertised from ATE:port1 must have 1 nexthop. -* IS-IS routes advertised from ATE:port1 must have one next hop. -* Use gnmi Subscribe with ON_CHANGE option to /network-instances/network-instance/afts. -* Verify afts prefix entries using the following paths with in a timeout of 30s. - -/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix, -/network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix - - - -## AFT-2.1.1: AFT Prefix Counters ipv4 packets forwarded, ipv4 octets forwarded IS-IS route. - -### Procedure - -From ATE:port2 send 10000 packets to one of the ipv4 prefix advertise by IS-IS. - -### Verifications - -* Before the traffic measure the initial counter value. -* After the traffic measure the final counter value. -* The difference between final and initial value must match with the counter value in ATE then the test is marked as passed. -* Verify afts ipv4 forwarded packets and ipv4 forwarded octets counter entries using the path mentioned in the paths section of this test plan. - -## AFT-2.1.2: AFT Prefix Counters ipv4 packets forwarded, ipv4 octets forwarded BGP route. - -### Procedure - -From ATE:port2 send 10000 packets to one of the ipv4 prefix advertise by BGP. - -### Verifications - -* Before the traffic measure the initial counter value. -* After the traffic measure the final counter value. -* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. -* Verify afts ipv4 forwarded packets and ipv4 forwarded octets counter entries using the path mentioned in the paths section of this test plan. - - -## AFT-2.1.3: AFT Prefix Counters ipv6 packets forwarded, ipv6 octets forwarded IS-IS route. - -### Procedure - -From ATE:port2 send 10000 packets to one of the ipv6 prefix advertise by IS-IS. - -### Verifications - -* Before the traffic measure the initial counter value. -* After the traffic measure the final counter value. -* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. -* Verify afts ipv6 forwarded packets and ipv6 forwarded octets counter entries using the path mentioned in the paths section of this test plan. - -## AFT-2.1.4: AFT Prefix Counters ipv6 packets forwarded, ipv6 octets forwarded BGP route. - -### Procedure - -From ATE:port2 send 10000 packets to one of the ipv6 prefix advertise by BGP. - -### Verifications - -* Before the traffic measure the initial counter value. -* After the traffic measure the final counter value. -* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. -* Verify afts ipv6 forwarded packets and ipv6 forwarded octets counter entries using the path mentioned in the paths section of this test plan. - -## AFT-2.1.5: AFT Prefix Counters withdraw the ipv4 prefix. - -### Procedure - -* From ATE:port1 withdraw some prefixes of BGP and IS-IS. -* Send 10000 packets from ATE:port2 to DUT:port2 for one of the withdrawn ipv4 prefix. -* The traffic must blackhole. - -### Verifications - -* The counters must not send incremental value as the prefix is not present in RIB/FIB. The test fails if the counter shows incremental values. -* Verify afts ipv4 forwarded packet counter entries using the path mentioned in the paths section of this test plan. - -## AFT-2.1.6: AFT Prefix Counters add the ipv4 prefix back. - -### Procedure - -* From ATE:port1 add the prefixes of BGP and IS-IS back. -* Send 10000 packets from ATE:port2 to DUT:port2 for one of the added ipv4 prefix. -* The traffic must flow end to end. - -### Verifications - -* Before the traffic measure the initial counter value. -* After the traffic measure the final counter value. -* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. -* Verify afts counter entries using the path mentioned in the paths section of this test plan. - -## AFT-2.1.7: AFT Prefix Counters withdraw the ipv6 prefix. - -### Procedure - -* From ATE:port1 withdraw some prefixes of BGP and IS-IS. -* Send 10000 packets from ATE:port2 to DUT:port2 for one of the withdrawn ipv6 prefix. -* The traffic must blackhole. - -### Verifications - -* The counters must not send incremental value as the prefix is not present in RIB/FIB. The test fails if the counter shows incremental values. -* Verify afts counter entries using the path mentioned in the paths section of this test plan. - -## AFT-2.1.8: AFT Prefix Counters add the ipv6 prefix back. - -### Procedure - -* From ATE:port1 add the prefixes of BGP and IS-IS back. -* Send 10000 packets from ATE:port2 to DUT:port2 for one of the added ipv6 prefix. -* The traffic must flow end to end. - -### Verifications - -* Before the traffic measure the initial counter value. -* After the traffic measure the final counter value. -* The difference between final and initial value must match with the counter value in ATE, then the test is marked as passed. -* Verify afts counter entries using the path mentioned in the paths section of this test plan. - -## 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 -paths: - ## Config Paths ## - - ## State Paths ## - - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/counters/octets-forwarded: - /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/counters/packets-forwarded: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/counters/octets-forwarded: - /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/counters/packets-forwarded: - - -rpcs: - gnmi: - gNMI.Subscribe: -``` - -## Control Protocol Coverage - -BGP -IS-IS - -## Minimum DUT Platform Requirement - -vRX \ No newline at end of file diff --git a/feature/aft/afts_summary/otg_tests/route_summary_counters_test/README.md b/feature/aft/aft_summary/otg_tests/route_summary_counters_test/README.md similarity index 100% rename from feature/aft/afts_summary/otg_tests/route_summary_counters_test/README.md rename to feature/aft/aft_summary/otg_tests/route_summary_counters_test/README.md diff --git a/feature/aft/afts_summary/otg_tests/route_summary_counters_test/metadata.textproto b/feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto similarity index 100% rename from feature/aft/afts_summary/otg_tests/route_summary_counters_test/metadata.textproto rename to feature/aft/aft_summary/otg_tests/route_summary_counters_test/metadata.textproto diff --git a/feature/aft/afts_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 similarity index 100% rename from feature/aft/afts_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go rename to feature/aft/aft_summary/otg_tests/route_summary_counters_test/route_summary_counters_test.go diff --git a/feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md b/feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md deleted file mode 100644 index e7e416b40e7..00000000000 --- a/feature/aft/afts_summary/otg_tests/scale_aft_summary/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# RT-4.11: AFTs Route Summary - -## Summary - -IPv4/IPv6 scale unicast AFTs route summary for ISIS and BGP protocol - -## Procedure - -* Configure DUT:port1 for an IS-IS session with ATE:port1 -* Establish eBGP sessions between ATE:port1 and DUT:port1 and another between ATE:port2 and DUT:port2 -* Configure Route-policy under BGP peer-group address-family -* Advertise scale prefixes from ATE port-1, port-2 observe received prefixes at DUT for IPv4 and IPv6 -* Validate total number of entries of AFT for IPv4 and IPv6 - -## 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 -paths: - ## Config Paths ## - - ## State Paths ## - /network-instances/network-instance/afts/aft-summaries/ipv4-unicast/protocols/protocol/state/counters/aft-entries: - /network-instances/network-instance/afts/aft-summaries/ipv6-unicast/protocols/protocol/state/counters/aft-entries: - -rpcs: - gnmi: - gNMI.Subscribe: -``` - -## Control Protocol Coverage - -BGP -IS-IS - -## Minimum DUT Platform Requirement - -vRX diff --git a/feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto b/feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto deleted file mode 100644 index d61d4590b2b..00000000000 --- a/feature/aft/afts_summary/otg_tests/scale_aft_summary/metadata.textproto +++ /dev/null @@ -1,54 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "89da0b4c-9a16-44f8-9757-d98ccdd6aaf4" -plan_id: "RT-4.11" -description: "AFTs Route Summary" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - isis_multi_topology_unsupported: true - isis_interface_level1_disable_required: true - missing_isis_interface_afi_safi_enable: true - isis_restart_suppress_unsupported: true - explicit_port_speed: true - explicit_interface_in_default_vrf: true - missing_value_for_defaults: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - isis_interface_level1_disable_required: true - isis_single_topology_required: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - isis_level_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - omit_l2_mtu: true - missing_value_for_defaults: true - interface_enabled: true - default_network_instance: "default" - isis_instance_enabled_required: true - isis_interface_afi_unsupported: true - route_policy_under_afi_unsupported: true - } -} diff --git a/feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go b/feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go deleted file mode 100644 index e283663711e..00000000000 --- a/feature/aft/afts_summary/otg_tests/scale_aft_summary/route_test.go +++ /dev/null @@ -1,566 +0,0 @@ -// 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 route_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/isissession" - "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 2001:db8::192:0:2:0/126 -// * Destination: dut:port2 -> ate:port2 subnet 192.0.2.4/30 2001:db8::192:0:2:4/126 -// -// 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 ( - advertisedRoutesv4Prefix = 32 - advertisedRoutesv6Prefix = 128 - dutAS = 65501 - ate1AS = 64501 - ate2AS = 200 - plenIPv4 = 30 - plenIPv6 = 126 - rplType = oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE - rplName = "ALLOW" - peerGrpNamev4 = "BGP-PEER-GROUP-V4" - peerGrpNamev6 = "BGP-PEER-GROUP-V6" - peerGrpNamev4P1 = "BGP-PEER-GROUP-V4-P1" - peerGrpNamev6P1 = "BGP-PEER-GROUP-V6-P1" - peerGrpNamev4P2 = "BGP-PEER-GROUP-V4-P2" - peerGrpNamev6P2 = "BGP-PEER-GROUP-V6-P2" - isisRoute = "199.0.0.1" - bgpRoute = "203.0.113.0" - isisRoutev6 = "2001:db8::203:0:113:1" - bgpRoutev6 = "2001:DB8:2::1" - RouteCount = uint32(1000) -) - -var ( - dutP1 = attrs.Attributes{ - Desc: "DUT to ATE source", - IPv4: "192.0.2.1", - IPv6: "2001:db8::1", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } - ateP1 = attrs.Attributes{ - Name: "ateP1", - MAC: "02:00:01:01:01:01", - IPv4: "192.0.2.2", - IPv6: "2001:db8::2", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } - - dutP2 = attrs.Attributes{ - Desc: "DUT to ATE destination", - IPv4: "192.0.2.5", - IPv6: "2001:db8::5", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } - - ateP2 = attrs.Attributes{ - Name: "ateP2", - MAC: "02:00:02:01:01:01", - IPv4: "192.0.2.6", - IPv6: "2001:db8::6", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } -) - -// configureDUT configures all the interfaces and BGP on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - dc := gnmi.OC() - p1 := dut.Port(t, "port1").Name() - i1 := dutP1.NewOCInterface(p1, dut) - gnmi.Replace(t, dut, dc.Interface(p1).Config(), i1) - - p2 := dut.Port(t, "port2").Name() - i2 := dutP2.NewOCInterface(p2, dut) - gnmi.Replace(t, dut, dc.Interface(p2).Config(), i2) - - // Configure Network instance type on DUT - t.Log("Configure/update Network Instance") - 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, p1, deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2, deviations.DefaultNetworkInstance(dut), 0) - } - configureRoutePolicy(t, dut, rplName, rplType) - - dutConfPath := dc.NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - dutConf := createBGPNeighborP1(dutAS, ate1AS, dut) - gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) - dutConf = createBGPNeighborP2(dutAS, ate2AS, dut) - gnmi.Update(t, dut, dutConfPath.Config(), dutConf) - ts := isissession.MustNew(t).WithISIS() - ts.ConfigISIS(func(isis *oc.NetworkInstance_Protocol_Isis) { - global := isis.GetOrCreateGlobal() - global.HelloPadding = oc.Isis_HelloPaddingType_DISABLE - - if deviations.ISISSingleTopologyRequired(ts.DUT) { - afv6 := global.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST) - afv6.GetOrCreateMultiTopology().SetAfiName(oc.IsisTypes_AFI_TYPE_IPV4) - afv6.GetOrCreateMultiTopology().SetSafiName(oc.IsisTypes_SAFI_TYPE_UNICAST) - } - }) - ts.ATEIntf1.Isis().Advanced().SetEnableHelloPadding(false) - ts.PushAndStart(t) -} - -type BGPNeighbor struct { - as uint32 - neighborip string - isV4 bool -} - -func createBGPNeighborP1(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { - nbrs := []*BGPNeighbor{ - {as: peerAs, neighborip: ateP1.IPv4, isV4: true}, - {as: peerAs, neighborip: ateP1.IPv6, isV4: false}, - } - - 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(localAs) - global.RouterId = ygot.String(dutP1.IPv4) - - 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. - pgv4 := bgp.GetOrCreatePeerGroup(peerGrpNamev4P1) - pgv4.PeerAs = ygot.Uint32(peerAs) - pgv4.PeerGroupName = ygot.String(peerGrpNamev4P1) - pgv6 := bgp.GetOrCreatePeerGroup(peerGrpNamev6P1) - pgv6.PeerAs = ygot.Uint32(peerAs) - pgv6.PeerGroupName = ygot.String(peerGrpNamev6P1) - - for _, nbr := range nbrs { - if nbr.isV4 { - nv4 := bgp.GetOrCreateNeighbor(nbr.neighborip) - nv4.PeerAs = ygot.Uint32(nbr.as) - nv4.Enabled = ygot.Bool(true) - nv4.PeerGroup = ygot.String(peerGrpNamev4P1) - afisafi := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - afisafi.Enabled = ygot.Bool(true) - nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(false) - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - rpl := pgv4.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - } else { - pgafv4 := pgv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - pgafv4.Enabled = ygot.Bool(true) - rpl := pgafv4.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - } - } else { - nv6 := bgp.GetOrCreateNeighbor(nbr.neighborip) - nv6.PeerAs = ygot.Uint32(nbr.as) - nv6.Enabled = ygot.Bool(true) - nv6.PeerGroup = ygot.String(peerGrpNamev6P1) - afisafi6 := nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) - afisafi6.Enabled = ygot.Bool(true) - nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(false) - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - rpl := pgv6.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - } else { - pgafv6 := pgv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) - pgafv6.Enabled = ygot.Bool(true) - rpl := pgafv6.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - - } - } - } - return niProto -} - -func createBGPNeighborP2(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { - nbrs := []*BGPNeighbor{ - {as: peerAs, neighborip: ateP2.IPv4, isV4: true}, - {as: peerAs, neighborip: ateP2.IPv6, isV4: false}, - } - - 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(localAs) - global.RouterId = ygot.String(dutP1.IPv4) - - 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. - pgv4 := bgp.GetOrCreatePeerGroup(peerGrpNamev4P2) - pgv4.PeerAs = ygot.Uint32(peerAs) - pgv4.PeerGroupName = ygot.String(peerGrpNamev4P2) - pgv6 := bgp.GetOrCreatePeerGroup(peerGrpNamev6P2) - pgv6.PeerAs = ygot.Uint32(peerAs) - pgv6.PeerGroupName = ygot.String(peerGrpNamev6P2) - - for _, nbr := range nbrs { - if nbr.isV4 { - nv4 := bgp.GetOrCreateNeighbor(nbr.neighborip) - nv4.PeerAs = ygot.Uint32(nbr.as) - nv4.Enabled = ygot.Bool(true) - nv4.PeerGroup = ygot.String(peerGrpNamev4P2) - afisafi := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - afisafi.Enabled = ygot.Bool(true) - nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(false) - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - rpl := pgv4.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - } else { - pgafv4 := pgv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) - pgafv4.Enabled = ygot.Bool(true) - rpl := pgafv4.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - } - } else { - nv6 := bgp.GetOrCreateNeighbor(nbr.neighborip) - nv6.PeerAs = ygot.Uint32(nbr.as) - nv6.Enabled = ygot.Bool(true) - nv6.PeerGroup = ygot.String(peerGrpNamev6P2) - afisafi6 := nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) - afisafi6.Enabled = ygot.Bool(true) - nv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(false) - if deviations.RoutePolicyUnderAFIUnsupported(dut) { - rpl := pgv6.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - } else { - pgafv6 := pgv6.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) - pgafv6.Enabled = ygot.Bool(true) - rpl := pgafv6.GetOrCreateApplyPolicy() - rpl.ImportPolicy = []string{rplName} - rpl.ExportPolicy = []string{rplName} - - } - } - } - return niProto -} - -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) - } - st.GetOrCreateActions().PolicyResult = pr - gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) -} - -func waitForBGPSession(t *testing.T, dut *ondatra.DUTDevice, wantEstablished bool) { - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() - nbrPath := statePath.Neighbor(ateP2.IPv4) - nbrPathv6 := statePath.Neighbor(ateP2.IPv6) - compare := func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { - state, ok := val.Val() - if ok { - if wantEstablished { - t.Logf("BGP session state: %s", state.String()) - return state == oc.Bgp_Neighbor_SessionState_ESTABLISHED - } - return state == oc.Bgp_Neighbor_SessionState_IDLE - } - return false - } - - _, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), 2*time.Minute, compare).Await(t) - if !ok { - fptest.LogQuery(t, "BGP reported state", nbrPath.State(), gnmi.Get(t, dut, nbrPath.State())) - if wantEstablished { - t.Fatal("No BGP neighbor formed...") - } else { - t.Fatal("BGPv4 session didn't teardown.") - } - } - _, ok = gnmi.Watch(t, dut, nbrPathv6.SessionState().State(), 2*time.Minute, compare).Await(t) - if !ok { - fptest.LogQuery(t, "BGPv6 reported state", nbrPathv6.State(), gnmi.Get(t, dut, nbrPathv6.State())) - if wantEstablished { - t.Fatal("No BGPv6 neighbor formed...") - } else { - t.Fatal("BGPv6 session didn't teardown.") - } - } -} - -func verifyBGPTelemetry(t *testing.T, dut *ondatra.DUTDevice) { - t.Log("Waiting for BGPv4 neighbor to establish...") - waitForBGPSession(t, dut, true) - -} - -func configureATE(t *testing.T) gosnappi.Config { - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - config := gosnappi.NewConfig() - // add ports - p1 := config.Ports().Add().SetName(ap1.ID()) - p2 := config.Ports().Add().SetName(ap2.ID()) - // add devices - d1 := config.Devices().Add().SetName("p1.d1") - d2 := config.Devices().Add().SetName("p2.d1") - // Configuration on port1. - d1Eth1 := d1.Ethernets(). - Add(). - SetName("p1.d1.eth1"). - SetMac("00:00:02:02:02:02"). - SetMtu(1500) - d1Eth1. - Connection(). - SetPortName(p1.Name()) - - d1ipv41 := d1Eth1. - Ipv4Addresses(). - Add(). - SetName("p1.d1.eth1.ipv4"). - SetAddress("192.0.2.2"). - SetGateway("192.0.2.1"). - SetPrefix(30) - - d1ipv61 := d1Eth1. - Ipv6Addresses(). - Add(). - SetName("p1.d1.eth1.ipv6"). - SetAddress("2001:db8::2"). - SetGateway("2001:db8::1"). - SetPrefix(126) - - // isis router - d1isis := d1.Isis(). - SetName("p1.d1.isis"). - SetSystemId("650000000001") - d1isis.Basic(). - SetIpv4TeRouterId(d1ipv41.Address()). - SetHostname("ixia-c-port1") - d1isis.Advanced().SetAreaAddresses([]string{"49"}) - d1isisint := d1isis.Interfaces(). - Add(). - SetName("p1.d1.isis.intf"). - SetEthName(d1Eth1.Name()). - SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). - SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2). - SetMetric(10) - d1isisint.TrafficEngineering().Add().PriorityBandwidths() - d1isisint.Advanced().SetAutoAdjustMtu(true).SetAutoAdjustArea(true).SetAutoAdjustSupportedProtocols(true) - - d1IsisRoute1 := d1isis.V4Routes().Add().SetName("p1.d1.isis.rr1") - d1IsisRoute1.Addresses(). - Add(). - SetAddress(isisRoute). - SetPrefix(32).SetCount(RouteCount) - - d1IsisRoute1v6 := d1isis.V6Routes().Add().SetName("p1.d1.isis.rr1.v6") - d1IsisRoute1v6.Addresses(). - Add(). - SetAddress(isisRoutev6). - SetPrefix(126).SetCount(RouteCount) - - configureBGPDev(d1, d1ipv41, d1ipv61, ate1AS) - - // configuration on port2 - d2Eth1 := d2.Ethernets(). - Add(). - SetName("p2.d1.eth1"). - SetMac("00:00:03:03:03:03"). - SetMtu(1500) - d2Eth1. - Connection(). - SetPortName(p2.Name()) - d2ipv41 := d2Eth1.Ipv4Addresses(). - Add(). - SetName("p2.d1.eth1.ipv4"). - SetAddress("192.0.2.6"). - SetGateway("192.0.2.5"). - SetPrefix(30) - - d2ipv61 := d2Eth1. - Ipv6Addresses(). - Add(). - SetName("p2.d1.eth1.ipv6"). - SetAddress("2001:db8::6"). - SetGateway("2001:db8::5"). - SetPrefix(126) - - // isis router - d2isis := d2.Isis(). - SetName("p2.d1.isis"). - SetSystemId("650000000001") - d2isis.Basic(). - SetIpv4TeRouterId(d2ipv41.Address()). - SetHostname("ixia-c-port2") - d2isis.Advanced().SetAreaAddresses([]string{"49"}) - d2isisint := d2isis.Interfaces(). - Add(). - SetName("p2.d1.isis.intf"). - SetEthName(d2Eth1.Name()). - SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). - SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2). - SetMetric(10) - d2isisint.TrafficEngineering().Add().PriorityBandwidths() - d2isisint.Advanced().SetAutoAdjustMtu(true).SetAutoAdjustArea(true).SetAutoAdjustSupportedProtocols(true) - - d2IsisRoute1 := d2isis.V4Routes().Add().SetName("p2.d1.isis.rr1") - d2IsisRoute1.Addresses(). - Add(). - SetAddress(isisRoute). - SetPrefix(32). - SetCount(RouteCount) - - d2IsisRoute1V6 := d2isis.V6Routes().Add().SetName("p2.d1.isis.rr1.v6") - d2IsisRoute1V6.Addresses(). - Add(). - SetAddress(isisRoutev6). - SetPrefix(126). - SetCount(RouteCount) - - configureBGPDev(d2, d2ipv41, d2ipv61, ate2AS) - - return config -} - -// configureBGPDev configures the BGP on the OTG dev -func configureBGPDev(dev gosnappi.Device, Ipv4 gosnappi.DeviceIpv4, Ipv6 gosnappi.DeviceIpv6, as int) { - - Bgp := dev.Bgp().SetRouterId(Ipv4.Address()) - Bgp4Peer := Bgp.Ipv4Interfaces().Add().SetIpv4Name(Ipv4.Name()).Peers().Add().SetName(dev.Name() + ".BGP4.peer") - Bgp4Peer.SetPeerAddress(Ipv4.Gateway()).SetAsNumber(uint32(as)).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) - Bgp6Peer := Bgp.Ipv6Interfaces().Add().SetIpv6Name(Ipv6.Name()).Peers().Add().SetName(dev.Name() + ".BGP6.peer") - Bgp6Peer.SetPeerAddress(Ipv6.Gateway()).SetAsNumber(uint32(as)).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) - - configureBGPv4Routes(Bgp4Peer, Ipv4.Address(), Bgp4Peer.Name()+"v4route", bgpRoute, RouteCount) - configureBGPv6Routes(Bgp6Peer, Ipv6.Address(), Bgp6Peer.Name()+"v6route", bgpRoutev6, RouteCount) - -} - -func configureBGPv4Routes(peer gosnappi.BgpV4Peer, ipv4 string, name string, prefix string, count uint32) { - routes := peer.V4Routes().Add().SetName(name) - routes.SetNextHopIpv4Address(ipv4). - SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). - SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) - routes.Addresses().Add(). - SetAddress(prefix). - SetPrefix(advertisedRoutesv4Prefix). - SetCount(count) -} - -func configureBGPv6Routes(peer gosnappi.BgpV6Peer, ipv6 string, name string, prefix string, count uint32) { - routes := peer.V6Routes().Add().SetName(name) - routes.SetNextHopIpv6Address(ipv6). - SetNextHopAddressType(gosnappi.BgpV6RouteRangeNextHopAddressType.IPV6). - SetNextHopMode(gosnappi.BgpV6RouteRangeNextHopMode.MANUAL) - routes.Addresses().Add(). - SetAddress(prefix). - SetPrefix(advertisedRoutesv6Prefix). - SetCount(count) -} -func VerifyDUT(t *testing.T, dut *ondatra.DUTDevice) { - - dni := deviations.DefaultNetworkInstance(dut) - if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv4Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { - t.Errorf("ipv4 BGP entries, got: %d, want: %d", got, RouteCount) - } else { - t.Logf("Test case Passed: ipv4 BGP entries, got: %d, want: %d", got, RouteCount) - } - if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv6Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { - t.Errorf("ipv6 BGP entries, got: %d, want: %d", got, RouteCount) - } else { - t.Logf("Test case Passed:ipv6 BGP entries, got: %d, want: %d", got, RouteCount) - } - - if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv4Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { - t.Errorf("ipv4 isis entries, got: %d, want: %d", got, RouteCount) - } else { - t.Logf("Test case Passed: ipv4 isis entries, got: %d, want: %d", got, RouteCount) - - } - - if got, ok := gnmi.Await(t, dut, gnmi.OC().NetworkInstance(dni).Afts().AftSummaries().Ipv6Unicast().Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS).Counters().AftEntries().State(), 1*time.Minute, uint64(RouteCount)).Val(); !ok { - t.Errorf("ipv6 isis entries, got: %d, want: %d", got, RouteCount) - } else { - t.Logf("Test case Passed: ipv6 isis entries, got: %d, want: %d", got, RouteCount) - } -} - -func TestBGP(t *testing.T) { - - dut := ondatra.DUT(t, "dut") - ate := ondatra.ATE(t, "ate") - // DUT Configuration - t.Log("Start DUT interface Config") - configureDUT(t, dut) - // ATE Configuration. - t.Log("Start ATE Config") - config := configureATE(t) - ate.OTG().PushConfig(t, config) - time.Sleep(time.Second * 20) - ate.OTG().StartProtocols(t) - time.Sleep(time.Second * 20) - verifyBGPTelemetry(t, dut) - VerifyDUT(t, dut) -} diff --git a/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go b/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go index bdecdb40c3b..d40b62036ec 100644 --- a/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go +++ b/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/bgp_override_as_path_split_horizon_test.go @@ -112,8 +112,6 @@ func bgpCreateNbr(t *testing.T, dut *ondatra.DUTDevice) *oc.NetworkInstance_Prot global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutPort2.IPv4) global.As = ygot.Uint32(dutGlobalAS) - 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. @@ -124,7 +122,6 @@ func bgpCreateNbr(t *testing.T, dut *ondatra.DUTDevice) *oc.NetworkInstance_Prot pg.PeerAs = ygot.Uint32(nbr.PeerAS) pg.LocalAs = ygot.Uint32(nbr.LocalAS) pg.PeerGroupName = ygot.String(nbr.PeerGrp) - pg.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) nv4 := bgp.GetOrCreateNeighbor(nbr.Neighborip) nv4.PeerGroup = ygot.String(nbr.PeerGrp) @@ -221,7 +218,6 @@ func advBGPRouteFromOTG(t *testing.T, args *otgTestArgs, asSeg []uint32) { // sent and received IPv4 prefixes. func verifyPrefixesTelemetry(t *testing.T, dut *ondatra.DUTDevice, nbr string, wantInstalled, wantSent uint32) { t.Helper() - time.Sleep(15 * time.Second) 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 { @@ -236,15 +232,15 @@ func verifyPrefixesTelemetry(t *testing.T, dut *ondatra.DUTDevice, nbr string, w func configureRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, name string, pr oc.E_RoutingPolicy_PolicyResultType) { d := &oc.Root{} rp := d.GetOrCreateRoutingPolicy() - pdef := rp.GetOrCreatePolicyDefinition(name) - stmt, err := pdef.AppendNewStatement(name) + pd := rp.GetOrCreatePolicyDefinition(name) + st, err := pd.AppendNewStatement("id-1") if err != nil { - t.Fatalf("AppendNewStatement(%s) failed: %v", name, err) + t.Fatal(err) } - stmt.GetOrCreateActions().PolicyResult = pr - // stmt.GetOrCreateConditions().InstallProtocolEq = oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) - + stc := st.GetOrCreateConditions() + stc.InstallProtocolEq = oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP + st.GetOrCreateActions().PolicyResult = pr + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) } // verifyOTGPrefixTelemetry is to Validate prefix received on OTG por2. @@ -329,6 +325,7 @@ func testSplitHorizonAllowOwnAs3(t *testing.T, args *otgTestArgs) { t.Log("Validate session state and capabilities received on DUT using telemetry.") cfgplugins.VerifyDUTBGPEstablished(t, args.dut) cfgplugins.VerifyBGPCapabilities(t, args.dut, []*cfgplugins.BgpNeighbor{nbr1, nbr2}) + t.Log("Verify that the DUT accepts the route.") verifyPrefixesTelemetry(t, args.dut, nbr1.Neighborip, 1, 0) verifyPrefixesTelemetry(t, args.dut, nbr2.Neighborip, 0, 1) @@ -443,7 +440,8 @@ func TestBGPOverrideASPathSplitHorizon(t *testing.T) { }) t.Run("Configure DEFAULT network instance", func(t *testing.T) { - fptest.ConfigureDefaultNetworkInstance(t, dut) + 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") diff --git a/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go b/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go index a1205cfa0c0..c7031776efc 100644 --- a/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go +++ b/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go @@ -123,7 +123,7 @@ var ( "linkbw_any": "^.*:.*$", } - communitySet = map[string]string{ + CommunitySet = map[string]string{ "regex_match_comm100": "^100:.*$", } ) @@ -182,65 +182,35 @@ func TestBGPLinkBandwidth(t *testing.T) { } baseSetupConfigAndVerification(t, td) configureExtCommunityRoutingPolicy(t, dut) - enableExtCommunityCLIConfig(t, dut) - + if deviations.BgpExplicitExtendedCommunityEnable(dut) { + enableExtCommunityCLIConfig(t, dut) + } testCases := []testCase{ { - name: "ImportPolicy set not_match_100_set_linkbw_1M", + name: "Policy set not_match_100_set_linkbw_1M", policyName: "not_match_100_set_linkbw_1M", - applyPolicy: applyImportPolicyDut, - validate: validateImportPolicyDut, - routeCommunity: extCommunity{prefixSet1Comm: "link-bandwidth:23456:1000000", prefixSet2Comm: "100:100", prefixSet3Comm: "link-bandwidth:23456:1000000"}, + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "link-bandwidth:23456:0"}, localPerf: false, validateRouteCommunityV4: validateRouteCommunityV4, validateRouteCommunityV6: validateRouteCommunityV6, }, { - name: "ExportPolicy set not_match_100_set_linkbw_1M", - policyName: "not_match_100_set_linkbw_1M", - applyPolicy: applyExportPolicyDut, - validate: validateExportPolicyDut, - routeCommunity: extCommunity{prefixSet1Comm: "link-bandwidth:23456:1000000", prefixSet2Comm: "100:100", prefixSet3Comm: "link-bandwidth:23456:1000000"}, - localPerf: false, - validateRouteCommunityV4: validateRouteCommunityV4, - validateRouteCommunityV6: validateRouteCommunityV6, - }, - { - name: "ImportPolicy set match_100_set_linkbw_2G", + name: "Policy set match_100_set_linkbw_2G", policyName: "match_100_set_linkbw_2G", - applyPolicy: applyImportPolicyDut, - validate: validateImportPolicyDut, - routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "link-bandwidth:23456:2000000000", prefixSet3Comm: "link-bandwidth:23456:1000"}, + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, + routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "link-bandwidth:23456:2000000000", prefixSet3Comm: "link-bandwidth:23456:0"}, localPerf: false, validateRouteCommunityV4: validateRouteCommunityV4, validateRouteCommunityV6: validateRouteCommunityV6, }, - { - name: "ExportPolicy set match_100_set_linkbw_2G", - policyName: "match_100_set_linkbw_2G", - applyPolicy: applyExportPolicyDut, - validate: validateExportPolicyDut, - routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "link-bandwidth:23456:2000000000", prefixSet3Comm: "link-bandwidth:23456:1000"}, - localPerf: false, - validateRouteCommunityV4: validateRouteCommunityV4, - validateRouteCommunityV6: validateRouteCommunityV6, - }, - { - name: "ImportPolicy set del_linkbw", + name: "Policy set del_linkbw", policyName: "del_linkbw", - applyPolicy: applyImportPolicyDut, - validate: validateImportPolicyDut, - routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "none"}, - localPerf: false, - validateRouteCommunityV4: validateRouteCommunityV4, - validateRouteCommunityV6: validateRouteCommunityV6, - }, - { - name: "ExportPolicy set del_linkbw", - policyName: "del_linkbw", - applyPolicy: applyExportPolicyDut, - validate: validateExportPolicyDut, + applyPolicy: applyPolicyDut, + validate: validatPolicyDut, routeCommunity: extCommunity{prefixSet1Comm: "none", prefixSet2Comm: "100:100", prefixSet3Comm: "none"}, localPerf: false, validateRouteCommunityV4: validateRouteCommunityV4, @@ -259,41 +229,25 @@ func TestBGPLinkBandwidth(t *testing.T) { } func enableExtCommunityCLIConfig(t *testing.T, dut *ondatra.DUTDevice) { - if deviations.BgpExplicitExtendedCommunityEnable(dut) { - var extCommunityEnableCLIConfig string - switch dut.Vendor() { - case ondatra.CISCO: - extCommunityEnableCLIConfig = fmt.Sprintf("router bgp %v instance BGP neighbor-group %v \n ebgp-recv-extcommunity-dmz \n ebgp-send-extcommunity-dmz\n", dutAS, cfgplugins.BGPPeerGroup1) - default: - t.Fatalf("Unsupported vendor %s for deviation 'BgpExplicitExtendedCommunityEnable'", dut.Vendor()) - } - helpers.GnmiCLIConfig(t, dut, extCommunityEnableCLIConfig) - } -} - -func removeImportAndExportPolicy(t *testing.T, dut *ondatra.DUTDevice) { - dni := deviations.DefaultNetworkInstance(dut) - - bd := &gnmi.SetBatch{} - path1 := 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() - path2 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort2.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() - path3 := 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() - path4 := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort2.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() - gnmi.BatchDelete(bd, path1.Config()) - gnmi.BatchDelete(bd, path2.Config()) - gnmi.BatchDelete(bd, path3.Config()) - gnmi.BatchDelete(bd, path4.Config()) - bd.Set(t, dut) + var extCommunityEnableCLIConfig string + switch dut.Vendor() { + case ondatra.CISCO: + extCommunityEnableCLIConfig = fmt.Sprintf("router bgp %v instance BGP neighbor-group %v \n ebgp-recv-extcommunity-dmz \n ebgp-send-extcommunity-dmz\n", dutAS, cfgplugins.BGPPeerGroup1) + default: + t.Fatalf("Unsupported vendor %s for deviation 'BgpExplicitExtendedCommunityEnable'", dut.Vendor()) + } + helpers.GnmiCLIConfig(t, dut, extCommunityEnableCLIConfig) } -func applyImportPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { +func applyPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { + // Apply ipv4 policy to bgp neighbour. root := &oc.Root{} dni := deviations.DefaultNetworkInstance(dut) - removeImportAndExportPolicy(t, 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() - // Apply ipv4 policy to bgp neighbour. - 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 := 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) @@ -315,70 +269,13 @@ func applyImportPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName strin gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config(), niProto) } -func applyExportPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { - root := &oc.Root{} - dni := deviations.DefaultNetworkInstance(dut) - removeImportAndExportPolicy(t, dut) - - // Apply ipv4 policy to bgp neighbour. - path := gnmi.OC().NetworkInstance(dni).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).Bgp().Neighbor(atePort2.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() - policy := root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort2.IPv4).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateApplyPolicy() - policy.SetExportPolicy([]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(atePort2.IPv6).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).ApplyPolicy() - policy = root.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, bgpName).GetOrCreateBgp().GetOrCreateNeighbor(atePort2.IPv6).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).GetOrCreateApplyPolicy() - policy.SetExportPolicy([]string{policyName}) - gnmi.Replace(t, dut, path.Config(), policy) - - ni := root.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - niProto := ni.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := niProto.GetOrCreateBgp() - bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) - bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) - bgpNbrV4 := bgp.GetOrCreateNeighbor(atePort1.IPv4) - bgpNbrV4.PeerGroup = ygot.String(cfgplugins.BGPPeerGroup1) - bgpNbrV6 := bgp.GetOrCreateNeighbor(atePort1.IPv6) - bgpNbrV6.PeerGroup = ygot.String(cfgplugins.BGPPeerGroup1) - gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config(), niProto) -} - -func validateImportPolicyDut(t *testing.T, dut *ondatra.DUTDevice, policyName string) { +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() - _, ok := gnmi.Watch(t, dut, path.State(), 30*time.Second, func(v *ygnmi.Value[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy]) bool { - value, ok := v.Val() - if !ok { - return false - } - importPolicies := value.GetImportPolicy() - if len(importPolicies) != 1 || importPolicies[0] != policyName { - return false - } - return true - }).Await(t) - if !ok { - t.Fatalf("invalid import policy") - } -} - -func validateExportPolicyDut(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(atePort2.IPv4).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).ApplyPolicy() - _, ok := gnmi.Watch(t, dut, path.State(), 30*time.Second, func(v *ygnmi.Value[*oc.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_ApplyPolicy]) bool { - value, ok := v.Val() - if !ok { - return false - } - exportPolicies := value.GetExportPolicy() - if len(exportPolicies) != 1 || exportPolicies[0] != policyName { - return false - } - return true - }).Await(t) - if !ok { - t.Fatalf("invalid export policy") + 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}) } } @@ -428,19 +325,20 @@ func validateRouteCommunityV4Prefix(t *testing.T, td testData, community, v4Pref for _, ec := range bgpPrefix.ExtendedCommunity { lbSubType := ec.Structured.NonTransitive_2OctetAsType.LinkBandwidthSubtype listCommunity := strings.Split(community, ":") - bandwidth := listCommunity[2] + Bandwidth := listCommunity[2] if lbSubType.GetGlobal_2ByteAs() != 23456 && lbSubType.GetGlobal_2ByteAs() != 32002 && lbSubType.GetGlobal_2ByteAs() != 32001 { t.Errorf("ERROR AS number should be 23456 or %d got %d", ateAS, lbSubType.GetGlobal_2ByteAs()) return } - if bandwidth == "1000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) == 0 { - t.Errorf("ERROR lb Bandwidth want 1000, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } else if bandwidth == "1000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 125000 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 1000000 { - t.Errorf("ERROR lb Bandwidth want :1M, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } else if bandwidth == "2000000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { - t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + if Bandwidth == "0" { + if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 0 { + t.Errorf("ERROR lb Bandwidth want 0, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } + } else { + if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { + t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } } - if !deviations.BgpExtendedCommunityIndexUnsupported(td.dut) { verifyExtCommunityIndexV4(t, td, v4Prefix) } @@ -463,6 +361,7 @@ func validateRouteCommunityV6(t *testing.T, td testData, ec extCommunity) { } func validateRouteCommunityV6Prefix(t *testing.T, td testData, community, v6Prefix string) { + // This function to verify received route communities on ATE ports. _, ok := gnmi.WatchAll(t, td.ate.OTG(), @@ -497,17 +396,19 @@ func validateRouteCommunityV6Prefix(t *testing.T, td testData, community, v6Pref for _, ec := range bgpPrefix.ExtendedCommunity { lbSubType := ec.Structured.NonTransitive_2OctetAsType.LinkBandwidthSubtype listCommunity := strings.Split(community, ":") - bandwidth := listCommunity[2] + Bandwidth := listCommunity[2] if lbSubType.GetGlobal_2ByteAs() != 23456 && lbSubType.GetGlobal_2ByteAs() != 32002 && lbSubType.GetGlobal_2ByteAs() != 32001 { t.Errorf("ERROR AS number should be 23456 or %d got %d", ateAS, lbSubType.GetGlobal_2ByteAs()) return } - if bandwidth == "1000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) == 0 { - t.Errorf("ERROR lb Bandwidth want 1000, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } else if bandwidth == "1000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 125000 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 1000000 { - t.Errorf("ERROR lb Bandwidth want :1M, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) - } else if bandwidth == "2000000000" && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { - t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + if Bandwidth == "0" { + if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 0 { + t.Errorf("ERROR lb Bandwidth want 0, got:=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } + } else { + if ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2.5e+08 && ygot.BinaryToFloat32(lbSubType.GetBandwidth()) != 2000000000 { + t.Errorf("ERROR lb Bandwidth want :2G, got=%v", ygot.BinaryToFloat32(lbSubType.GetBandwidth())) + } } if !deviations.BgpExtendedCommunityIndexUnsupported(td.dut) { verifyExtCommunityIndexV6(t, td, v6Prefix) @@ -518,7 +419,6 @@ func validateRouteCommunityV6Prefix(t *testing.T, td testData, community, v6Pref } } } - func configureImportRoutingPolicyAllowAll(t *testing.T, dut *ondatra.DUTDevice) { root := &oc.Root{} rp := root.GetOrCreateRoutingPolicy() @@ -609,10 +509,26 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { root := &oc.Root{} var communitySetCLIConfig string var extCommunitySetCLIConfig string - if deviations.BgpExtendedCommunitySetUnsupported(dut) { + switch dut.Vendor() { + case ondatra.CISCO: + extCommunitySet = extCommunitySetCisco + default: + t.Logf("extCommunitySet = %v", extCommunitySet) + } + if !deviations.BgpExtendedCommunitySetUnsupported(dut) { + 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) + } + } else { switch dut.Vendor() { case ondatra.CISCO: - extCommunitySet = extCommunitySetCisco for name, community := range extCommunitySet { if name == "linkbw_any" && deviations.CommunityMemberRegexUnsupported(dut) { communitySetCLIConfig = fmt.Sprintf("community-set %v \n dfa-regex '%v' \n end-set", name, community) @@ -625,55 +541,45 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { default: t.Fatalf("Unsupported vendor %s for native command support for deviation 'BgpExtendedCommunitySetUnsupported'", dut.Vendor()) } - } else { - for name, community := range extCommunitySet { + } + + if !(deviations.CommunityMemberRegexUnsupported(dut)) { + for name, community := range CommunitySet { rp := root.GetOrCreateRoutingPolicy() pdef := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets() - stmt, err := pdef.NewExtCommunitySet(name) + stmt, err := pdef.NewCommunitySet(name) if err != nil { - t.Fatalf("NewExtCommunitySet failed: %v", err) + t.Fatalf("NewCommunitySet failed: %v", err) } - stmt.SetExtCommunityMember([]string{community}) + cs := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} + cs = append(cs, oc.UnionString(community)) + stmt.SetCommunityMember(cs) gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) } - } - - if deviations.CommunityMemberRegexUnsupported(dut) { + } else { switch dut.Vendor() { case ondatra.CISCO: - for name, community := range communitySet { + for name, community := range CommunitySet { communitySetCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v' \n end-set", name, community) helpers.GnmiCLIConfig(t, dut, communitySetCLIConfig) } default: t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'CommunityMemberRegexUnsupported'", dut.Vendor()) } - } else { - for name, community := range communitySet { - rp := root.GetOrCreateRoutingPolicy() - pdef := rp.GetOrCreateDefinedSets().GetOrCreateBgpDefinedSets() - stmt, err := pdef.NewCommunitySet(name) - if err != nil { - t.Fatalf("NewCommunitySet failed: %v", err) - } - cs := []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{} - cs = append(cs, oc.UnionString(community)) - stmt.SetCommunityMember(cs) - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) - } } // 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("regex_match_comm100_rm_lbw") + pdef2Stmt1, err := pdef2.AppendNewStatement("1-megabit-match") if err != nil { - t.Fatalf("AppendNewStatement regex_match_comm100_rm_lbw failed: %v", err) + t.Fatalf("AppendNewStatement 1-megabit-match failed: %v", err) } + if !deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { ref := pdef2Stmt1.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() - ref.GetOrCreateReference().SetExtCommunitySetRefs([]string{"linkbw_any"}) - ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_REMOVE) + ref.GetOrCreateReference().SetExtCommunitySetRefs([]string{"linkbw_1M"}) + ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) ref.SetMethod(oc.SetCommunity_Method_REFERENCE) } if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { @@ -702,51 +608,25 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { if !deviations.SkipSettingStatementForPolicy(dut) { pdef2Stmt1.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) } - - pdef2Stmt2, err := pdef2.AppendNewStatement("regex_match_comm100_add_lbw") - if err != nil { - t.Fatalf("AppendNewStatement regex_match_comm100_add_lbw failed: %v", err) - } - if !deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { - ref := pdef2Stmt2.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetExtCommunity() - ref.GetOrCreateReference().SetExtCommunitySetRefs([]string{"linkbw_1M"}) - ref.SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD) - ref.SetMethod(oc.SetCommunity_Method_REFERENCE) - } - if deviations.BGPConditionsMatchCommunitySetUnsupported(dut) { - switch dut.Vendor() { - case ondatra.ARISTA: - ref1 := pdef2Stmt2.GetOrCreateConditions().GetOrCreateBgpConditions() - ref1.SetCommunitySet("regex_match_comm100_deviation1") - } - } else { - ref1 := pdef2Stmt2.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet() - ref1.SetCommunitySet("regex_match_comm100") - ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_INVERT) - } - if !deviations.SkipSettingStatementForPolicy(dut) { - pdef2Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_NEXT_STATEMENT) - } - - pdef2Stmt3, err := pdef2.AppendNewStatement("accept_all_routes") + pdef2Stmt2, err := pdef2.AppendNewStatement("accept_all_routes") if err != nil { t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) } - pdef2Stmt3.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + pdef2Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) - if deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { + if !deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpNotMatch) + } else { switch dut.Vendor() { case ondatra.CISCO: var communityCLIConfig string - communityCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match invert \n end-set", "regex_match_comm100", communitySet["regex_match_comm100"]) + communityCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match invert \n end-set", "regex_match_comm100", CommunitySet["regex_match_comm100"]) policySetCLIConfig := fmt.Sprintf("route-policy %v \n #statement-1 1-megabit-match \n if community is-empty then \n pass \n elseif community in %v then \n set extcommunity bandwidth %v \n endif \n pass \n #statement-2 accept_all_routes \n done \n end-policy", "not_match_100_set_linkbw_1M", "regex_match_comm100", "linkbw_1M") helpers.GnmiCLIConfig(t, dut, communityCLIConfig) helpers.GnmiCLIConfig(t, dut, policySetCLIConfig) default: t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'BgpSetExtCommunitySetRefsUnsupported'", dut.Vendor()) } - } else { - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpNotMatch) } // Configure routing policy match_100_set_linkbw_2G. @@ -781,7 +661,7 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { ref1.SetCommunitySet("regex_match_comm100_deviation2") } } else { - ref1 := pdef3Stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetOrCreateMatchCommunitySet() + ref1 := pdef3Stmt1.GetOrCreateConditions().GetOrCreateBgpConditions().GetMatchCommunitySet() ref1.SetCommunitySet("regex_match_comm100") ref1.SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsType_ANY) } @@ -793,18 +673,18 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) } pdef3Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) - if deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { + if !deviations.BgpSetExtCommunitySetRefsUnsupported(dut) { + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpMatch) + } else { switch dut.Vendor() { case ondatra.CISCO: - communitySetCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match any \n end-set", "regex_match_any_comm100", communitySet["regex_match_comm100"]) + communitySetCLIConfig = fmt.Sprintf("community-set %v\n dfa-regex '%v', \n match any \n end-set", "regex_match_any_comm100", CommunitySet["regex_match_comm100"]) helpers.GnmiCLIConfig(t, dut, communitySetCLIConfig) communitySetCLIConfig = fmt.Sprintf("route-policy %v \n #statement-1 2-gigabit-match \n if community in %v then \n set extcommunity bandwidth %v \n endif \n pass \n #statement-2 accept_all_routes \n done \n end-policy", "match_100_set_linkbw_2G", "regex_match_any_comm100", "linkbw_2G") helpers.GnmiCLIConfig(t, dut, communitySetCLIConfig) default: t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'BgpSetExtCommunitySetRefsUnsupported' and 'BGPConditionsMatchCommunitySetUnsupported' and 'SkipSettingStatementForPolicy'", dut.Vendor()) } - } else { - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpMatch) } // Configure routing policy del_linkbw. @@ -828,7 +708,9 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Fatalf("AppendNewStatement accept_all_routes failed: %v", err) } pdef4Stmt2.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) - if deviations.BgpDeleteLinkBandwidthUnsupported(dut) { + if !deviations.BgpDeleteLinkBandwidthUnsupported(dut) { + gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpDelLinkbw) + } else { var delLinkbwCLIConfig string switch dut.Vendor() { case ondatra.CISCO: @@ -837,11 +719,7 @@ func configureExtCommunityRoutingPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Fatalf("Unsupported vendor %s for native cmd support for deviation 'BgpDeleteLinkBandwidthUnsupported'", dut.Vendor()) } helpers.GnmiCLIConfig(t, dut, delLinkbwCLIConfig) - } else { - gnmi.Update(t, dut, gnmi.OC().RoutingPolicy().Config(), rpDelLinkbw) } - - fptest.LogQuery(t, "", gnmi.OC().RoutingPolicy().Config(), root) } func createFlow(t *testing.T, td testData, fc flowConfig) { @@ -923,7 +801,7 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { nV42 := bgp.GetOrCreateNeighbor(atePort2.IPv4) nV42.SetPeerAs(dutAS) if !deviations.SkipBgpSendCommunityType(td.dut) { - nV42.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_STANDARD, oc.Bgp_CommunityType_EXTENDED}) + nV42.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_BOTH}) } nV42.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) nV61 := bgp.GetOrCreateNeighbor(atePort1.IPv6) @@ -932,7 +810,7 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { nV62 := bgp.GetOrCreateNeighbor(atePort2.IPv6) nV62.SetPeerAs(dutAS) if !deviations.SkipBgpSendCommunityType(td.dut) { - nV62.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_STANDARD, oc.Bgp_CommunityType_EXTENDED}) + nV62.SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_BOTH}) } 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) @@ -971,12 +849,12 @@ func (td *testData) advertiseRoutesWithEBGP(t *testing.T) { netv43.Addresses().Add().SetAddress(advertisedIPv43.address).SetPrefix(advertisedIPv43.prefix) extcommv4 := netv43.ExtendedCommunities().Add().NonTransitive2OctetAsType().LinkBandwidthSubtype() extcommv4.SetGlobal2ByteAs(23456) - extcommv4.SetBandwidth(1000) + 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(23456) - extcommv6.SetBandwidth(1000) + extcommv6.SetBandwidth(0) // Configure iBGP on OTG port2. ipv42 := td.otgP2.Ethernets().Items()[0].Ipv4Addresses().Items()[0] diff --git a/feature/gribi/otg_tests/encap_decap_scale/README.md b/feature/gribi/otg_tests/encap_decap_scale/README.md index def619ebb79..050b8bae94a 100644 --- a/feature/gribi/otg_tests/encap_decap_scale/README.md +++ b/feature/gribi/otg_tests/encap_decap_scale/README.md @@ -326,7 +326,7 @@ network-instances { * Add 1 VRF for decapsulation, `DECAP_TE_VRF`. * Add 2 Tunnel VRFs, `TE_VRF_111` and `TE_VRF_222`. * Inject 5000 IPv4Entry-ies and 5000 IPv6Entry-ies to each of the 4 encap VRFs. - * The entries in the encap VRFs should point to NextHopGroups in the `DEFAULT` VRF. Inject 800 such NextHopGroups in the DEFAULT VRF. + * The entries in the encap VRFs should point to NextHopGroups in the `DEFAULT` VRF. Inject 200 such NextHopGroups in the DEFAULT VRF. * Each NextHopGroup should have 8 NextHops where each NextHop points to a tunnel in the `TE_VRF_111`. In addition, the weights specified in the NextHopGroup should be co-prime and the sum of the weights should be 16. * Inject `48` entries in the DECAP_TE_VRF where the entries have a mix of prefix lengths /22, /24, /26, and /28. @@ -395,7 +395,7 @@ network-instances { * outer_src: `ipv4_outer_src_111` * outer_dst: `ipv4_outer_decap_match` * dscp: `dscp_encap_d` - * proto: `41` + * proto: `41` ``` 3. Send traffic to DUT-1, covering all the installed v4 and v6 entries in the decap and encap VRFs. Validate that all traffic are all decapped per the DECAP VRFs and then encapsulated per the ENCAP VRFs and received as encapsulated packet by ATE. diff --git a/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go b/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go index 886a2554e2e..22b731e0879 100644 --- a/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go +++ b/feature/gribi/otg_tests/encap_decap_scale/encap_decap_scale_test.go @@ -107,7 +107,7 @@ const ( teVrf111TunnelCount = 1600 teVrf222TunnelCount = 1600 encapNhCount = 1600 - encapNhgcount = 800 + encapNhgcount = 200 encapIPv4Count = 5000 encapIPv6Count = 5000 decapIPv4Count = 48 @@ -368,7 +368,7 @@ func createIPv6Entries(startIP string, count uint64) []string { // pushEncapEntries pushes IP entries in a specified Encap VRFs and tunnel VRFs. // The entries in the encap VRFs should point to NextHopGroups in the DEFAULT VRF. -// Inject 800 such NextHopGroups in the DEFAULT VRF. Each NextHopGroup should have +// Inject 200 such NextHopGroups in the DEFAULT VRF. Each NextHopGroup should have // 8 NextHops where each NextHop points to a tunnel in the TE_VRF_111. // In addition, the weights specified in the NextHopGroup should be co-prime and the // sum of the weights should be 16. diff --git a/feature/isis/otg_tests/weighted_ecmp_test/README.md b/feature/isis/otg_tests/weighted_ecmp_test/README.md index 8a5bdf8448a..dee5ca53f52 100644 --- a/feature/isis/otg_tests/weighted_ecmp_test/README.md +++ b/feature/isis/otg_tests/weighted_ecmp_test/README.md @@ -29,25 +29,23 @@ G[DUT:LAG4] <-- IBGP+IS-IS --> H[LAG3:ATE2]; ## Procedure -### Test environment setup - -* Configure 1 aggregate interface with 2 100GE ports between DUT and ATE1 -* Configure 3 aggregate interfaces, each with 2 100GE ports between DUT and ATE2. -* Configure IPv4 and IPv6 L2 adjacencies between DUT and ATE aggregate interfaces. - Therefore, DUT will have - * 1xIS-IS adjacency with ATE1 DUT:LAG1<->ATE1:LAG1, - * 3xIS-IS adjacencies between DUT and ATE2 - * DUT:LAG2<->ATE2:LAG1 - * DUT:LAG3<->ATE2:LAG2 - * DUT:LAG4<->ATE2:LAG3 - - * Set ISIS parameters as - * /network-instances/network-instance/protocols/protocol/isis/global/ - * afi-safi/af/config/afi-name: IPV4, IPV6 - * afi-safi/af/config/safi-name: UNICAST - * afi-safi/af/config/enabled: true - * config/level-capability = LEVEL_2 - * /network-instances/network-instance/protocols/protocol/isis/levels/level/config/metric-style = WIDE_METRIC +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. @@ -76,7 +74,7 @@ G[DUT:LAG4] <-- IBGP+IS-IS --> H[LAG3:ATE2]; * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/weighted-ecmp/config/load-balancing-weight set to Auto -## RT-2.13.1: Equal distribution of traffic +## 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 @@ -116,7 +114,7 @@ G[DUT:LAG4] <-- IBGP+IS-IS --> H[LAG3:ATE2]; * /interfaces/interface/state/counters/in-pkts -## RT-2.13.2: Unequal distribution of traffic +## 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. @@ -144,8 +142,17 @@ G[DUT:LAG4] <-- IBGP+IS-IS --> H[LAG3:ATE2]; * /interfaces/interface/state/counters/in-pkts +### Config paths + +### Telemetry Parameter 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. + +TODO(OCPATH): Container path originally part of spec that needs to be separated +into leaves: /routing-policy/defined-sets/prefix-sets/prefix-set: + ```yaml paths: ## Config Paths ## diff --git a/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto b/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto index fb942581ff5..caa9410e80a 100644 --- a/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_logical_channels_test/metadata.textproto @@ -14,14 +14,3 @@ platform_exceptions: { missing_port_to_optical_channel_component_mapping: true } } -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - otn_channel_trib_unsupported: true - eth_channel_ingress_parameters_unsupported: true - eth_channel_assignment_cisco_numbering: true - otn_channel_assignment_cisco_numbering: true - } -} \ No newline at end of file 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 fdf5d9220e8..06dca4f91ed 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 @@ -1,8 +1,6 @@ package zr_logical_channels_test import ( - "flag" - "strings" "testing" "time" @@ -10,7 +8,6 @@ import ( "github.com/openconfig/featureprofiles/internal/attrs" "github.com/openconfig/featureprofiles/internal/cfgplugins" "github.com/openconfig/featureprofiles/internal/components" - "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/samplestream" "github.com/openconfig/ondatra" @@ -21,6 +18,7 @@ import ( const ( targetOutputPower = -9 frequency = 193100000 + dp16QAM = 1 samplingInterval = 10 * time.Second timeout = 10 * time.Minute otnIndex1 = uint32(4001) @@ -35,32 +33,21 @@ var ( IPv4: "192.0.2.1", IPv4Len: 30, } + dutPort2 = attrs.Attributes{ Desc: "dutPort2", IPv4: "192.0.2.5", IPv4Len: 30, } - operationalModeFlag = flag.Int("operational_mode", 1, "vendor-specific operational-mode for the channel") - operationalMode uint16 ) -type testcase struct { - desc string - got any - want any -} - func TestMain(m *testing.M) { fptest.RunTests(m) } func Test400ZRLogicalChannels(t *testing.T) { dut := ondatra.DUT(t, "dut") - if operationalModeFlag != nil { - operationalMode = uint16(*operationalModeFlag) - } else { - t.Fatalf("Please specify the vendor-specific operational-mode flag") - } + p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") @@ -74,10 +61,10 @@ func Test400ZRLogicalChannels(t *testing.T) { tr1 := gnmi.Get(t, dut, gnmi.OC().Interface(p1.Name()).Transceiver().State()) tr2 := gnmi.Get(t, dut, gnmi.OC().Interface(p2.Name()).Transceiver().State()) - cfgplugins.ConfigOpticalChannel(t, dut, oc1, frequency, targetOutputPower, operationalMode) + cfgplugins.ConfigOpticalChannel(t, dut, oc1, frequency, targetOutputPower, dp16QAM) cfgplugins.ConfigOTNChannel(t, dut, oc1, otnIndex1, ethernetIndex1) cfgplugins.ConfigETHChannel(t, dut, p1.Name(), tr1, otnIndex1, ethernetIndex1) - cfgplugins.ConfigOpticalChannel(t, dut, oc2, frequency, targetOutputPower, operationalMode) + cfgplugins.ConfigOpticalChannel(t, dut, oc2, frequency, targetOutputPower, dp16QAM) cfgplugins.ConfigOTNChannel(t, dut, oc2, otnIndex2, ethernetIndex2) cfgplugins.ConfigETHChannel(t, dut, p2.Name(), tr2, otnIndex2, ethernetIndex2) @@ -93,13 +80,13 @@ func Test400ZRLogicalChannels(t *testing.T) { gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP) - validateEthernetChannelTelemetry(t, dut, otnIndex1, ethernetIndex1, ethChan1) - validateEthernetChannelTelemetry(t, dut, otnIndex2, ethernetIndex2, ethChan2) - validateOTNChannelTelemetry(t, dut, otnIndex1, ethernetIndex1, oc1, otnChan1) - validateOTNChannelTelemetry(t, dut, otnIndex2, ethernetIndex2, oc2, otnChan2) + validateEthernetChannelTelemetry(t, otnIndex1, ethernetIndex1, ethChan1) + validateEthernetChannelTelemetry(t, otnIndex2, ethernetIndex2, ethChan2) + validateOTNChannelTelemetry(t, otnIndex1, ethernetIndex1, oc1, otnChan1) + validateOTNChannelTelemetry(t, otnIndex2, ethernetIndex2, oc2, otnChan2) } -func validateEthernetChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx, ethernetChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { +func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { 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") @@ -108,7 +95,11 @@ func validateEthernetChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnC if !ok { t.Fatalf("Ethernet Channel telemetry stream empty in last 10 seconds") } - tcs := []testcase{ + tcs := []struct { + desc string + got any + want any + }{ { desc: "Index", got: ec.GetIndex(), @@ -129,64 +120,32 @@ func validateEthernetChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnC got: ec.GetTribProtocol().String(), want: oc.TransportTypes_TRIBUTARY_PROTOCOL_TYPE_PROT_400GE.String(), }, + { + desc: "Assignment: Index", + got: ec.GetAssignment(0).GetIndex(), + want: uint32(0), + }, + { + desc: "Assignment: Logical Channel", + got: ec.GetAssignment(0).GetLogicalChannel(), + want: otnChIdx, + }, + { + desc: "Assignment: Description", + got: ec.GetAssignment(0).GetDescription(), + want: "ETH to OTN", + }, + { + desc: "Assignment: Allocation", + got: ec.GetAssignment(0).GetAllocation(), + want: float64(400), + }, + { + desc: "Assignment: Type", + got: ec.GetAssignment(0).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), + }, } - var assignmentIndexTestcases []testcase - - if deviations.EthChannelAssignmentCiscoNumbering(dut) { - assignmentIndexTestcases = []testcase{ - { - desc: "Assignment: Index", - got: ec.GetAssignment(1).GetIndex(), - want: uint32(1)}, - { - desc: "Assignment: Logical Channel", - got: ec.GetAssignment(1).GetLogicalChannel(), - want: otnChIdx, - }, - { - desc: "Assignment: Description", - got: ec.GetAssignment(1).GetDescription(), - want: "ETH to OTN", - }, - { - 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(), - }} - } else { - assignmentIndexTestcases = []testcase{ - { - desc: "Assignment: Index", - got: ec.GetAssignment(0).GetIndex(), - want: uint32(0), - }, - { - desc: "Assignment: Logical Channel", - got: ec.GetAssignment(0).GetLogicalChannel(), - want: otnChIdx, - }, - { - desc: "Assignment: Description", - got: ec.GetAssignment(0).GetDescription(), - want: "ETH to OTN", - }, - { - desc: "Assignment: Allocation", - got: ec.GetAssignment(0).GetAllocation(), - want: float64(400), - }, - { - desc: "Assignment: Type", - got: ec.GetAssignment(0).GetAssignmentType().String(), - want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), - }} - } - tcs = append(tcs, assignmentIndexTestcases...) for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { if diff := cmp.Diff(tc.got, tc.want); diff != "" { @@ -196,7 +155,7 @@ func validateEthernetChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnC } } -func validateOTNChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx uint32, ethChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { +func validateOTNChannelTelemetry(t *testing.T, otnChIdx uint32, ethChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) { val := stream.Next() // value received in the gnmi subscription within 10 seconds if val == nil { t.Fatalf("OTN Channel telemetry stream not received in last 10 seconds") @@ -205,7 +164,11 @@ func validateOTNChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx if !ok { t.Fatalf("OTN Channel telemetry stream empty in last 10 seconds") } - tcs := []testcase{ + tcs := []struct { + desc string + got any + want any + }{ { desc: "Description", got: cc.GetDescription(), @@ -221,97 +184,56 @@ func validateOTNChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx got: cc.GetLogicalChannelType().String(), want: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_OTN.String(), }, - } - var opticalChannelAssignmentIndexTestcases []testcase - - if deviations.OTNChannelAssignmentCiscoNumbering(dut) { - ciscoOpticalChannelFormat := strings.ReplaceAll(opticalChannel, "/", "_") // Ex: OpticalChannel0_0_0_18 - opticalChannelAssignmentIndexTestcases = []testcase{ - { - desc: "Assignment: Index", - got: cc.GetAssignment(1).GetIndex(), - want: uint32(1), - }, - { - desc: "Optical Channel Assignment: Optical Channel", - got: cc.GetAssignment(1).GetOpticalChannel(), - want: ciscoOpticalChannelFormat, - }, - { - desc: "Optical Channel Assignment: Description", - got: cc.GetAssignment(1).GetDescription(), - want: "OTN to Optical Channel", - }, - { - desc: "Optical Channel Assignment: Allocation", - got: cc.GetAssignment(1).GetAllocation(), - want: float64(400), - }, - { - desc: "Optical Channel Assignment: Type", - got: cc.GetAssignment(1).GetAssignmentType().String(), - want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(), - }, - } - } else { - opticalChannelAssignmentIndexTestcases = []testcase{ - { - desc: "Assignment: Index", - got: cc.GetAssignment(0).GetIndex(), - want: uint32(0)}, - { - desc: "Optical Channel Assignment: Optical Channel", - got: cc.GetAssignment(0).GetOpticalChannel(), - want: opticalChannel, - }, - { - desc: "Optical Channel Assignment: Description", - got: cc.GetAssignment(0).GetDescription(), - want: "OTN to Optical Channel", - }, - { - desc: "Optical Channel Assignment: Allocation", - got: cc.GetAssignment(0).GetAllocation(), - want: float64(400), - }, - { - desc: "Optical Channel Assignment: Type", - got: cc.GetAssignment(0).GetAssignmentType().String(), - want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(), - }, - } - } - tcs = append(tcs, opticalChannelAssignmentIndexTestcases...) - - if !deviations.OTNChannelTribUnsupported(dut) { - logicalChannelAssignmentTestcases := []testcase{ - { - desc: "Ethernet Assignment: Index", - got: cc.GetAssignment(1).GetIndex(), - want: uint32(1), - }, - { - desc: "Ethernet Assignment: Logical Channel", - got: cc.GetAssignment(1).GetLogicalChannel(), - want: ethChIdx, - }, - { - desc: "Ethernet Assignment: Description", - got: cc.GetAssignment(1).GetDescription(), - want: "OTN to ETH", - }, - { - desc: "Ethernet Assignment: Allocation", - got: cc.GetAssignment(1).GetAllocation(), - want: float64(400), - }, - { - desc: "Ethernet Assignment: Type", - got: cc.GetAssignment(1).GetAssignmentType().String(), - want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), - }, - } - tcs = append(tcs, logicalChannelAssignmentTestcases...) + { + desc: "Optical Channel Assignment: Index", + got: cc.GetAssignment(0).GetIndex(), + want: uint32(0), + }, + { + desc: "Optical Channel Assignment: Optical Channel", + got: cc.GetAssignment(0).GetOpticalChannel(), + want: opticalChannel, + }, + { + desc: "Optical Channel Assignment: Description", + got: cc.GetAssignment(0).GetDescription(), + want: "OTN to Optical Channel", + }, + { + desc: "Optical Channel Assignment: Allocation", + got: cc.GetAssignment(0).GetAllocation(), + want: float64(400), + }, + { + desc: "Optical Channel Assignment: Type", + got: cc.GetAssignment(0).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(), + }, + { + desc: "Ethernet Assignment: Index", + got: cc.GetAssignment(1).GetIndex(), + want: uint32(1), + }, + { + desc: "Ethernet Assignment: Logical Channel", + got: cc.GetAssignment(1).GetLogicalChannel(), + want: ethChIdx, + }, + { + desc: "Ethernet Assignment: Description", + got: cc.GetAssignment(1).GetDescription(), + want: "OTN to ETH", + }, + { + desc: "Ethernet Assignment: Allocation", + got: cc.GetAssignment(1).GetAllocation(), + want: float64(400), + }, + { + desc: "Ethernet Assignment: Type", + got: cc.GetAssignment(1).GetAssignmentType().String(), + want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(), + }, } for _, tc := range tcs { diff --git a/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto b/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto index e7ad71ae9dd..91557f86ff6 100644 --- a/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto +++ b/feature/platform/transceiver/tests/zr_pm_test/metadata.textproto @@ -13,14 +13,3 @@ platform_exceptions: { default_network_instance: "default" } } -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - otn_channel_trib_unsupported: true - eth_channel_ingress_parameters_unsupported: true - eth_channel_assignment_cisco_numbering: true - cisco_pre_fec_ber_inactive_value: true - } - } \ No newline at end of file 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 4ffd98c8287..455bf38a6cf 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 @@ -1,12 +1,10 @@ package zr_pm_test import ( - "flag" "testing" "time" "github.com/openconfig/featureprofiles/internal/cfgplugins" - "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/samplestream" "github.com/openconfig/ondatra" @@ -16,6 +14,7 @@ import ( ) const ( + dp16QAM = uint16(1) samplingInterval = 10 * time.Second minAllowedQValue = 7.0 maxAllowedQValue = 14.0 @@ -27,6 +26,7 @@ const ( inactivePreFECBER = 0.0 inactiveESNR = 0.0 timeout = 10 * time.Minute + flapInterval = 30 * time.Second otnIndexBase = uint32(4000) ethernetIndexBase = uint32(40000) ) @@ -34,8 +34,6 @@ const ( var ( frequencies = []uint64{191400000, 196100000} targetOpticalPowers = []float64{-9, -13} - operationalModeFlag = flag.Int("operational_mode", 1, "vendor-specific operational-mode for the channel") - operationalMode uint16 ) func TestMain(m *testing.M) { @@ -44,11 +42,7 @@ func TestMain(m *testing.M) { func TestPM(t *testing.T) { dut := ondatra.DUT(t, "dut") - if operationalModeFlag != nil { - operationalMode = uint16(*operationalModeFlag) - } else { - t.Fatalf("Please specify the vendor-specific operational-mode flag") - } + fptest.ConfigureDefaultNetworkInstance(t, dut) var ( @@ -77,7 +71,7 @@ func TestPM(t *testing.T) { for _, targetOpticalPower := range targetOpticalPowers { // Configure OCH component and OTN and ETH logical channels. for _, p := range dut.Ports() { - cfgplugins.ConfigOpticalChannel(t, dut, ochs[p.Name()], frequency, targetOpticalPower, operationalMode) + cfgplugins.ConfigOpticalChannel(t, dut, ochs[p.Name()], frequency, targetOpticalPower, dp16QAM) cfgplugins.ConfigOTNChannel(t, dut, ochs[p.Name()], otnIndexes[p.Name()], ethIndexes[p.Name()]) cfgplugins.ConfigETHChannel(t, dut, p.Name(), trs[p.Name()], otnIndexes[p.Name()], ethIndexes[p.Name()]) } @@ -141,7 +135,7 @@ func validateAllSamples(t *testing.T, dut *ondatra.DUTDevice, isEnabled bool, in if valIndex >= len(otnStreams[p.Name()].All()) { break } - operStatus := validateSampleStream(t, dut, interfaceStreams[p.Name()].All()[valIndex], otnStreams[p.Name()].All()[valIndex], p.Name()) + operStatus := validateSampleStream(t, interfaceStreams[p.Name()].All()[valIndex], otnStreams[p.Name()].All()[valIndex], p.Name()) switch operStatus { case oc.Interface_OperStatus_UP: if !isEnabled { @@ -157,7 +151,7 @@ func validateAllSamples(t *testing.T, dut *ondatra.DUTDevice, isEnabled bool, in } // validateSampleStream validates the stream data. -func validateSampleStream(t *testing.T, dut *ondatra.DUTDevice, interfaceData *ygnmi.Value[*oc.Interface], terminalDeviceData *ygnmi.Value[*oc.TerminalDevice_Channel], portName string) oc.E_Interface_OperStatus { +func validateSampleStream(t *testing.T, interfaceData *ygnmi.Value[*oc.Interface], terminalDeviceData *ygnmi.Value[*oc.TerminalDevice_Channel], portName string) oc.E_Interface_OperStatus { if interfaceData == nil { t.Errorf("Data not received for port %v.", portName) return oc.Interface_OperStatus_UNSET @@ -185,11 +179,7 @@ func validateSampleStream(t *testing.T, dut *ondatra.DUTDevice, interfaceData *y if b := otn.GetPreFecBer(); b == nil { t.Errorf("PreFECBER data is empty for port %v", portName) } else { - if deviations.CiscoPreFECBERInactiveValue(dut) { - validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, 0.5, operStatus) - } else { - validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, inactivePreFECBER, operStatus) - } + validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, inactivePreFECBER, operStatus) } if e := otn.GetEsnr(); e == nil { t.Errorf("ESNR data is empty for port %v", portName) @@ -213,7 +203,7 @@ func validatePMValue(t *testing.T, portName, pm string, instant, min, max, avg, return } case oc.Interface_OperStatus_DOWN: - if instant > inactiveValue { + if instant != 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 } diff --git a/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md b/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md index e0b5b2ba32b..51ac7dab893 100644 --- a/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md +++ b/feature/system/gnmi/metadata/tests/large_set_consistency_test/README.md @@ -40,13 +40,3 @@ dut.testbed ## Minimum DUT platform FFF - -## OpenConfig Path and RPC Coverage - -```yaml -rpcs: - gnmi: - gNMI.Get: - gNMI.Subscribe: - -``` \ No newline at end of file diff --git a/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go b/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go index 5dbc85b2572..84b7e7af943 100644 --- a/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go +++ b/feature/system/gnmi/metadata/tests/large_set_consistency_test/large_set_consistency_test.go @@ -49,6 +49,57 @@ func TestMain(m *testing.M) { fptest.RunTests(m) } +// getDeviceConfig gets a full config from a device but refurbishes it enough so it can be +// pushed out again +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) + + for cname, component := range config.Component { + // Keep the port components in order to preserve the breakout-mode config. + if component.GetPort() == nil { + delete(config.Component, cname) + continue + } + // Need to prune subcomponents that may have a leafref to a component that was + // pruned. + component.Subcomponent = nil + } + + for iname, iface := range config.Interface { + if iface.GetEthernet() == nil { + continue + } + // 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) + } + ygot.PruneConfigFalse(oc.SchemaTree["Interface_Ethernet"], e) + if e.PortSpeed != 0 && e.PortSpeed != oc.IfEthernet_ETHERNET_SPEED_SPEED_UNKNOWN { + iface.Ethernet = e + } + } + + if config.Lldp != nil { + config.Lldp.ChassisId = nil + config.Lldp.ChassisIdType = oc.Lldp_ChassisIdType_UNSET + } + + config.Qos = nil + + for _, ni := range config.NetworkInstance { + ni.Fdb = nil + } + + fptest.WriteQuery(t, "Touched", gnmi.OC().Config(), config) + return config +} + // setEthernetFromBase merges the ethernet config from the interfaces in base config into // the destination config. func setEthernetFromBase(t testing.TB, config *oc.Root) { @@ -193,7 +244,8 @@ func checkMetadata1(t *testing.T, gnmiClient gpb.GNMIClient, dut *ondatra.DUTDev t.Helper() got, getRespTimeStamp := extractMetadataAnnotation(t, gnmiClient, dut) want := metadata1 - if got != want && getRespTimeStamp < done.Load() { + t.Logf("getResp: %v ", getRespTimeStamp) + if got != want && done.Load() == 0 { t.Errorf("extractMetadataAnnotation: got %v, want %v", got, want) } } @@ -216,15 +268,13 @@ func TestLargeSetConsistency(t *testing.T) { p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") - fptest.ConfigureDefaultNetworkInstance(t, dut) - // 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) - baselineConfig := fptest.GetDeviceConfig(t, dut) + baselineConfig := getDeviceConfig(t, dut) setEthernetFromBase(t, baselineConfig) gnmiClient := dut.RawAPIs().GNMI(t) 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 c346a8d5da2..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 @@ -13,12 +13,4 @@ platform_exceptions: { default_network_instance: "default" } } -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - skip_macaddress_check: true - } -} 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 d169ecec2f9..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 @@ -45,8 +45,22 @@ var ( skipContainerOp = flag.Bool("skip_container_op", false, "Skip ContainerOp test cases.") skipItemOp = flag.Bool("skip_item_op", false, "Skip ItemOp test cases.") + // The following experimental flags fine-tune the RootOp and ContainerOp behavior. Some + // devices require the config to be pruned for these to work. We are still undecided + // whether they should be deviations; pending OpenConfig clarifications. + pruneComponents = flag.Bool("prune_components", true, "Prune components that are not ports. Use this to preserve the breakout-mode settings.") + pruneLLDP = flag.Bool("prune_lldp", true, "Prune LLDP config.") + setEthernetFromState = flag.Bool("set_ethernet_from_state", true, "Set interface/ethernet config from state, mostly to get the port-speed settings correct.") + + // This has no known effect except to reduce logspam while debugging. + 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 ( @@ -222,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) @@ -822,7 +840,7 @@ func forEachPushOp( f func(t *testing.T, op pushOp, config *oc.Root), ) { baselineConfigOnce.Do(func() { - baselineConfig = fptest.GetDeviceConfig(t, dut) + baselineConfig = getDeviceConfig(t, dut) }) for _, op := range []pushOp{ @@ -832,12 +850,154 @@ func forEachPushOp( if op.shouldSkip() { t.Skip() } - config := fptest.CopyDeviceConfig(t, dut, baselineConfig) + o, err := ygot.DeepCopy(baselineConfig) + if err != nil { + t.Fatalf("Cannot copy baseConfig: %v", err) + } + config := o.(*oc.Root) f(t, op, config) }) } } +// getDeviceConfig gets a full config from a device but refurbishes it enough so it can be +// pushed out again. Ideally, we should be able to push the config we get from the same +// device without modification, but this is not explicitly defined in OpenConfig. +func getDeviceConfig(t testing.TB, dev gnmi.DeviceOrOpts) *oc.Root { + t.Helper() + + // Gets all the config (read-write) paths from root, not the state (read-only) paths. + 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. + if component.GetPort() == nil { + delete(config.Component, cname) + continue + } + // Need to prune subcomponents that may have a leafref to a component that was + // pruned. + component.Subcomponent = nil + } + } + + if *setEthernetFromState { + for iname, iface := range config.Interface { + if iface.GetEthernet() == nil { + continue + } + // 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()) + e := intf.GetEthernet() + 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 + } + } + + if *pruneLLDP && config.Lldp != nil { + config.Lldp.ChassisId = nil + config.Lldp.ChassisIdType = oc.Lldp_ChassisIdType_UNSET + } + + if *pruneQoS { + config.Qos = nil + } + + pruneUnsupportedPaths(config) + + fptest.WriteQuery(t, "Touched", gnmi.OC().Config(), config) + return config +} + +func pruneUnsupportedPaths(config *oc.Root) { + for _, ni := range config.NetworkInstance { + ni.Fdb = nil + } +} + // pushScope describe the config scope that the test case wants to modify. This is for // itemOp only; rootOp and containerOp ignore this. type pushScope struct { @@ -852,6 +1012,23 @@ type pushOp interface { push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, scope *pushScope) } +// setEthernetFromBase merges the ethernet config from the interfaces in base config into +// the destination config. +func setEthernetFromBase(t testing.TB, base *oc.Root, config *oc.Root) { + t.Helper() + + for iname, iface := range config.Interface { + eb := base.GetInterface(iname).GetEthernet() + ec := iface.GetOrCreateEthernet() + if eb == nil || ec == nil { + continue + } + if err := ygot.MergeStructInto(ec, eb); err != nil { + t.Errorf("Cannot merge %s ethernet: %v", iname, err) + } + } +} + // rootOp pushes config using replace at root. type rootOp struct{ base *oc.Root } @@ -860,6 +1037,9 @@ func (rootOp) shouldSkip() bool { return *skipRootOp } func (op rootOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, _ *pushScope) { t.Helper() + if *setEthernetFromState { + setEthernetFromBase(t, op.base, config) + } fptest.WriteQuery(t, "RootOp", gnmi.OC().Config(), config) dut := ondatra.DUT(t, "dut") if deviations.AddMissingBaseConfigViaCli(dut) { @@ -880,6 +1060,9 @@ func (containerOp) shouldSkip() bool { return *skipContainerOp } func (op containerOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, _ *pushScope) { t.Helper() + if *setEthernetFromState { + setEthernetFromBase(t, op.base, config) + } fptest.WriteQuery(t, "ContainerOp", gnmi.OC().Config(), config) batch := &gnmi.SetBatch{} @@ -912,6 +1095,9 @@ func (itemOp) shouldSkip() bool { return *skipItemOp } func (op itemOp) push(t testing.TB, dev gnmi.DeviceOrOpts, config *oc.Root, scope *pushScope) { t.Helper() + if *setEthernetFromState { + setEthernetFromBase(t, op.base, config) + } fptest.WriteQuery(t, "ItemOp", gnmi.OC().Config(), config) batch := &gnmi.SetBatch{} diff --git a/internal/deviations/README.md b/internal/deviations/README.md index a42d37cfd59..670bdbe9226 100644 --- a/internal/deviations/README.md +++ b/internal/deviations/README.md @@ -1,57 +1,21 @@ -# Guidelines to add deviations to FNT tests +## Guidelines to add deviations to FNT tests -## When to use deviations +### Adding Deviations -1. Deviations may be created to use alternate OC or use CLI instead of OC to - achieve the operational intent described in the README. -2. Deviations should not be created which change the operational intent. See - below for guidance on changing operational intent. -3. Deviations may be created to change which OC path is used for telemetry or - use an implementation's native yang path.  Deviations for telemetry - should not introduce a depedency on CLI output. -4. As with any pull request (PR), the CODEOWNERs must review and approve (or - delegate if appropriate). -5. The CODEOWNERs must ensure the README and code reflects the agreed to - operational support goal.  This may be done via offline discussions or - directly via approvals in the github PR. +* Add the deviation to the `Deviations` message in the [proto/metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) file. -See [Deviation Examples](#deviation-examples) for more information. - -## When not to use a deviation - -Deviations should not be used to skip configuration or skip validations. If the -feature is not supported and there is no workaround to achieve -the functionality, then the test should fail for that platform. - -If the README is in error, the README can be updated and code can be changed -(without introducing deviation) with approval from the CODEOWNERs. - -If the intent of the README needs to be changed (not due to an error, but a -change in the feature request), the CODEOWNER must ensure all parties are -notified. The CODEOWNER must determine if the change is late or early in the -development cycle. If late (development is underway and/or nearly complete), it -is recommended to create a new test which represents the change. If early in -the feature request (development has not started or is very early stage), then -the existing README and code may be updated. - -## Adding Deviations - -* Add the deviation to the `Deviations` message in the - [proto/metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) - file. - -```go + ``` message Deviations { ... // Device does not support fragmentation bit for traceroute. bool traceroute_fragmentation = 2; ... } -``` + ``` * Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles root directory to generate the Go code for the added proto fields. -```shell + ``` $ make proto/metadata_go_proto/metadata.pb.go mkdir -p proto/metadata_go_proto # Set directory to hold symlink @@ -66,57 +30,36 @@ the existing README and code may be updated. go list -f '{{ .Dir }} protobuf-import/{{ .Path }}' -m github.com/openconfig/ondatra | xargs -L1 -- ln -s 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 -``` - -* Add the accessor function for this deviation to the - [internal/deviations/deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) - file. This function will need to accept a parameter `dut` of type - `*ondatra.DUTDevice` to lookup the deviation value for a specific dut. This - accessor function must call `lookupDUTDeviations` and return the deviation - value. Test code will use this function to access deviations. - * If the default value of the deviation is the same as the default value for - the proto field, the accessor method can directly call the `Get*()` function - for the deviation field. For example, the boolean `traceroute_fragmentation` - deviation, which has a default value of `false`, will have an accessor - method with the single line `return - lookupDUTDeviations(dut).GetTracerouteFragmentation()`. - - ```go - // TraceRouteFragmentation returns if the device does not support fragmentation bit for traceroute. - // Default value is false. - func TraceRouteFragmentation(dut *ondatra.DUTDevice) bool { - return lookupDUTDeviations(dut).GetTracerouteFragmentation() - } - ``` - - * If the default value of deviation is not the same as the default value of - the proto field, the accessor method can add a check and return the required - default value. For example, the accessor method for the float - `hierarchical_weight_resolution_tolerance` deviation, which has a default - value of `0`, will call the `GetHierarchicalWeightResolutionTolerance()` to - check the value set in `metadata.textproto` and return the default value - `0.2` if applicable. - - ```go - // HierarchicalWeightResolutionTolerance returns the allowed tolerance for BGP traffic flow while comparing for pass or fail conditions. - // Default minimum value is 0.2. Anything less than 0.2 will be set to 0.2. - func HierarchicalWeightResolutionTolerance(dut *ondatra.DUTDevice) float64 { - hwrt := lookupDUTDeviations(dut).GetHierarchicalWeightResolutionTolerance() - if minHWRT := 0.2; hwrt < minHWRT { + ``` + +* Add the accessor function for this deviation to the [internal/deviations/deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) file. This function will need to accept a parameter `dut` of type `*ondatra.DUTDevice` to lookup the deviation value for a specific dut. This accessor function must call `lookupDUTDeviations` and return the deviation value. Test code will use this function to access deviations. + * If the default value of the deviation is the same as the default value for the proto field, the accessor method can directly call the `Get*()` function for the deviation field. For example, the boolean `traceroute_fragmentation` deviation, which has a default value of `false`, will have an accessor method with the single line `return lookupDUTDeviations(dut).GetTracerouteFragmentation()`. + + ``` + // TraceRouteFragmentation returns if the device does not support fragmentation bit for traceroute. + // Default value is false. + func TraceRouteFragmentation(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetTracerouteFragmentation() + } + ``` + + * If the default value of deviation is not the same as the default value of the proto field, the accessor method can add a check and return the required default value. For example, the accessor method for the float `hierarchical_weight_resolution_tolerance` deviation, which has a default value of `0`, will call the `GetHierarchicalWeightResolutionTolerance()` to check the value set in `metadata.textproto` and return the default value `0.2` if applicable. + + ``` + // HierarchicalWeightResolutionTolerance returns the allowed tolerance for BGP traffic flow while comparing for pass or fail conditions. + // Default minimum value is 0.2. Anything less than 0.2 will be set to 0.2. + func HierarchicalWeightResolutionTolerance(dut *ondatra.DUTDevice) float64 { + hwrt := lookupDUTDeviations(dut).GetHierarchicalWeightResolutionTolerance() + if minHWRT := 0.2; hwrt < minHWRT { return minHWRT - } - return hwrt - } - ``` - -* Set the deviation value in the `metadata.textproto` file in the same folder as - the test. For example, the deviations used in the test - `feature/gnoi/system/tests/traceroute_test/traceroute_test.go` will be set in - the file `feature/gnoi/system/tests/traceroute_test/metadata.textproto`. List - all the vendor and optionally also hardware model regex that this deviation is - applicable for. - - ```go + } + return hwrt + } + ``` + +* Set the deviation value in the `metadata.textproto` file in the same folder as the test. For example, the deviations used in the test `feature/gnoi/system/tests/traceroute_test/traceroute_test.go` will be set in the file `feature/gnoi/system/tests/traceroute_test/metadata.textproto`. List all the vendor and optionally also hardware model regex that this deviation is applicable for. + + ``` ... platform_exceptions: { platform: { @@ -130,69 +73,30 @@ the existing README and code may be updated. ... ``` -* To access the deviation from the test call the accessor function for the - deviation. Pass the dut to this accessor. +* To access the deviation from the test call the accessor function for the deviation. Pass the dut to this accessor. - ```go + ``` if deviations.TraceRouteFragmentation(dut) { ... } ``` -* Example PRs - and - - -## Removing Deviations +* Example PRs - https://github.com/openconfig/featureprofiles/pull/1649 and + https://github.com/openconfig/featureprofiles/pull/1668 -* Once a deviation is no longer required and removed from all tests, delete the - deviation by removing them from the following files: +### Removing Deviations - * metadata.textproto - Remove the deviation field from all metadata.textproto - in all tests. +* Once a deviation is no longer required and removed from all tests, delete the deviation by removing them from the following files: - * Remove the accessor method from - [deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) + * metadata.textproto - Remove the deviation field from all metadata.textproto in all tests. - * Remove the field number from - [metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) - by adding the `reserved n` to the `Deviations` message. Ref: - + * [deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) - Remove the accessor method for this deviation. -* Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles - root directory to update the Go code for the removed proto fields. + * [metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) - Remove the deviation field from the `Deviations` message and reserve the deleted field number by adding the `reserved n` to the `Deviations` message. +Ref: https://protobuf.dev/programming-guides/proto3/#deleting -## Deviation examples - -```go -conf := configureDUT(dut) // returns *oc.Root - -if deviations.AlternateOCEnabled(t, dut) { - switch dut.Vendor() { - case ondatra.VENDOR_X: - conf.SetAlternateOC(val) - } -} else { - conf.SetRequiredOC(val) -} -``` - -```go -conf := configureDUT(dut) // returns *oc.Root - -if deviations.RequiredOCNotSupported(t, dut) { - switch dut.Vendor() { - case ondatra.VENDOR_X: - configureDeviceUsingCli(t, dut, vendorXConfig) - } -} -``` +* Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles root directory to update the Go code for the removed proto fields. ## Notes - -* If you run into issues with the `make proto/metadata_go_proto/metadata.pb.go` - you may need to check if the `protoc` module is installed in your environment. - Also depending on your Go version you may need to update your PATH and GOPATH. -* After running the `make proto/metadata_go_proto/metadata.pb.go` script, a - `protobuf-import/` folder will be added in your current directory. Keep an eye - out for this in case you use `git add .` to add modified files since this - folder should not be part of your PR. +* If you run into issues with the `make proto/metadata_go_proto/metadata.pb.go` you may need to check if the `protoc` module is installed in your environment. Also depending on your Go version you may need to update your PATH and GOPATH. +* After running the `make proto/metadata_go_proto/metadata.pb.go` script, a `protobuf-import/` folder will be added in your current directory. Keep an eye out for this in case you use `git add .` to add modified files since this folder should not be part of your PR. diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 13fe41e364b..93ef505adb3 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -1208,18 +1208,7 @@ func BgpAllowownasDiffDefaultValue(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetBgpAllowownasDiffDefaultValue() } -// OTNChannelAssignmentCiscoNumbering returns true if OTN channel assignment index starts from 1 instead of 0 -func OTNChannelAssignmentCiscoNumbering(dut *ondatra.DUTDevice) bool { - return lookupDUTDeviations(dut).GetOtnChannelAssignmentCiscoNumbering() -} - -// CiscoPreFECBERInactiveValue returns true if a non-zero pre-fec-ber value is to be used for Cisco -func CiscoPreFECBERInactiveValue(dut *ondatra.DUTDevice) bool { - return lookupDUTDeviations(dut).GetCiscoPreFecBerInactiveValue() -} - // Admin Enable Table Connections in SRL native func EnableTableConnections(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetEnableTableConnections() } - diff --git a/internal/fptest/config.go b/internal/fptest/config.go deleted file mode 100644 index bb976eea456..00000000000 --- a/internal/fptest/config.go +++ /dev/null @@ -1,205 +0,0 @@ -package fptest - -import ( - "flag" - "testing" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" -) - -var ( - // Some devices require the config to be pruned for these to work. We are still undecided - // whether they should be deviations; pending OpenConfig clarifications. - pruneComponents = flag.Bool("prune_components", true, "Prune components that are not ports. Use this to preserve the breakout-mode settings.") - pruneLLDP = flag.Bool("prune_lldp", true, "Prune LLDP config.") - setEthernetFromState = flag.Bool("set_ethernet_from_state", true, "Set interface/ethernet config from state, mostly to get the port-speed settings correct.") - - // This has no known effect except to reduce logspam while debugging. - pruneQoS = flag.Bool("prune_qos", true, "Prune QoS config.") - - // Experimental flags that will likely become a deviation. - 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.") -) - -// GetDeviceConfig gets a full config from a device but refurbishes it enough so it can be -// pushed out again. Ideally, we should be able to push the config we get from the same -// device without modification, but this is not explicitly defined in OpenConfig. -func GetDeviceConfig(t testing.TB, dev gnmi.DeviceOrOpts) *oc.Root { - t.Helper() - - // Gets all the config (read-write) paths from root, not the state (read-only) paths. - config := gnmi.Get[*oc.Root](t, dev, gnmi.OC().Config()) - 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. - if component.GetPort() == nil { - delete(config.Component, cname) - continue - } - // Need to prune subcomponents that may have a leafref to a component that was - // pruned. - component.Subcomponent = nil - } - } - - if *setEthernetFromState { - for iname, iface := range config.Interface { - if iface.GetEthernet() == nil { - continue - } - // 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()) - e := intf.GetEthernet() - 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 - } - } - - if *pruneLLDP && config.Lldp != nil { - config.Lldp.ChassisId = nil - config.Lldp.ChassisIdType = oc.Lldp_ChassisIdType_UNSET - } - - if *pruneQoS { - config.Qos = nil - } - - pruneUnsupportedPaths(config) - - WriteQuery(t, "Touched", gnmi.OC().Config(), config) - return config -} - -// CopyDeviceConfig returns a deep copy of a device config but refurbishes it enough so it can be -// pushed out again -func CopyDeviceConfig(t testing.TB, dut *ondatra.DUTDevice, config *oc.Root) *oc.Root { - if deviations.SkipMacaddressCheck(dut) { - *setEthernetFromState = false - } - - o, err := ygot.DeepCopy(config) - if err != nil { - t.Fatalf("Cannot copy baseConfig: %v", err) - } - - copy := o.(*oc.Root) - - if *setEthernetFromState { - setEthernetFromBase(t, config, copy) - } - - return copy -} - -func pruneUnsupportedPaths(config *oc.Root) { - for _, ni := range config.NetworkInstance { - ni.Fdb = nil - } -} - -// setEthernetFromBase merges the ethernet config from the interfaces in base config into -// the destination config. -func setEthernetFromBase(t testing.TB, base *oc.Root, config *oc.Root) { - t.Helper() - - for iname, iface := range config.Interface { - eb := base.GetInterface(iname).GetEthernet() - ec := iface.GetOrCreateEthernet() - if eb == nil || ec == nil { - continue - } - if err := ygot.MergeStructInto(ec, eb); err != nil { - t.Errorf("Cannot merge %s ethernet: %v", iname, err) - } - } -} diff --git a/internal/security/acctz/acctz.go b/internal/security/acctz/acctz.go index 6f475e14e1e..6837c82f0bc 100644 --- a/internal/security/acctz/acctz.go +++ b/internal/security/acctz/acctz.go @@ -27,8 +27,8 @@ import ( "testing" "time" - gnmipb "github.com/openconfig/gnmi/proto/gnmi" - systempb "github.com/openconfig/gnoi/system" + "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/gnoi/system" acctzpb "github.com/openconfig/gnsi/acctz" authzpb "github.com/openconfig/gnsi/authz" cpb "github.com/openconfig/gnsi/credentialz" @@ -113,7 +113,7 @@ func setupUserPassword(t *testing.T, dut *ondatra.DUTDevice, username, password time.Sleep(time.Second) } -func nokiaFailCliRole(t *testing.T) *gnmipb.SetRequest { +func nokiaFailCliRole(t *testing.T) *gnmi.SetRequest { failRoleData, err := json.Marshal([]any{ map[string]any{ "services": []string{"cli"}, @@ -126,22 +126,22 @@ func nokiaFailCliRole(t *testing.T) *gnmipb.SetRequest { t.Fatalf("Error with json marshal: %v", err) } - return &gnmipb.SetRequest{ - Prefix: &gnmipb.Path{ + return &gnmi.SetRequest{ + Prefix: &gnmi.Path{ Origin: "native", }, - Replace: []*gnmipb.Update{ + Replace: []*gnmi.Update{ { - Path: &gnmipb.Path{ - Elem: []*gnmipb.PathElem{ + Path: &gnmi.Path{ + Elem: []*gnmi.PathElem{ {Name: "system"}, {Name: "aaa"}, {Name: "authorization"}, {Name: "role", Key: map[string]string{"rolename": failRoleName}}, }, }, - Val: &gnmipb.TypedValue{ - Value: &gnmipb.TypedValue_JsonIetfVal{ + Val: &gnmi.TypedValue{ + Value: &gnmi.TypedValue_JsonIetfVal{ JsonIetfVal: failRoleData, }, }, @@ -157,7 +157,7 @@ func SetupUsers(t *testing.T, dut *ondatra.DUTDevice, configureFailCliRole bool) successUser.SetRole(oc.AaaTypes_SYSTEM_DEFINED_ROLES_SYSTEM_ROLE_ADMIN) failUser := auth.GetOrCreateUser(failUsername) if configureFailCliRole { - var SetRequest *gnmipb.SetRequest + var SetRequest *gnmi.SetRequest // Create failure cli role in native. switch dut.Vendor() { @@ -325,13 +325,13 @@ func SendGnmiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons var records []*acctzpb.RecordResponse grpcConn := dialGrpc(t, target) - gnmiClient := gnmipb.NewGNMIClient(grpcConn) + gnmiClient := gnmi.NewGNMIClient(grpcConn) ctx := context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", failUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", failPassword) // Send an unsuccessful gNMI capabilities request (bad creds in context). - _, err := gnmiClient.Capabilities(ctx, &gnmipb.CapabilityRequest{}) + _, err := gnmiClient.Capabilities(ctx, &gnmi.CapabilityRequest{}) if err != nil { t.Logf("Got expected error fetching capabilities with bad creds, error: %s", err) } else { @@ -364,7 +364,7 @@ func SendGnmiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons ctx = context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", successUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", successPassword) - req := &gnmipb.CapabilityRequest{} + req := &gnmi.CapabilityRequest{} payload, err := anypb.New(req) if err != nil { t.Fatal("Failed creating anypb payload.") @@ -422,14 +422,14 @@ func SendGnoiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons var records []*acctzpb.RecordResponse grpcConn := dialGrpc(t, target) - gnoiSystemClient := systempb.NewSystemClient(grpcConn) + gnoiSystemClient := system.NewSystemClient(grpcConn) ctx := context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", failUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", failPassword) // Send an unsuccessful gNOI system time request (bad creds in context), we don't // care about receiving on it, just want to make the request. - gnoiSystemPingClient, err := gnoiSystemClient.Ping(ctx, &systempb.PingRequest{ + gnoiSystemPingClient, err := gnoiSystemClient.Ping(ctx, &system.PingRequest{ Destination: "127.0.0.1", Count: 1, }) @@ -468,7 +468,7 @@ func SendGnoiRPCs(t *testing.T, dut *ondatra.DUTDevice) []*acctzpb.RecordRespons ctx = context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "username", successUsername) ctx = metadata.AppendToOutgoingContext(ctx, "password", successPassword) - req := &systempb.PingRequest{ + req := &system.PingRequest{ Destination: "127.0.0.1", Count: 1, } diff --git a/proto/metadata.proto b/proto/metadata.proto index 3106cf05272..82e022fcec7 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -643,12 +643,9 @@ message Metadata { // Device have different default value for allow own as. // Juniper : b/373559004 bool bgp_allowownas_diff_default_value = 231; - // Cisco numbering for OTN channel assignment starts from 1 instead of 0 - bool otn_channel_assignment_cisco_numbering = 232; - // Cisco pre-fec-ber inactive value for CISCO-ACACIA vendors - bool cisco_pre_fec_ber_inactive_value = 233; // Nokia; b/304493065 comment#7 SRL native admin_enable for table-connections - bool enable_table_connections = 234; + bool enable_table_connections = 232; + // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19, 36, 35, 40, 173; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 08ec21c158b..5fdcccea5fb 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -924,12 +924,8 @@ type Metadata_Deviations struct { // Device have different default value for allow own as. // Juniper : b/373559004 BgpAllowownasDiffDefaultValue bool `protobuf:"varint,231,opt,name=bgp_allowownas_diff_default_value,json=bgpAllowownasDiffDefaultValue,proto3" json:"bgp_allowownas_diff_default_value,omitempty"` - // Cisco numbering for OTN channel assignment starts from 1 instead of 0 - OtnChannelAssignmentCiscoNumbering bool `protobuf:"varint,232,opt,name=otn_channel_assignment_cisco_numbering,json=otnChannelAssignmentCiscoNumbering,proto3" json:"otn_channel_assignment_cisco_numbering,omitempty"` - // Cisco pre-fec-ber inactive value for CISCO-ACACIA vendors - CiscoPreFecBerInactiveValue bool `protobuf:"varint,233,opt,name=cisco_pre_fec_ber_inactive_value,json=ciscoPreFecBerInactiveValue,proto3" json:"cisco_pre_fec_ber_inactive_value,omitempty"` // Nokia; b/304493065 comment#7 SRL native admin_enable for table-connections - EnableTableConnections bool `protobuf:"varint,234,opt,name=enable_table_connections,json=enableTableConnections,proto3" json:"enable_table_connections,omitempty"` + EnableTableConnections bool `protobuf:"varint,232,opt,name=enable_table_connections,json=enableTableConnections,proto3" json:"enable_table_connections,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -2434,20 +2430,6 @@ func (x *Metadata_Deviations) GetBgpAllowownasDiffDefaultValue() bool { return false } -func (x *Metadata_Deviations) GetOtnChannelAssignmentCiscoNumbering() bool { - if x != nil { - return x.OtnChannelAssignmentCiscoNumbering - } - return false -} - -func (x *Metadata_Deviations) GetCiscoPreFecBerInactiveValue() bool { - if x != nil { - return x.CiscoPreFecBerInactiveValue - } - return false -} - func (x *Metadata_Deviations) GetEnableTableConnections() bool { if x != nil { return x.EnableTableConnections @@ -2518,7 +2500,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, 0x92, 0x84, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5, 0x82, 0x01, 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, @@ -2552,7 +2534,7 @@ var file_metadata_proto_rawDesc = []byte{ 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, 0xe5, 0x7b, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xc8, 0x7a, 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, @@ -3524,59 +3506,49 @@ var file_metadata_proto_rawDesc = []byte{ 0x66, 0x66, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xe7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x62, 0x67, 0x70, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x77, 0x6e, 0x61, 0x73, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x53, 0x0a, 0x26, 0x6f, 0x74, 0x6e, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, - 0x5f, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x18, 0xe8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x6f, 0x74, 0x6e, 0x43, 0x68, 0x61, 0x6e, - 0x6e, 0x65, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x69, 0x73, - 0x63, 0x6f, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x46, 0x0a, 0x20, 0x63, - 0x69, 0x73, 0x63, 0x6f, 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x66, 0x65, 0x63, 0x5f, 0x62, 0x65, 0x72, - 0x5f, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0xe9, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x50, 0x72, 0x65, - 0x46, 0x65, 0x63, 0x42, 0x65, 0x72, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0xea, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 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, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x4a, 0x04, 0x08, 0x23, 0x10, 0x24, - 0x4a, 0x04, 0x08, 0x28, 0x10, 0x29, 0x4a, 0x06, 0x08, 0xad, 0x01, 0x10, 0xae, 0x01, 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, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0xe8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 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, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x4a, 0x04, 0x08, + 0x23, 0x10, 0x24, 0x4a, 0x04, 0x08, 0x28, 0x10, 0x29, 0x4a, 0x06, 0x08, 0xad, 0x01, 0x10, 0xae, + 0x01, 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 412f0a93b7d..f3da91c3cfe 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -809,13 +809,6 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_summary/otg_tests/route_summary_counters_test/README.md" exec: " " } -test: { - id: "RT-4.11" - description: " Scale AFTs Route Summary" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_summary/otg_tests/scale_aft_summary/README.md" - exec: " " -} - test: { id: "RT-5.1" description: "Singleton Interface" @@ -1231,8 +1224,7 @@ test: { exec: " " } test: { - id: "TE-9.1" - description: "Push MPLS Labels to MPLS payload" + id: "TE-9.1: Push MPLS Labels to MPLS payload" readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/mpls_compliance/README.md" } test: { @@ -1806,15 +1798,3 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/container/networking/tests/container_connectivity/README.md" exec: " " } -test: { - id: "AFT-1.1" - description: "AFT Streaming" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_base/otg_tests/aft_base/README.md" - exec: " " -} -test: { - id: "AFT-2.1" - description: "AFT Streaming" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/aft/aft_base/otg_tests/aft_prefixcounters/README.md" - exec: " " -} \ No newline at end of file diff --git a/tools/nosimage/validate/validate.go b/tools/nosimage/validate/validate.go index 76115528626..a43203d4e4d 100644 --- a/tools/nosimage/validate/validate.go +++ b/tools/nosimage/validate/validate.go @@ -91,12 +91,7 @@ func main() { if err := os.MkdirAll(config.DownloadPath, 0750); err != nil { fmt.Println(fmt.Errorf("cannot create download path directory: %v", config.DownloadPath)) } - - ocReleaseTag := "" - if profile.Ocpaths.GetVersion() != "" { - ocReleaseTag = "v" + profile.Ocpaths.GetVersion() - } - publicPath, err := ocpaths.ClonePublicRepo(config.DownloadPath, ocReleaseTag) + publicPath, err := ocpaths.ClonePublicRepo(config.DownloadPath, "v"+profile.Ocpaths.GetVersion()) if err != nil { fmt.Println(err) os.Exit(1) From 7c0aed4213534a5a588f19c3a18b941e7dda913a Mon Sep 17 00:00:00 2001 From: snaragund Date: Wed, 4 Dec 2024 17:08:10 +0530 Subject: [PATCH 6/9] -Defined & calling `ConfigEnableTbNative` function from fptest. "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_isis_redistribution_test.go | 50 +------------- internal/fptest/tableconnection.go | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 48 deletions(-) create mode 100644 internal/fptest/tableconnection.go 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 083ce37ff44..b9a95fce876 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 @@ -15,8 +15,6 @@ package bgp_isis_redistribution_test import ( - "context" - "encoding/json" "fmt" "net" "strconv" @@ -30,7 +28,6 @@ import ( "github.com/openconfig/featureprofiles/internal/helpers" "github.com/openconfig/featureprofiles/internal/isissession" "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" @@ -734,8 +731,7 @@ func bgpISISRedistribution(t *testing.T, dut *ondatra.DUTDevice, operation strin dni := deviations.DefaultNetworkInstance(dut) root := &oc.Root{} if deviations.EnableTableConnections(dut) { - state := "enable" - configEnableTbNative(t, dut, state) + fptest.ConfigEnableTbNative(t, dut) } tableConn := root.GetOrCreateNetworkInstance(dni).GetOrCreateTableConnection(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, oc.Types_ADDRESS_FAMILY_IPV4) if operation == "set" { @@ -756,8 +752,7 @@ func bgpISISRedistributionV6(t *testing.T, dut *ondatra.DUTDevice, operation str dni := deviations.DefaultNetworkInstance(dut) root := &oc.Root{} if deviations.EnableTableConnections(dut) { - state := "enable" - configEnableTbNative(t, dut, state) + fptest.ConfigEnableTbNative(t, dut) } tableConn := root.GetOrCreateNetworkInstance(dni).GetOrCreateTableConnection(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, oc.Types_ADDRESS_FAMILY_IPV6) if operation == "set" { @@ -928,44 +923,3 @@ func containsValue[T comparable](slice []T, val T) bool { } return found } - -func configEnableTbNative(t testing.TB, d *ondatra.DUTDevice, state string) { - t.Helper() - switch d.Vendor() { - case ondatra.NOKIA: - //value := state - adminEnable, err := json.Marshal(state) - 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: "table-connections"}, - {Name: "admin-state"}, - }, - }, - Val: &gpb.TypedValue{ - Value: &gpb.TypedValue_JsonIetfVal{ - JsonIetfVal: adminEnable, - }, - }, - }, - }, - } - - gnmiClient := d.RawAPIs().GNMI(t) - if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { - t.Fatalf("Unexpected error updating SRL static-route tag-set: %v", err) - } - default: - t.Fatalf("Unsupported vendor %s for deviation 'EnableTableConnections'", d.Vendor()) - } -} diff --git a/internal/fptest/tableconnection.go b/internal/fptest/tableconnection.go new file mode 100644 index 00000000000..174453dfb3c --- /dev/null +++ b/internal/fptest/tableconnection.go @@ -0,0 +1,65 @@ +// 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 fptest + +import ( + "context" + "encoding/json" + "testing" + + gpb "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/ondatra" +) + +func ConfigEnableTbNative(t testing.TB, d *ondatra.DUTDevice) { + t.Helper() + state := "enable" + switch d.Vendor() { + case ondatra.NOKIA: + adminEnable, err := json.Marshal(state) + 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: "table-connections"}, + {Name: "admin-state"}, + }, + }, + Val: &gpb.TypedValue{ + Value: &gpb.TypedValue_JsonIetfVal{ + JsonIetfVal: adminEnable, + }, + }, + }, + }, + } + + gnmiClient := d.RawAPIs().GNMI(t) + if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { + t.Fatalf("Unexpected error updating SRL static-route tag-set: %v", err) + } + default: + t.Fatalf("Unsupported vendor %s for deviation 'EnableTableConnections'", d.Vendor()) + } +} From 4f3d286e46acde8a73d9e16397bc4ea710457187 Mon Sep 17 00:00:00 2001 From: snaragund Date: Wed, 4 Dec 2024 21:25:17 +0530 Subject: [PATCH 7/9] -updated 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." --- internal/deviations/deviations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 9c04c301319..0f6b0bd0ad2 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -1234,7 +1234,7 @@ func BgpAfiSafiWildcardNotSupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetBgpAfiSafiWildcardNotSupported() } -// Admin Enable Table Connections in SRL native +// EnableTableConnections returns true if admin state of tableconnections needs to be enabled in SRL native model func EnableTableConnections(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetEnableTableConnections() } From 09e873cbb074215f8559d0e8728f8314daf52c2e Mon Sep 17 00:00:00 2001 From: snaragund Date: Thu, 12 Dec 2024 11:02:32 +0530 Subject: [PATCH 8/9] Fixed tableconnection with comment --- internal/fptest/tableconnection.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/fptest/tableconnection.go b/internal/fptest/tableconnection.go index 174453dfb3c..258f48a5acc 100644 --- a/internal/fptest/tableconnection.go +++ b/internal/fptest/tableconnection.go @@ -23,6 +23,7 @@ import ( "github.com/openconfig/ondatra" ) +// ConfigEnableTbNative enables admin-state of table-connections in native mode. func ConfigEnableTbNative(t testing.TB, d *ondatra.DUTDevice) { t.Helper() state := "enable" From cf9a628bc26ed7f63a33866132df4a528417fc4a Mon Sep 17 00:00:00 2001 From: snaragund Date: Wed, 25 Dec 2024 20:09:08 +0530 Subject: [PATCH 9/9] -Removing extra space in deviations.go "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." --- internal/deviations/deviations.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index ff3e15d3ee3..2d34420d438 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -1264,4 +1264,3 @@ func BgpSetMedV7Unsupported(dut *ondatra.DUTDevice) bool { func EnableTableConnections(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetEnableTableConnections() } -