diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 70a8a814170..df375ba3436 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,19 +11,25 @@ * @openconfig/featureprofiles-maintainers # /feature folders each have owners who are auto requested for review and may merge PR's +/feature/acl/ @alokmtri-g +/feature/aft/ @sudhinj /feature/bgp/ @dplore +/feature/dhcp/ @alokmtri-g /feature/ethernet/ @ram-mac /feature/interface/ @ram-mac /feature/isis/ @rohit-rp +/feature/lldp/ @alokmtri-g /feature/mpls/ @swetha-haridasula /feature/mtu/ @swetha-haridasula /feature/networkinstance/ @swetha-haridasula -/feature/policy_forwarding/ @swetha-haridasula +/feature/platform/ @amrindrr /feature/qos @sezhang2 /feature/routing_policy/ @swetha-haridasula +/feature/sampling/ @sudhinj /feature/security @mihirpitale-googler /feature/staticroute/ @swetha-haridasula -/feature/system @self-maurya +/feature/stp/ @alokmtri-g +/feature/system @swetha-haridasula /feature/vrrp @amrindrr # Common OTG utilities diff --git a/.github/workflows/readme_oc_path_and_rpc.yml b/.github/workflows/readme_oc_path_and_rpc.yml index b757f475a66..73e78f5be8d 100644 --- a/.github/workflows/readme_oc_path_and_rpc.yml +++ b/.github/workflows/readme_oc_path_and_rpc.yml @@ -37,7 +37,7 @@ jobs: exemption_flags=( --non-test-readme feature/security/gnsi/certz/test_data/README.md - --non-test-readme feature/experimental/p4rt/README.md + --non-test-readme feature/p4rt/README.md --non-test-readme feature/security/gnsi/acctz/README.md ) diff --git a/.gitignore b/.gitignore index 93acb89f3cb..07ebd5a939c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *~ topologies/kne/testbed.kne.yml .vscode/ +.idea/ # used by `make validate_paths` openconfig_public/ # used by `make proto/...` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5875bebd432..2290141cb5a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,10 +62,6 @@ The directory tree is organized as follows: * `cloudbuild/` contains google cloud build scripts for running virtual routers in containers on [KNE](https://github.com/openconfig/kne) * `feature/` contains definition and tests of feature profiles. -* `feature/experimental` contains tests which have automation which is - not confirmed to pass on any hardware platform or software release. - When the test automation is passing against at least one DUT, - it is moved to the `feature/` directory. * `internal/` contains packages used by feature profile tests. * `proto/` contains protobuf files for feature profiles. * `tools/` contains code used for CI checks. diff --git a/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/README.md b/feature/bgp/ate_tests/bgp_long_lived_graceful_restart/README.md similarity index 100% rename from feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/README.md rename to feature/bgp/ate_tests/bgp_long_lived_graceful_restart/README.md diff --git a/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go b/feature/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go similarity index 100% rename from feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go rename to feature/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go diff --git a/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/metadata.textproto b/feature/bgp/ate_tests/bgp_long_lived_graceful_restart/metadata.textproto similarity index 100% rename from feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/metadata.textproto rename to feature/bgp/ate_tests/bgp_long_lived_graceful_restart/metadata.textproto diff --git a/feature/bgp/bgp_session_mode_configuration_test/README.md b/feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/README.md similarity index 100% rename from feature/bgp/bgp_session_mode_configuration_test/README.md rename to feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/README.md diff --git a/feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/bgp_session_mode_configuration_test.go b/feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/bgp_session_mode_configuration_test.go new file mode 100644 index 00000000000..80fc518aee2 --- /dev/null +++ b/feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/bgp_session_mode_configuration_test.go @@ -0,0 +1,326 @@ +// 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 bgp_session_mode_configuration_test + +import ( + "testing" + "time" + + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +// The testbed consists of ate:port1 -> dut:port1. +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// List of variables. +var ( + dutAttrs = attrs.Attributes{ + Desc: "To ATE", + IPv4: "192.0.2.1", + IPv4Len: 30, + } + ateAttrs = attrs.Attributes{ + Desc: "To DUT", + Name: "ateSrc", + MAC: "02:00:01:01:01:01", + IPv4: "192.0.2.2", + IPv4Len: 30, + } +) + +// Constants. +const ( + dutAS = 65540 + ateAS = 65550 + peerGrpName = "eBGP-PEER-GROUP" + peerLvlPassive = "PeerGrpLevelPassive" + peerLvlActive = "PeerGrpLevelActive" + nbrLvlPassive = "nbrLevelPassive" + nbrLvlActive = "nbrLevelActive" +) + +// configureDUT is used to configure interfaces on the DUT. +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + dc := gnmi.OC() + i1 := dutAttrs.NewOCInterface(dut.Port(t, "port1").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dut.Port(t, "port1")) + } + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, i1.GetName(), deviations.DefaultNetworkInstance(dut), 0) + } +} + +// verifyPortsUp asserts that each port on the device is operating. +func verifyPortsUp(t *testing.T, dev *ondatra.Device) { + t.Helper() + for _, p := range dev.Ports() { + status := gnmi.Get(t, dev, gnmi.OC().Interface(p.Name()).OperStatus().State()) + if want := oc.Interface_OperStatus_UP; status != want { + t.Errorf("%s Status: got %v, want %v", p, status, want) + } + } +} + +// Struct is to pass bgp session parameters. +type bgpTestParams struct { + localAS, peerAS, nbrLocalAS uint32 + peerIP string + transportMode string +} + +// bgpCreateNbr creates a BGP object with neighbors pointing to ate and returns bgp object. +func bgpCreateNbr(bgpParams *bgpTestParams, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { + d := &oc.Root{} + ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + + bgp := niProto.GetOrCreateBgp() + + global := bgp.GetOrCreateGlobal() + global.As = ygot.Uint32(bgpParams.localAS) + global.RouterId = ygot.String(dutAttrs.IPv4) + + // 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. + pg := bgp.GetOrCreatePeerGroup(peerGrpName) + pg.PeerAs = ygot.Uint32(dutAS) + pg.PeerGroupName = ygot.String(peerGrpName) + + nv4 := bgp.GetOrCreateNeighbor(ateAttrs.IPv4) + nv4.PeerGroup = ygot.String(peerGrpName) + nv4.PeerAs = ygot.Uint32(ateAS) + nv4.Enabled = ygot.Bool(true) + + nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + + switch bgpParams.transportMode { + case nbrLvlPassive: + nv4.GetOrCreateTransport().SetPassiveMode(true) + case nbrLvlActive: + nv4.GetOrCreateTransport().SetPassiveMode(false) + case peerLvlPassive: + pg.GetOrCreateTransport().SetPassiveMode(true) + case peerLvlActive: + pg.GetOrCreateTransport().SetPassiveMode(false) + } + + return niProto +} + +// bgpClearConfig removes all BGP configuration from the DUT. +func bgpClearConfig(t *testing.T, dut *ondatra.DUTDevice) { + resetBatch := &gnmi.SetBatch{} + gnmi.BatchDelete(resetBatch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Config()) + + if deviations.NetworkInstanceTableDeletionRequired(dut) { + tablePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).TableAny() + for _, table := range gnmi.LookupAll[*oc.NetworkInstance_Table](t, dut, tablePath.Config()) { + if val, ok := table.Val(); ok { + if val.GetProtocol() == oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP { + gnmi.BatchDelete(resetBatch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Table(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, val.GetAddressFamily()).Config()) + } + } + } + } + resetBatch.Set(t, dut) +} + +// verifyBgpTelemetry checks that the dut has an established BGP session with reasonable settings. +func verifyBgpTelemetry(t *testing.T, dut *ondatra.DUTDevice, wantState oc.E_Bgp_Neighbor_SessionState, transMode string) { + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + nbrPath := statePath.Neighbor(ateAttrs.IPv4) + + // Get BGP adjacency state + t.Log("Checking BGP neighbor to state...") + _, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, present := val.Val() + return present && state == wantState + }).Await(t) + if !ok { + fptest.LogQuery(t, "BGP reported state", nbrPath.State(), gnmi.Get(t, dut, nbrPath.State())) + t.Errorf("BGP Session state is not as expected.") + } + status := gnmi.Get(t, dut, nbrPath.SessionState().State()) + t.Logf("BGP adjacency for %s: %s", ateAttrs.IPv4, status) + if status != wantState { + t.Errorf("BGP peer %s status got %d, want %d", ateAttrs.IPv4, status, wantState) + } + + nbrTransMode := gnmi.Get(t, dut, nbrPath.Transport().State()) + pgTransMode := gnmi.Get(t, dut, statePath.PeerGroup(peerGrpName).Transport().State()) + // Check transport mode telemetry. + switch transMode { + case nbrLvlPassive: + if nbrTransMode.GetPassiveMode() != true { + t.Errorf("Neighbor level passive mode is not set to true on DUT. want true, got %v", nbrTransMode.GetPassiveMode()) + } + t.Logf("Neighbor level passive mode is set to %v on DUT", nbrTransMode.GetPassiveMode()) + case nbrLvlActive: + if nbrTransMode.GetPassiveMode() != false { + t.Errorf("Neighbor level passive mode is not set to false on DUT. want false, got %v", nbrTransMode.GetPassiveMode()) + } + t.Logf("Neighbor level passive mode is set to %v on DUT", nbrTransMode.GetPassiveMode()) + case peerLvlPassive: + if pgTransMode.GetPassiveMode() != true { + t.Errorf("Peer group level passive mode is not set to true on DUT. want true, got %v", pgTransMode.GetPassiveMode()) + } + t.Logf("Peer group level passive mode is set to %v on DUT", pgTransMode.GetPassiveMode()) + case peerLvlActive: + if pgTransMode.GetPassiveMode() != false { + t.Errorf("Peer group level passive mode is not set to false on DUT. want false, got %v", pgTransMode.GetPassiveMode()) + } + t.Logf("Peer group level passive mode is set to %v on DUT", pgTransMode.GetPassiveMode()) + } +} + +// Function to configure ATE configs based on args and returns ate topology handle. +func configureATE(t *testing.T, ateParams *bgpTestParams) gosnappi.Config { + t.Helper() + ate := ondatra.ATE(t, "ate") + port1 := ate.Port(t, "port1") + topo := gosnappi.NewConfig() + + topo.Ports().Add().SetName(port1.ID()) + dev := topo.Devices().Add().SetName(ateAttrs.Name) + eth := dev.Ethernets().Add().SetName(ateAttrs.Name + ".Eth") + eth.Connection().SetPortName(port1.ID()) + eth.SetMac(ateAttrs.MAC) + + ip := eth.Ipv4Addresses().Add().SetName(dev.Name() + ".IPv4") + ip.SetAddress(ateAttrs.IPv4).SetGateway(dutAttrs.IPv4).SetPrefix(uint32(ateAttrs.IPv4Len)) + + bgp := dev.Bgp().SetRouterId(ateAttrs.IPv4) + peerBGP := bgp.Ipv4Interfaces().Add().SetIpv4Name(ip.Name()).Peers().Add() + peerBGP.SetName(ateAttrs.Name + ".BGP4.peer") + peerBGP.SetPeerAddress(ip.Gateway()).SetAsNumber(uint32(ateParams.localAS)) + peerBGP.SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + + switch ateParams.transportMode { + case nbrLvlPassive: + case peerLvlPassive: + peerBGP.Advanced().SetPassiveMode(true) + case peerLvlActive: + case nbrLvlActive: + peerBGP.Advanced().SetPassiveMode(false) + } + + return topo +} + +func verifyOTGBGPTelemetry(t *testing.T, otg *otg.OTG, c gosnappi.Config) { + //nbrPath := gnmi.OTG().BgpPeer("ateSrc.BGP4.peer") + t.Log("OTG telemetry does not support checking transport mode.") +} + +// TestBgpSessionModeConfiguration is to verify when transport mode is set +// active/passive at both neighbor level and peer group level. +func TestBgpSessionModeConfiguration(t *testing.T) { + dutIP := dutAttrs.IPv4 + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + // Configure interface on the DUT + t.Log("Start DUT interface Config") + configureDUT(t, dut) + + // Configure Network instance type on DUT + t.Log("Configure Network Instance") + fptest.ConfigureDefaultNetworkInstance(t, dut) + + // Verify Port Status + t.Log("Verifying port status") + verifyPortsUp(t, dut.Device) + + dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + + cases := []struct { + name string + dutConf *oc.NetworkInstance_Protocol + ateConf gosnappi.Config + wantBGPState oc.E_Bgp_Neighbor_SessionState + dutTransportMode string + otgTransportMode string + }{ + { + name: "Test transport mode passive at neighbor level on both DUT and ATE ", + dutConf: bgpCreateNbr(&bgpTestParams{localAS: dutAS, peerAS: ateAS, transportMode: nbrLvlPassive}, dut), + ateConf: configureATE(t, &bgpTestParams{localAS: ateAS, peerIP: dutIP, transportMode: nbrLvlPassive}), + wantBGPState: oc.Bgp_Neighbor_SessionState_ACTIVE, + dutTransportMode: nbrLvlPassive, + otgTransportMode: nbrLvlPassive, + }, + { + name: "Test transport mode active on ATE and passive on DUT at neighbor level", + dutConf: bgpCreateNbr(&bgpTestParams{localAS: dutAS, peerAS: ateAS, nbrLocalAS: dutAS, transportMode: nbrLvlPassive}, dut), + ateConf: configureATE(t, &bgpTestParams{localAS: ateAS, peerIP: dutIP, transportMode: nbrLvlActive}), + wantBGPState: oc.Bgp_Neighbor_SessionState_ESTABLISHED, + dutTransportMode: nbrLvlPassive, + otgTransportMode: nbrLvlActive, + }, + { + name: "Test transport passive mode at Peer group level on both DUT and ATE.", + dutConf: bgpCreateNbr(&bgpTestParams{localAS: dutAS, peerAS: ateAS, transportMode: peerLvlPassive}, dut), + ateConf: configureATE(t, &bgpTestParams{localAS: ateAS, peerIP: dutIP, transportMode: peerLvlPassive}), + wantBGPState: oc.Bgp_Neighbor_SessionState_ACTIVE, + dutTransportMode: peerLvlPassive, + otgTransportMode: peerLvlPassive, + }, + { + name: "Test transport mode active on ATE and passive on DUT at peer group level", + dutConf: bgpCreateNbr(&bgpTestParams{localAS: dutAS, peerAS: ateAS, nbrLocalAS: dutAS, transportMode: peerLvlPassive}, dut), + ateConf: configureATE(t, &bgpTestParams{localAS: ateAS, peerIP: dutIP, transportMode: peerLvlActive}), + wantBGPState: oc.Bgp_Neighbor_SessionState_ESTABLISHED, + dutTransportMode: peerLvlPassive, + otgTransportMode: peerLvlActive, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + t.Log("Clear BGP configuration") + bgpClearConfig(t, dut) + + t.Log("Configure BGP Configs on DUT") + gnmi.Replace(t, dut, dutConfPath.Config(), tc.dutConf) + fptest.LogQuery(t, "DUT BGP Config ", dutConfPath.Config(), gnmi.Get(t, dut, dutConfPath.Config())) + + t.Log("Configure BGP on ATE") + ate.OTG().PushConfig(t, tc.ateConf) + ate.OTG().StartProtocols(t) + + t.Logf("Verify BGP telemetry") + verifyBgpTelemetry(t, dut, tc.wantBGPState, tc.dutTransportMode) + + t.Logf("Verify BGP telemetry on otg") + verifyOTGBGPTelemetry(t, ate.OTG(), tc.ateConf) + + t.Log("Clear BGP Configs on ATE") + ate.OTG().StopProtocols(t) + }) + } +} diff --git a/feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/metadata.textproto b/feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/metadata.textproto new file mode 100644 index 00000000000..2b5a539450e --- /dev/null +++ b/feature/bgp/bgp_session_mode/otg_tests/bgp_session_mode_configuration_test/metadata.textproto @@ -0,0 +1,41 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "7e2082f6-4fbc-4e2b-a8a8-c83af2574ec4" +plan_id: "RT-1.55" +description: "BGP session mode (active/passive)" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + ipv4_missing_enabled: true + connect_retry: true + } +} +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_port_speed: true + explicit_interface_in_default_vrf: true + missing_value_for_defaults: true + interface_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + connect_retry: true + omit_l2_mtu: true + network_instance_table_deletion_required: true + bgp_md5_requires_reset: true + missing_value_for_defaults: true + interface_enabled: true + default_network_instance: "default" + } +} diff --git a/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go b/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go index 2354ccc83ac..f22f1b4ed3c 100644 --- a/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go +++ b/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/bgp_multipath_ecmp_test.go @@ -15,13 +15,12 @@ package bgp_multipath_ecmp_test import ( + "math/rand" "sort" "strconv" "testing" "time" - "math/rand" - "github.com/open-traffic-generator/snappi/gosnappi" "github.com/openconfig/featureprofiles/internal/cfgplugins" "github.com/openconfig/featureprofiles/internal/deviations" @@ -39,8 +38,8 @@ const ( prefixesCount = 4 pathID = 1 maxPaths = 2 - trafficPps = 100000 - totalPackets = 12000000 + trafficPps = 1000 + totalPackets = 120000 lossTolerancePct = 0 lbToleranceFms = 20 ) @@ -54,7 +53,7 @@ func configureOTG(t *testing.T, bs *cfgplugins.BGPSession) { byName := func(i, j int) bool { return devices[i].Name() < devices[j].Name() } sort.Slice(devices, byName) for i, otgPort := range bs.ATEPorts { - if i == 0 { + if i < 2 { continue } @@ -92,7 +91,7 @@ func configureFlow(t *testing.T, bs *cfgplugins.BGPSession) { bs.ATETop.Flows().Clear() var rxNames []string - for i := 1; i < len(bs.ATEPorts); i++ { + for i := 2; i < len(bs.ATEPorts); i++ { rxNames = append(rxNames, bs.ATEPorts[i].Name+".BGP4.peer.rr4") } flow := bs.ATETop.Flows().Add().SetName("flow") @@ -125,7 +124,7 @@ func verifyECMPLoadBalance(t *testing.T, ate *ondatra.ATEDevice, pc int, expecte max := expectedPerLinkFms + (expectedPerLinkFms * lbToleranceFms / 100) got := 0 - for i := 2; i <= pc; i++ { + for i := 3; i <= pc; i++ { framesRx := gnmi.Get(t, ate.OTG(), gnmi.OTG().Port(ate.Port(t, "port"+strconv.Itoa(i)).ID()).Counters().InFrames().State()) if framesRx <= lbToleranceFms { t.Logf("Skip: Traffic through port%d interface is %d", i, framesRx) @@ -193,7 +192,7 @@ func TestBGPSetup(t *testing.T) { for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount4, nil) - bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST}, []string{"port2", "port3", "port4"}, true, !tc.enableMultiAS) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST}, []string{"port3", "port4"}, true, !tc.enableMultiAS) dni := deviations.DefaultNetworkInstance(bs.DUT) bgp := bs.DUTConf.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() gEBGP := bgp.GetOrCreateGlobal().GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().GetOrCreateEbgp() @@ -202,7 +201,7 @@ func TestBGPSetup(t *testing.T) { t.Logf("Enable Multipath") pgUseMulitplePaths.Enabled = ygot.Bool(true) t.Logf("Enable Maximum Paths") - gEBGP.MaximumPaths = ygot.Uint32(maxPaths) + bgp.GetOrCreateGlobal().GetOrCreateUseMultiplePaths().GetOrCreateEbgp().MaximumPaths = ygot.Uint32(maxPaths) } if tc.enableMultiAS && !deviations.SkipSettingAllowMultipleAS(bs.DUT) && deviations.SkipAfiSafiPathForBgpMultipleAs(bs.DUT) { t.Logf("Enable MultiAS ") diff --git a/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/metadata.textproto b/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/metadata.textproto index 7c594707925..905c4d35d27 100644 --- a/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/metadata.textproto +++ b/feature/bgp/multipath/otg_tests/bgp_multipath_ecmp_test/metadata.textproto @@ -11,6 +11,7 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true + skip_setting_allow_multiple_as: true skip_afi_safi_path_for_bgp_multiple_as: true } } @@ -20,6 +21,7 @@ platform_exceptions: { } deviations: { bgp_max_multipath_paths_unsupported: true + multipath_unsupported_neighbor_or_afisafi: true } } platform_exceptions: { @@ -42,8 +44,7 @@ platform_exceptions: { interface_enabled: true default_network_instance: "default" missing_value_for_defaults: true - skip_setting_allow_multiple_as: false + skip_setting_allow_multiple_as: true } } -tags: TAGS_DATACENTER_EDGE - +tags: TAGS_DATACENTER_EDGE \ No newline at end of file diff --git a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/README.md b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/README.md index fb8c4ec0341..caf12697c34 100644 --- a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/README.md +++ b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/README.md @@ -19,43 +19,90 @@ Validate BGP in multipath UCMP support with link bandwidth community * ATE port-2 and DUT port-2 * ATE port-3 and DUT port-3 * Enable an Accept-route all import-policy/export-policy for eBGP session - under the neighbor AFI/SAFI -* Create an IPv4 internal target network attached to ATE port 2 and 3 + under the neighbor AFI/SAFI - IPv6 unicast and IPv4 unicast. +* Create an single IPv4 internal target network attached to ATE port 2 and 3 +* Create an single IPv6 internal target network attached to ATE port 2 and 3 + ### Tests -* RT-1.52.1: Verify use of community type - - * Configure ATE port 1, 2 and 3 on different AS - * Enable multipath, set maximum-paths limit to 2, enable allow multiple - AS, and send community type to BOTH (STANDARD and EXTENDED) - * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/config/enabled - * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/ebgp/config/allow-multiple-as - * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/ebgp/config/maximum-paths - * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/send-community-type - * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/use-multiple-paths/ebgp/link-bandwidth-ext-community/config/enabled - * Advertise equal cost paths from port2 and port3 of ATE - * Check entries in FIB for advertised prefix, it should have 2 entries - * /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops - * Initiate traffic from ATE port-1 to the DUT and destined to internal - target network - * Check entire traffic should only be unequally forwarded between DUT - port2 and port3 - -## Config Parameter Coverage - -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/config/enabled -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/ebgp/config/allow-multiple-as -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/ebgp/config/maximum-paths -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/send-community-type -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/use-multiple-paths/ebgp/link-bandwidth-ext-community/config/enabled - -## Telemetry Parameter Coverage - -* /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state -* /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group -* /network-instances/network-instance/afts/next-hop-groups/next-hop-group[id=]/state -* /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops +* RT-1.52.1: Verify use of unequal community type + + * Test Configuration + * Configure ATE port 1, 2 and 3 on different AS, with boths AFI/SAFI + * Advertise IPv4 and IPv6 internal target, both, form both ATE port-1 and ATE port-2 in eBGP. + * For ATE port 2 attach `link-bandwidth:23456:10K` extended-community + * For ATE port 3 attach `link-bandwidth:23456:5K` extended-community + * Enable multipath, set maximum-paths limit to 2, enable allow multiple + AS, and send community type to [STANDARD, EXTENDED, LARGE] + * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/config/enabled + * /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/use-multiple-paths/ebgp/config/allow-multiple-as + * /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/use-multiple-paths/ebgp/config/maximum-paths + * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/send-community-type + * /network-instances/network-instance/protocols/protocol/bgp/global/use-multiple-paths/ebgp/link-bandwidth-ext-community/config/enabled + * Advertise equal cost paths from port2 and port3 of ATE + * Initiate traffic from ATE port-1 to the DUT and destined to internal + target network. + * Use UDP traffic with src and dst port randomly selected from 1-65535 range for each packet. Or equivalent pattern guaranteeng high entropy of traffic. + * Behaviour Validation + * Check entries in AFT for advertised prefix, it should have 2 entries.\ + The `weight` leafs of next-hops shall be in 2:1 ratio. + * Find next-hop-group IDs for both internal target networks: + * /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry[prefix=IPv4 internal target network]/state/**next-hop-group** + * /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry[prefix=IPv6 internal target network]/state/**next-hop-group** + * using next-hop-group as key find number and weight of next-hops of both internal target network + * /network-instances/network-instance/afts/next-hop-groups/next-hop-group[id=next-hop-group ID]/next-hops/next-hop/state/index + * /network-instances/network-instance/afts/next-hop-groups/next-hop-group[id=next-hop-group ID]/next-hops/next-hop/state/**weight** + * Check entire traffic should be unequally forwarded between DUT + port2 and port3 only + * 66% via port2 + * 33% via port3 + * with +/-5% tolerance + +* RT-1.52.2: Verify use of equal community type + + * Test Configuration + Use test configuration as in RT-1.52.1 above with following modifications: + * Advertise IPv4 and IPv6 internal target, both, form both ATE port-1 and ATE port-2 in eBGP. + * For ATE port 2 attach `link-bandwidth:23456:10K` extended-community + * For ATE port 3 attach `link-bandwidth:23456:10K` extended-community + * Behaviour Validation + * Check entries in AFT for advertised prefix, it should have 2 entries.\ + The `weight` leafs of next-hops shall be in 1:1 ratio. + * Find next-hop-group IDs for both internal target networks: + * /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry[prefix=IPv4 internal target network]/state/**next-hop-group** + * /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry[prefix=IPv6 internal target network]/state/**next-hop-group** + * using next-hop-group as key find number and weight of next-hops of both internal target network + * /network-instances/network-instance/afts/next-hop-groups/next-hop-group[id=next-hop-group ID]/next-hops/next-hop/state/index + * /network-instances/network-instance/afts/next-hop-groups/next-hop-group[id=next-hop-group ID]/next-hops/next-hop/state/**weight** + * Check entire traffic should be unequally forwarded between DUT + port2 and port3 only + * 50% via port2 + * 50% via port3 + * with +/-5% tolerance + +* RT-1.52.3: Verify BGP multipath when some path missing link-bandwidth extended-community + + * Test Configuration + Use test configuration as in RT-1.52.1 above with following modifications: + * Configure ATE port 1, 2 and 3 on different AS, with boths AFI/SAFI + * Advertise IPv4 and IPv6 internal target, both, form both ATE port-1 and ATE port-2 in eBGP. + * For ATE port 2 attach `link-bandwidth:23456:10K` extended-community + * For ATE port 3 **DO NOT** attach any link-bandwidth extended-community + * Behaviour Validation + * Check entries in AFT for advertised prefix, it should have 2 entries.\ + The `weight` leafs of next-hops shall be in 1:1 ratio. + * Find next-hop-group IDs for both internal target networks: + * /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry[prefix=IPv4 internal target network]/state/**next-hop-group** + * /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry[prefix=IPv6 internal target network]/state/**next-hop-group** + * using next-hop-group as key find number and weight of next-hops of both internal target network + * /network-instances/network-instance/afts/next-hop-groups/next-hop-group[id=next-hop-group ID]/next-hops/next-hop/state/index + * /network-instances/network-instance/afts/next-hop-groups/next-hop-group[id=next-hop-group ID]/next-hops/next-hop/state/**weight** + * Check entire traffic should be unequally forwarded between DUT + port2 and port3 only + * 50% via port2 + * 50% via port3 + * with +/-5% tolerance ## OpenConfig Path and RPC Coverage @@ -64,6 +111,18 @@ rpcs: gnmi: gNMI.Get: gNMI.Subscribe: +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/use-multiple-paths/config/enabled: + /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/use-multiple-paths/ebgp/config/allow-multiple-as: + /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/use-multiple-paths/ebgp/config/maximum-paths: + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/send-community-type: + /network-instances/network-instance/protocols/protocol/bgp/global/use-multiple-paths/ebgp/link-bandwidth-ext-community/config/enabled: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight: + ``` ## Required DUT platform diff --git a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go index 3ab2c1cc4fd..5f452a05e61 100644 --- a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go +++ b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/bgp_multipath_wecmp_test.go @@ -42,10 +42,10 @@ const ( trafficPps = 1000 totalPackets = 120000 lossTolerancePct = 0 - lbToleranceFms = 5 + lbToleranceFms = 10 ) -var linkBw = []int{10, 5} +var linkBw = []int{10} func TestMain(m *testing.M) { fptest.RunTests(m) @@ -71,13 +71,32 @@ func configureOTG(t *testing.T, bs *cfgplugins.BGPSession) { routeAddress.SetPrefix(prefixP4Len) routeAddress.SetCount(prefixesCount) bgp4PeerRoute.AddPath().SetPathId(pathID) - bgpExtCom := bgp4PeerRoute.ExtendedCommunities().Add() - bgpExtCom.NonTransitive2OctetAsType().LinkBandwidthSubtype().SetBandwidth(float32(linkBw[i-2] * 1000)) } configureFlow(bs) } +func attachLBWithInternalNetwork(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) { + devices := top.Devices().Items() + byName := func(i, j int) bool { return devices[i].Name() < devices[j].Name() } + sort.Slice(devices, byName) + + for _, i := range []int{2, 3} { + bgp4Peer := devices[i].Bgp().Ipv4Interfaces().Items()[0].Peers().Items()[0] + bgp4PeerRoute := bgp4Peer.V4Routes().Items()[0] + bgp4PeerRoute.ExtendedCommunities().Clear() + if i-2 < len(linkBw) { + bgpExtCom := bgp4PeerRoute.ExtendedCommunities().Add() + bgpExtCom.NonTransitive2OctetAsType().LinkBandwidthSubtype().SetBandwidth(float32(linkBw[i-2] * 1000)) + bgpExtCom.NonTransitive2OctetAsType().LinkBandwidthSubtype().SetGlobal2ByteAs(23456) + } + } + + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, ate.OTG(), top, "IPv4") +} + func configureFlow(bs *cfgplugins.BGPSession) { bs.ATETop.Flows().Clear() @@ -118,8 +137,15 @@ func checkPacketLoss(t *testing.T, ate *ondatra.ATEDevice) { func verifyECMPLoadBalance(t *testing.T, ate *ondatra.ATEDevice, pc int, expectedLinks int) { framesTx := gnmi.Get(t, ate.OTG(), gnmi.OTG().Port(ate.Port(t, "port1").ID()).Counters().OutFrames().State()) - expectedPerLinkFmsP3 := int(float32(linkBw[0]) / (float32(linkBw[0] + linkBw[1])) * float32(framesTx)) - expectedPerLinkFmsP4 := int(float32(linkBw[1]) / (float32(linkBw[0] + linkBw[1])) * float32(framesTx)) + var lb1, lb2 float32 + if len(linkBw) == 1 { + lb1, lb2 = float32(linkBw[0]), float32(linkBw[0]) + } else { + lb1, lb2 = float32(linkBw[0]), float32(linkBw[1]) + } + + expectedPerLinkFmsP3 := int(lb1 / (lb1 + lb2) * float32(framesTx)) + expectedPerLinkFmsP4 := int(lb2 / (lb1 + lb2) * float32(framesTx)) t.Logf("Total packets %d flow through the %d links and expected per link packets: %d, %d", framesTx, expectedLinks, expectedPerLinkFmsP3, expectedPerLinkFmsP4) p3Min := expectedPerLinkFmsP3 - (expectedPerLinkFmsP3 * lbToleranceFms / 100) @@ -146,13 +172,21 @@ func verifyECMPLoadBalance(t *testing.T, ate *ondatra.ATEDevice, pc int, expecte func TestBGPSetup(t *testing.T) { bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount4, nil) bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST}, []string{"port3", "port4"}, true, false) + dni := deviations.DefaultNetworkInstance(bs.DUT) bgp := bs.DUTConf.GetOrCreateNetworkInstance(dni).GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").GetOrCreateBgp() + bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().Enabled = ygot.Bool(true) + + if !deviations.SkipBgpSendCommunityType(bs.DUT) { + bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).SetSendCommunityType([]oc.E_Bgp_CommunityType{oc.Bgp_CommunityType_STANDARD, oc.Bgp_CommunityType_EXTENDED, oc.Bgp_CommunityType_LARGE}) + } + if deviations.MultipathUnsupportedNeighborOrAfisafi(bs.DUT) { t.Logf("MultipathUnsupportedNeighborOrAfisafi is supported") bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateUseMultiplePaths().Enabled = ygot.Bool(true) bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateUseMultiplePaths().GetOrCreateEbgp().AllowMultipleAs = ygot.Bool(true) } + if deviations.SkipAfiSafiPathForBgpMultipleAs(bs.DUT) { var communitySetCLIConfig string t.Log("AfiSafi Path For BgpMultipleAs is not supported") @@ -170,13 +204,19 @@ func TestBGPSetup(t *testing.T) { helpers.GnmiCLIConfig(t, bs.DUT, communitySetCLIConfig) } } else { - t.Logf("AfiSafi Path For BgpMultipleAs is supported") - gEBGP := bgp.GetOrCreateGlobal().GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().GetOrCreateEbgp() - if !deviations.SkipSettingAllowMultipleAS(bs.DUT) { - gEBGP.AllowMultipleAs = ygot.Bool(true) + if deviations.SkipSettingAllowMultipleAS(bs.DUT) { + bgp.GetOrCreateGlobal().GetOrCreateUseMultiplePaths().GetOrCreateEbgp().MaximumPaths = ygot.Uint32(maxPaths) + bgp.GetOrCreateGlobal().GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().GetOrCreateEbgp().GetOrCreateLinkBandwidthExtCommunity().Enabled = ygot.Bool(true) + switch bs.DUT.Vendor() { + case ondatra.ARISTA: + helpers.GnmiCLIConfig(t, bs.DUT, "router bgp 65501\n ucmp mode 1\n") + default: + t.Fatalf("Unsupported vendor %s for deviation 'SkipSettingAllowMultipleAS'", bs.DUT.Vendor()) + } + } else { + bgp.GetOrCreateGlobal().GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().GetOrCreateEbgp().AllowMultipleAs = ygot.Bool(true) } } - bgp.GetOrCreatePeerGroup(cfgplugins.BGPPeerGroup1).GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateUseMultiplePaths().Enabled = ygot.Bool(true) configureOTG(t, bs) bs.PushAndStart(t) @@ -187,22 +227,55 @@ func TestBGPSetup(t *testing.T) { t.Logf("Verify OTG BGP sessions up") cfgplugins.VerifyOTGBGPEstablished(t, bs.ATE) + testCases := []struct { + name string + desc string + linkBw []int + }{ + { + name: "RT-1.52.1", + desc: "Verify BGP multipath when some path missing link-bandwidth extended-community", + linkBw: []int{10}, + }, + { + name: "RT-1.52.2", + desc: "Verify use of equal community type", + linkBw: []int{10, 10}, + }, + { + name: "RT-1.52.1", + desc: "Verify use of unequal community type", + linkBw: []int{10, 5}, + }, + } + aftsPath := gnmi.OC().NetworkInstance(dni).Afts() prefix := prefixesStart + "/" + strconv.Itoa(prefixP4Len) - ipv4Entry := gnmi.Get[*oc.NetworkInstance_Afts_Ipv4Entry](t, bs.DUT, aftsPath.Ipv4Entry(prefix).State()) - hopGroup := gnmi.Get[*oc.NetworkInstance_Afts_NextHopGroup](t, bs.DUT, aftsPath.NextHopGroup(ipv4Entry.GetNextHopGroup()).State()) - if got, want := len(hopGroup.NextHop), 2; got != want { - t.Errorf("prefix: %s, found %d hops, want %d", ipv4Entry.GetPrefix(), got, want) - } else { - t.Logf("prefix: %s, found %d hops, want %d", ipv4Entry.GetPrefix(), got, want) - } - sleepTime := time.Duration(totalPackets/trafficPps) + 5 - bs.ATE.OTG().StartTraffic(t) - time.Sleep(sleepTime * time.Second) - bs.ATE.OTG().StopTraffic(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + linkBw = tc.linkBw + attachLBWithInternalNetwork(t, bs.ATE, bs.ATETop) + time.Sleep(30 * time.Second) - otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) - checkPacketLoss(t, bs.ATE) - verifyECMPLoadBalance(t, bs.ATE, int(cfgplugins.PortCount4), 2) + ipv4Entry := gnmi.Get[*oc.NetworkInstance_Afts_Ipv4Entry](t, bs.DUT, aftsPath.Ipv4Entry(prefix).State()) + hopGroup := gnmi.Get[*oc.NetworkInstance_Afts_NextHopGroup](t, bs.DUT, aftsPath.NextHopGroup(ipv4Entry.GetNextHopGroup()).State()) + if got, want := len(hopGroup.NextHop), 2; got != want { + t.Errorf("prefix: %s, found %d hops, want %d", ipv4Entry.GetPrefix(), got, want) + } else { + for i, nh := range hopGroup.NextHop { + t.Logf("Prefix %s, NextHop(%d) weight: %d", ipv4Entry.GetPrefix(), i, nh.GetWeight()) + } + } + + sleepTime := time.Duration(totalPackets/trafficPps) + 5 + bs.ATE.OTG().StartTraffic(t) + time.Sleep(sleepTime * time.Second) + bs.ATE.OTG().StopTraffic(t) + + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + checkPacketLoss(t, bs.ATE) + verifyECMPLoadBalance(t, bs.ATE, int(cfgplugins.PortCount4), 2) + }) + } } diff --git a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/metadata.textproto b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/metadata.textproto index cba5b2008ac..820d96d3595 100644 --- a/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/metadata.textproto +++ b/feature/bgp/multipath/otg_tests/bgp_multipath_wecmp_lbw_community_test/metadata.textproto @@ -13,6 +13,7 @@ platform_exceptions: { ipv4_missing_enabled: true skip_setting_allow_multiple_as: true skip_afi_safi_path_for_bgp_multiple_as: true + skip_bgp_send_community_type: true } } platform_exceptions: { @@ -43,7 +44,7 @@ platform_exceptions: { interface_enabled: true default_network_instance: "default" missing_value_for_defaults: true - skip_setting_allow_multiple_as: false + skip_setting_allow_multiple_as: true } } tags: TAGS_DATACENTER_EDGE diff --git a/feature/experimental/bgp/otg_tests/base_bgp_session_parameters/README.md b/feature/bgp/otg_tests/base_bgp_session_parameters/README.md similarity index 61% rename from feature/experimental/bgp/otg_tests/base_bgp_session_parameters/README.md rename to feature/bgp/otg_tests/base_bgp_session_parameters/README.md index dc3416dbd47..8bdeb896e1a 100644 --- a/feature/experimental/bgp/otg_tests/base_bgp_session_parameters/README.md +++ b/feature/bgp/otg_tests/base_bgp_session_parameters/README.md @@ -48,48 +48,21 @@ Test the normal session establishment and termination: * Explicit holdtime interval and keepalive interval. * Explicit connect retry interval. -## Config Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/bgp/global - -* For Parameters: - - * config/as - * config/router-id - * config/peer-as - * config/local-as - * config/description - * timers/config/hold-time - * timers/config/keepalive-interval - * timers/config/minimum-route-advertisement-interval - -* For prefixes: - - * /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor - -## Telemetry Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/bgp/ - -* For Parameters: - - * state/last-established - * state/messages/received/NOTIFICATION - * state/negotiated-hold-time - * state/supported-capabilities - -## Protocol/RPC Parameter coverage - -* BGP - - * OPEN - - * Version - * My Autonomous System - * BGP Identifier - * Hold Time +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/timers/config/hold-time: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/timers/config/keepalive-interval: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/last-established: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/messages/received/NOTIFICATION: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/timers/state/negotiated-hold-time: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/supported-capabilities: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` diff --git a/feature/experimental/bgp/otg_tests/base_bgp_session_parameters/base_bgp_session_parameters_test.go b/feature/bgp/otg_tests/base_bgp_session_parameters/base_bgp_session_parameters_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/base_bgp_session_parameters/base_bgp_session_parameters_test.go rename to feature/bgp/otg_tests/base_bgp_session_parameters/base_bgp_session_parameters_test.go diff --git a/feature/experimental/bgp/otg_tests/base_bgp_session_parameters/metadata.textproto b/feature/bgp/otg_tests/base_bgp_session_parameters/metadata.textproto similarity index 100% rename from feature/experimental/bgp/otg_tests/base_bgp_session_parameters/metadata.textproto rename to feature/bgp/otg_tests/base_bgp_session_parameters/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn/README.md b/feature/bgp/otg_tests/bgp_2byte_4byte_asn/README.md similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn/README.md rename to feature/bgp/otg_tests/bgp_2byte_4byte_asn/README.md diff --git a/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go b/feature/bgp/otg_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go rename to feature/bgp/otg_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go diff --git a/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn/metadata.textproto b/feature/bgp/otg_tests/bgp_2byte_4byte_asn/metadata.textproto similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn/metadata.textproto rename to feature/bgp/otg_tests/bgp_2byte_4byte_asn/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/README.md b/feature/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/README.md similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/README.md rename to feature/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/README.md diff --git a/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go b/feature/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go rename to feature/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go diff --git a/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto b/feature/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto rename to feature/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/README.md b/feature/bgp/otg_tests/bgp_afi_safi_defaults/README.md similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/README.md rename to feature/bgp/otg_tests/bgp_afi_safi_defaults/README.md diff --git a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go b/feature/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go rename to feature/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go diff --git a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto b/feature/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto rename to feature/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_always_compare_med/README.md b/feature/bgp/otg_tests/bgp_always_compare_med/README.md similarity index 57% rename from feature/experimental/bgp/otg_tests/bgp_always_compare_med/README.md rename to feature/bgp/otg_tests/bgp_always_compare_med/README.md index 91fdcdad95e..d239bc302e9 100644 --- a/feature/experimental/bgp/otg_tests/bgp_always_compare_med/README.md +++ b/feature/bgp/otg_tests/bgp_always_compare_med/README.md @@ -18,20 +18,22 @@ BGP always compare MED * Validate the change of traffic flow because of the change (OTG Port2). * Validate session state and capabilities received on DUT using telemetry. -## Config Parameter coverage - -* /route-selection-options/config/always-compare-med -* /global/afi-safis/afi-safi/route-selection-options/config/always-compare-med -* /global/route-selection-options/config/always-compare-med - -## Telemetry Parameter coverage - -* /global/afi-safis/afi-safi/route-selection-options/state/always-compare-med -* /global/route-selection-options/state/always-compare-med - -## Protocol/RPC Parameter coverage - -N/A +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/global/route-selection-options/config/always-compare-med: + /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/route-selection-options/config/always-compare-med: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/global/route-selection-options/state/always-compare-med: + /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/route-selection-options/state/always-compare-med: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go b/feature/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go rename to feature/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go diff --git a/feature/experimental/bgp/otg_tests/bgp_always_compare_med/metadata.textproto b/feature/bgp/otg_tests/bgp_always_compare_med/metadata.textproto similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_always_compare_med/metadata.textproto rename to feature/bgp/otg_tests/bgp_always_compare_med/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_override_as_path_split_horizon_test/README.md b/feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/README.md similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_override_as_path_split_horizon_test/README.md rename to feature/bgp/otg_tests/bgp_override_as_path_split_horizon_test/README.md diff --git a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/README.md b/feature/bgp/otg_tests/bgp_remove_private_as/README.md similarity index 60% rename from feature/experimental/bgp/otg_tests/bgp_remove_private_as/README.md rename to feature/bgp/otg_tests/bgp_remove_private_as/README.md index 6a5ce3e8a52..7da3a2fc346 100644 --- a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/README.md +++ b/feature/bgp/otg_tests/bgp_remove_private_as/README.md @@ -18,17 +18,20 @@ BGP remove private AS * PRIV_AS1 AS1 * AS1 PRIV_AS1 AS2 -## Config Parameter coverage - -* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/remove-private-as - -## Telemetry Parameter coverage - -* /network-instances/network-instance/protocols/protocol/bgp/rib/attr-sets/attr-set/as4-path/as4-segment/state - -## Protocol/RPC Parameter coverage - -N/A +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/remove-private-as: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/rib/attr-sets/attr-set/as4-path/as4-segment/state/index: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go b/feature/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go rename to feature/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go diff --git a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/metadata.textproto b/feature/bgp/otg_tests/bgp_remove_private_as/metadata.textproto similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_remove_private_as/metadata.textproto rename to feature/bgp/otg_tests/bgp_remove_private_as/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_tcp_mss_path_mtu/README.md b/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/README.md similarity index 67% rename from feature/experimental/bgp/otg_tests/bgp_tcp_mss_path_mtu/README.md rename to feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/README.md index 45457c0b801..8c21d568b0e 100644 --- a/feature/experimental/bgp/otg_tests/bgp_tcp_mss_path_mtu/README.md +++ b/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/README.md @@ -25,19 +25,22 @@ * Re-establish the IBGP sessions by tcp reset. * Validate that the min MSS value has been adjusted to be below 1500 bytes on the tcp session. -## Config Parameter coverage - -* /neighbors/neighbor/transport/config/tcp-mss -* /neighbors/neighbor/transport/config/mtu-discovery - -## Telemetry Parameter coverage - -* /neighbors/neighbor/transport/state/tcp-mss -* /neighbors/neighbor/transport/state/mtu-discovery - -## Protocol/RPC Parameter coverage - -N/A +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/transport/config/tcp-mss: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/transport/config/mtu-discovery: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/transport/state/tcp-mss: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/transport/state/mtu-discovery: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go b/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go rename to feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go diff --git a/feature/experimental/bgp/otg_tests/bgp_tcp_mss_path_mtu/metadata.textproto b/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/metadata.textproto similarity index 100% rename from feature/experimental/bgp/otg_tests/bgp_tcp_mss_path_mtu/metadata.textproto rename to feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/link_bandwidth_test/README.md b/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md similarity index 75% rename from feature/experimental/bgp/otg_tests/link_bandwidth_test/README.md rename to feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md index 4fa01af7fec..c725c5e4c7d 100644 --- a/feature/experimental/bgp/otg_tests/link_bandwidth_test/README.md +++ b/feature/bgp/policybase/otg_tests/link_bandwidth_test/README.md @@ -26,9 +26,9 @@ bandwidth communities to routes based on a prefix match. * Advertise ipv4 and ipv6 prefixes to DUT port 1 using the following communities: * prefix-set-1 with 2 ipv4 and 2 ipv6 routes without communities. * prefix-set-2 with 2 ipv4 and 2 ipv6 routes with communities `[ "100:100" ]`. - * prefix-set-3 with 2 ipv4 and 2 ipv6 routes with extended communities `[ "link-bandwidth:23456:0" ]`. + * [TODO value change] prefix-set-3 with 2 ipv4 and 2 ipv6 routes with extended communities `[ "link-bandwidth:23456:1000" ]`. * Configure Send community knob to IBGP neigbour to advertise the communities to IBGP peer - * use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/send-community`. + * [TODO] use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/send-community-type` leaf-list with value `[STANDARD EXTENDED]`. * RT-7.5.1 - Validate bgp sessions and traffic * For IPv4 and IPv6 prefixes: * Observe received prefixes at ATE port-2. @@ -48,18 +48,6 @@ bandwidth communities to routes based on a prefix match. * Create an ext-community-set named 'linkbw_any' with members as follows: * ext-community-member = [ "^link-bandwidth:.*:.*$" ] - - * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` named **'not_match_100_set_linkbw_1M'** with the following `statements` * statement[name='1-megabit-match']/ @@ -71,7 +59,7 @@ bandwidth communities to routes based on a prefix match. * actions/config/policy-result = ACCEPT_ROUTE * Create a `/routing-policy/policy-definitions/policy-definition/policy-definition` - named 'match_100_set_linkbw_2G' with the following `statements` + named **'match_100_set_linkbw_2G'** with the following `statements` * statement[name='2-gigabit-match']/ * conditions/bgp-conditions/match-community-set/config/community-set = 'regex_match_comm100' * conditions/bgp-conditions/match-community-set/config/match-set-options = ANY @@ -90,21 +78,7 @@ bandwidth communities to routes based on a prefix match. * statement[name='accept_all_routes']/ * actions/config/policy-result = ACCEPT_ROUTE - - - * For each policy-definition created, run a subtest (RT-7.8.3.x-) to + * For each policy-definition created, run a subtest (RT-7.5.3.x--import) to * Use gnmi Set REPLACE option for: * `/routing-policy/policy-definitions` to configure the policy * Use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/import-policy` @@ -119,32 +93,49 @@ bandwidth communities to routes based on a prefix match. * Expected community values for each policy | | set_linkbw_0 | not_match_100_set_linkbw_1M | | ------------ | -------------------------------------- | --------------------------- | - | prefix-set-1 | *DEPRECATED* | [none] | + | prefix-set-1 | *DEPRECATED* | [ "link-bandwidth:23456:1000000" ] | | prefix-set-2 | *DEPRECATED* | [ "100:100" ] | - | prefix-set-3 | *DEPRECATED* | [ "link-bandwidth:23456:0" ] | + | prefix-set-3 | *DEPRECATED* | [ "link-bandwidth:23456:1000000" ] | | | match_100_set_linkbw_2G | del_linkbw | rm_any_zero_bw_set_LocPref_5 | | ------------ | ------------------------------------------------- | ------------- | ---------------------------- | | prefix-set-1 | [ none ] | [none] | *DEPRECATED* | | prefix-set-2 | [ "100:100", "link-bandwidth:23456:2000000000" ] | [ "100:100" ] | *DEPRECATED* | - | prefix-set-3 | [ "link-bandwidth:23456:0" ] | [ none ] | *DEPRECATED* | + | prefix-set-3 | [ "link-bandwidth:23456:1000" ] | [ none ] | *DEPRECATED* | * Regarding prefix-set-3 and policy "nomatch_100_set_linkbw_2G" * prefix-set-3 is advertised to the DUT with community "link-bandwidth:100:0" set. * The DUT evaluates a match for "regex_nomatch_as100". This does not match because the regex pattern does not include the link-bandwidth community type. * Community linkbw_2G should be added. - - + +[TODO] For each policy-definition created, run a subtest (RT-7.5.4.x--export) to + + * Use gnmi Set REPLACE option to attach `allow_all` policy using `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy` to apply the policy on the DUT bgp neighbor to the ATE port 1. + * Use gnmi Set REPLACE option for: + * `/routing-policy/policy-definitions` to configure the policy + * Use `/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/apply-policy/config/export-policy` + to apply the policy on the DUT bgp neighbor to the ATE port 2. + * Verify expected communities are present in ATE port 2. + * Mark test as passing if Global Administartive valuee (ASN) of link-bakdwidth extended community **send by DUT** is either `23456` or ASN of DUT. + + * Expected community values for each policy + + | | set_linkbw_0 | not_match_100_set_linkbw_1M | + | ------------ | -------------------------------------- | --------------------------- | + | prefix-set-1 | *DEPRECATED* | [ "link-bandwidth:23456:1000000" ] | + | prefix-set-2 | *DEPRECATED* | [ "100:100" ] | + | prefix-set-3 | *DEPRECATED* | [ "link-bandwidth:23456:1000000" ] | + + | | match_100_set_linkbw_2G | del_linkbw | rm_any_zero_bw_set_LocPref_5 | + | ------------ | ------------------------------------------------- | ------------- | ---------------------------- | + | prefix-set-1 | [ none ] | [none] | *DEPRECATED* | + | prefix-set-2 | [ "100:100", "link-bandwidth:23456:2000000000" ] | [ "100:100" ] | *DEPRECATED* | + | prefix-set-3 | [ "link-bandwidth:23456:1000" ] | [ none ] | *DEPRECATED* | + + * Regarding prefix-set-3 and policy "nomatch_100_set_linkbw_2G" + * prefix-set-3 is advertised to the DUT with community "link-bandwidth:100:0" set. + * The DUT evaluates a match for "regex_nomatch_as100". This does not match because the regex pattern does not include the link-bandwidth community type. + * Community linkbw_2G should be added. ## OpenConfig Path and RPC Coverage @@ -154,7 +145,7 @@ The below yaml defines the OC paths intended to be covered by this test. OC pat paths: ## Config Parameter Coverage ## Configuration to enable advertise communities to bgp peer - /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/send-community: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/send-community-type: ## Policy for community-set configuration /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/ext-community-set-name: /routing-policy/defined-sets/bgp-defined-sets/ext-community-sets/ext-community-set/config/ext-community-member: diff --git a/feature/experimental/bgp/otg_tests/link_bandwidth_test/link_bandwidth_test.go b/feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go similarity index 100% rename from feature/experimental/bgp/otg_tests/link_bandwidth_test/link_bandwidth_test.go rename to feature/bgp/policybase/otg_tests/link_bandwidth_test/link_bandwidth_test.go diff --git a/feature/bgp/policybase/otg_tests/link_bandwidth_test/metadata.textproto b/feature/bgp/policybase/otg_tests/link_bandwidth_test/metadata.textproto index 13552ef78af..5d2b671575b 100644 --- a/feature/bgp/policybase/otg_tests/link_bandwidth_test/metadata.textproto +++ b/feature/bgp/policybase/otg_tests/link_bandwidth_test/metadata.textproto @@ -1,7 +1,41 @@ # proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto # proto-message: Metadata -plan_id: "RT-7.5" -description: "BGP Policy - Set Link Bandwidth Community" -testbed: TESTBED_DUT_ATE_2LINKS -tags: TAGS_DATACENTER_EDGE +uuid: "a8344612-0db0-42a1-96cf-38846a7f1603" +plan_id: "RT-7.5" +description: "BGP Policy - Match and Set Link Bandwidth Community" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + route_policy_under_afi_unsupported: true + omit_l2_mtu: true + missing_value_for_defaults: true + interface_enabled: true + default_network_instance: "default" + skip_set_rp_match_set_options: true + skip_setting_disable_metric_propagation: true + bgp_conditions_match_community_set_unsupported: true + bgp_extended_community_index_unsupported: true + } +} +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + bgp_extended_community_set_unsupported: true + community_member_regex_unsupported: true + skip_setting_statement_for_policy: true + bgp_set_ext_community_set_refs_unsupported: true + bgp_delete_link_bandwidth_unsupported: true + skip_bgp_send_community_type: true + bgp_extended_community_index_unsupported: true + bgp_conditions_match_community_set_unsupported: true + bgp_explicit_extended_community_enable: true + } +} +tags: TAGS_AGGREGATION +tags: TAGS_DATACENTER_EDGE diff --git a/feature/experimental/bgp/otg_tests/link_bandwidth_test/metadata.textproto b/feature/experimental/bgp/otg_tests/link_bandwidth_test/metadata.textproto deleted file mode 100644 index 5d2b671575b..00000000000 --- a/feature/experimental/bgp/otg_tests/link_bandwidth_test/metadata.textproto +++ /dev/null @@ -1,41 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "a8344612-0db0-42a1-96cf-38846a7f1603" -plan_id: "RT-7.5" -description: "BGP Policy - Match and Set Link Bandwidth Community" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - route_policy_under_afi_unsupported: true - omit_l2_mtu: true - missing_value_for_defaults: true - interface_enabled: true - default_network_instance: "default" - skip_set_rp_match_set_options: true - skip_setting_disable_metric_propagation: true - bgp_conditions_match_community_set_unsupported: true - bgp_extended_community_index_unsupported: true - } -} -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - bgp_extended_community_set_unsupported: true - community_member_regex_unsupported: true - skip_setting_statement_for_policy: true - bgp_set_ext_community_set_refs_unsupported: true - bgp_delete_link_bandwidth_unsupported: true - skip_bgp_send_community_type: true - bgp_extended_community_index_unsupported: true - bgp_conditions_match_community_set_unsupported: true - bgp_explicit_extended_community_enable: true - } -} -tags: TAGS_AGGREGATION -tags: TAGS_DATACENTER_EDGE diff --git a/feature/experimental/isis/ate_tests/internal/session/attrs.go b/feature/experimental/isis/ate_tests/internal/session/attrs.go deleted file mode 100644 index 06dfae73b5b..00000000000 --- a/feature/experimental/isis/ate_tests/internal/session/attrs.go +++ /dev/null @@ -1,124 +0,0 @@ -// 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 session - -// This is identical to the internal/attrs library except it points to ygnmi -import ( - "fmt" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" -) - -// Attributes bundles some common attributes for devices and/or interfaces. -// It provides helpers to generate appropriate configuration for OpenConfig -// and for an ATETopology. All fields are optional; only those that are -// non-empty will be set when configuring an interface. -type Attributes struct { - IPv4 string - IPv6 string - MAC string - Name string // Interface name, only applied to ATE ports. - Desc string // Description, only applied to DUT interfaces. - IPv4Len uint8 // Prefix length for IPv4. - IPv6Len uint8 // Prefix length for IPv6. - MTU uint16 -} - -// IPv4CIDR constructs the IPv4 CIDR notation with the given prefix -// length, e.g. "192.0.2.1/30". -func (a *Attributes) IPv4CIDR() string { - return fmt.Sprintf("%s/%d", a.IPv4, a.IPv4Len) -} - -// IPv6CIDR constructs the IPv6 CIDR notation with the given prefix -// length, e.g. "2001:db8::1/126". -func (a *Attributes) IPv6CIDR() string { - return fmt.Sprintf("%s/%d", a.IPv6, a.IPv6Len) -} - -// ConfigInterface configures an OpenConfig interface with these attributes. -func (a *Attributes) ConfigInterface(intf *oc.Interface, dut *ondatra.DUTDevice) *oc.Interface { - if a.Desc != "" { - intf.Description = ygot.String(a.Desc) - } - intf.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - intf.Enabled = ygot.Bool(true) - } - if a.MTU > 0 && !deviations.OmitL2MTU(dut) { - intf.Mtu = ygot.Uint16(a.MTU + 14) - } - e := intf.GetOrCreateEthernet() - if a.MAC != "" { - e.MacAddress = ygot.String(a.MAC) - } - - s := intf.GetOrCreateSubinterface(0) - if a.IPv4 != "" { - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - if a.MTU > 0 { - s4.Mtu = ygot.Uint16(a.MTU) - } - a4 := s4.GetOrCreateAddress(a.IPv4) - if a.IPv4Len > 0 { - a4.PrefixLength = ygot.Uint8(a.IPv4Len) - } - } - - if a.IPv6 != "" { - s6 := s.GetOrCreateIpv6() - if a.MTU > 0 { - s6.Mtu = ygot.Uint32(uint32(a.MTU)) - } - if deviations.InterfaceEnabled(dut) { - s6.Enabled = ygot.Bool(true) - } - a6 := s6.GetOrCreateAddress(a.IPv6) - if a.IPv6Len > 0 { - a6.PrefixLength = ygot.Uint8(a.IPv6Len) - } - } - return intf -} - -// NewOCInterface returns a new *oc.Interface configured with these attributes -func (a *Attributes) NewOCInterface(name string, dut *ondatra.DUTDevice) *oc.Interface { - return a.ConfigInterface(&oc.Interface{Name: ygot.String(name)}, dut) -} - -// AddToATE adds a new interface to an ATETopology with these attributes. -func (a *Attributes) AddToATE(top *ondatra.ATETopology, ap *ondatra.Port, peer *Attributes) *ondatra.Interface { - i := top.AddInterface(a.Name).WithPort(ap) - if a.MTU > 0 { - i.Ethernet().WithMTU(a.MTU) - } - if a.IPv4 != "" { - i.IPv4(). - WithAddress(a.IPv4CIDR()). - WithDefaultGateway(peer.IPv4) - } - if a.IPv6 != "" { - i.IPv6(). - WithAddress(a.IPv6CIDR()). - WithDefaultGateway(peer.IPv6) - } - return i -} diff --git a/feature/experimental/isis/ate_tests/internal/session/session.go b/feature/experimental/isis/ate_tests/internal/session/session.go deleted file mode 100644 index 6fbc5caa12c..00000000000 --- a/feature/experimental/isis/ate_tests/internal/session/session.go +++ /dev/null @@ -1,338 +0,0 @@ -// 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 session is deprecated and scoped only to be used with -// feature/experimental/isis/ate_tests/*. Do not use elsewhere. -package session - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/gnmi/oc/netinstisis" - "github.com/openconfig/ondatra/gnmi/oc/networkinstance" - "github.com/openconfig/ondatra/gnmi/oc/ocpath" - "github.com/openconfig/ondatra/ixnet" - "github.com/openconfig/ygnmi/ygnmi" - "github.com/openconfig/ygot/ygot" -) - -// PTISIS is shorthand for the long oc protocol type constant -const PTISIS = oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS - -// The testbed consists of a dut and an ate with two connections, labeled ISISIntf and Intf2. -// ISISIntf links dut:port1 and ate:port1, which are assigned 192.0.2.1/30 and 192.0.2.2/30 -// respectively. Intf2 connects dut:port2 to ate:port2, which are 192.0.2.5/30 and 192.0.2.6/30. -// We establish an IS-IS adjacency over ISISIntf. For traffic testing, we configure the ATE end -// of the IS-IS adjacency to advertise 198.51.100.0/24, then generate traffic through ate:port2 with -// IPv4 headers indicating that it should go to a random address in that range; the dut should -// route this traffic to the IS-IS link, where the ATE should log it arriving on ate:port1. -const ( - DUTAreaAddress = "49.0001" - ATEAreaAddress = "49.0002" - DUTSysID = "1920.0000.2001" - ISISName = "DEFAULT" - pLen4 = 30 - pLen6 = 126 -) - -var ( - // DUTNET is the Network Entity Title for the DUT - DUTNET = fmt.Sprintf("%v.%v.00", DUTAreaAddress, DUTSysID) - // DUTISISAttrs has attributes for the DUT ISIS connection on port1 - DUTISISAttrs = &Attributes{ - Desc: "DUT to ATE with IS-IS", - IPv4: "192.0.2.1", - IPv6: "2001:db8::1", - IPv4Len: pLen4, - IPv6Len: pLen6, - } - // ATEISISAttrs has attributes for the ATE ISIS connection on port1 - ATEISISAttrs = &Attributes{ - Name: "port1", - Desc: "ATE to DUT with IS-IS", - IPv4: "192.0.2.2", - IPv6: "2001:db8::2", - IPv4Len: pLen4, - IPv6Len: pLen6, - } - // DUTTrafficAttrs has attributes for the DUT end of the traffic connection (port2) - DUTTrafficAttrs = &Attributes{ - Desc: "DUT to ATE secondary link", - IPv4: "192.0.2.5", - IPv6: "2001:db8::5", - IPv4Len: pLen4, - IPv6Len: pLen6, - } - // ATETrafficAttrs has attributes for the ATE end of the traffic connection (port2) - ATETrafficAttrs = &Attributes{ - Name: "port2", - Desc: "ATE to DUT secondary link", - IPv4: "192.0.2.6", - IPv6: "2001:db8::6", - IPv4Len: pLen4, - IPv6Len: pLen6, - } -) - -// ISISPath is shorthand for ProtocolPath().Isis(). -func ISISPath(dut *ondatra.DUTDevice) *netinstisis.NetworkInstance_Protocol_IsisPath { - return ProtocolPath(dut).Isis() -} - -// ProtocolPath returns the path to the IS-IS protocol named ISISName on the -// default network instance. -func ProtocolPath(dut *ondatra.DUTDevice) *networkinstance.NetworkInstance_ProtocolPath { - return ocpath.Root().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(PTISIS, ISISName) -} - -// addISISOC configures basic IS-IS on a device. -func addISISOC(dev *oc.Root, areaAddress, sysID, ifaceName string, dut *ondatra.DUTDevice) { - inst := dev.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - prot := inst.GetOrCreateProtocol(PTISIS, ISISName) - prot.Enabled = ygot.Bool(true) - isis := prot.GetOrCreateIsis() - glob := isis.GetOrCreateGlobal() - if deviations.ISISInstanceEnabledRequired(dut) { - glob.Instance = ygot.String(ISISName) - } - glob.Net = []string{fmt.Sprintf("%v.%v.00", areaAddress, sysID)} - glob.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) - glob.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) - level := isis.GetOrCreateLevel(2) - level.MetricStyle = oc.Isis_MetricStyle_WIDE_METRIC - intf := isis.GetOrCreateInterface(ifaceName) - intf.CircuitType = oc.Isis_CircuitType_POINT_TO_POINT - intf.Enabled = ygot.Bool(true) - // Configure ISIS level at global mode if true else at interface mode - if deviations.ISISInterfaceLevel1DisableRequired(dut) { - intf.GetOrCreateLevel(1).Enabled = ygot.Bool(false) - } else { - intf.GetOrCreateLevel(2).Enabled = ygot.Bool(true) - } - glob.LevelCapability = oc.Isis_LevelType_LEVEL_2 - // Configure ISIS enable flag at interface level - intf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) - intf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) - if deviations.ISISInterfaceAfiUnsupported(dut) { - intf.Af = nil - } - -} - -// addISISTopo configures basic IS-IS on an ATETopology interface. -func addISISTopo(iface *ondatra.Interface, areaAddress, sysID string) { - isis := iface.ISIS() - isis. - WithAreaID(areaAddress). - WithTERouterID(sysID). - WithNetworkTypePointToPoint(). - WithWideMetricEnabled(true). - WithLevelL2().WithMetric(10) -} - -// TestSession is a convenience wrapper around the dut, ate, ports, and -// topology we're using. -type TestSession struct { - DUT *ondatra.DUTDevice - DUTClient *ygnmi.Client - ATE *ondatra.ATEDevice - // Rather than looking these up all the time, we fetch all the relevant ports - // and interfaces at setup time. - DUTPort1, DUTPort2, ATEPort1, ATEPort2 *ondatra.Port - ATEIntf1, ATEIntf2 *ondatra.Interface - // DUTConf and ATETop can be modified by tests; calling .Push() will apply - // them to the dut and ate. - DUTConf *oc.Root - ATETop *ondatra.ATETopology -} - -// New creates a new TestSession using the default global config, and -// configures the interfaces on the dut and the ate. -func New(t testing.TB) (*TestSession, error) { - t.Helper() - s := &TestSession{} - s.DUT = ondatra.DUT(t, "dut") - var err error - s.DUTClient, err = ygnmi.NewClient(s.DUT.RawAPIs().GNMI(t), ygnmi.WithTarget(s.DUT.ID())) - if err != nil { - return nil, fmt.Errorf("unable to connect to gNMI on %v: %w", s.DUT, err) - } - s.DUTPort1 = s.DUT.Port(t, "port1") - s.DUTPort2 = s.DUT.Port(t, "port2") - s.DUTConf = &oc.Root{} - // configure dut ports - DUTISISAttrs.ConfigInterface(s.DUTConf.GetOrCreateInterface(s.DUTPort1.Name()), s.DUT) - DUTTrafficAttrs.ConfigInterface(s.DUTConf.GetOrCreateInterface(s.DUTPort2.Name()), s.DUT) - - // If there is no ate, any operation that requires the ATE will call - // t.Fatal() instead. This is helpful for debugging the parts of the test - // that don't use an ATE. - if ate, ok := ondatra.ATEs(t)["ate"]; ok { - s.ATE = ate - s.ATEPort1 = s.ATE.Port(t, "port1") - s.ATEPort2 = s.ATE.Port(t, "port2") - s.ATETop = s.ATE.Topology().New() - s.ATEIntf1 = ATEISISAttrs.AddToATE(s.ATETop, s.ATEPort1, DUTISISAttrs) - s.ATEIntf2 = ATETrafficAttrs.AddToATE(s.ATETop, s.ATEPort2, DUTTrafficAttrs) - } - return s, nil -} - -// MustNew creates a new TestSession or Fatal()s if anything goes wrong. -func MustNew(t testing.TB) *TestSession { - t.Helper() - v, err := New(t) - if err != nil { - t.Fatalf("Unable to initialize topology: %v", err) - } - return v -} - -// WithISIS adds ISIS to a test session. -func (s *TestSession) WithISIS() *TestSession { - if deviations.ExplicitInterfaceInDefaultVRF(s.DUT) { - addISISOC(s.DUTConf, DUTAreaAddress, DUTSysID, s.DUTPort1.Name()+".0", s.DUT) - } else { - addISISOC(s.DUTConf, DUTAreaAddress, DUTSysID, s.DUTPort1.Name(), s.DUT) - } - if s.ATE != nil { - addISISTopo(s.ATEIntf1, ATEAreaAddress, "*") - } - return s -} - -// ConfigISIS takes two functions, one that operates on an OC IS-IS block and -// one that operates on an ondatra ATE IS-IS block. The first will be applied -// to the IS-IS block of ts.DUTConfig, and the second will be applied to the -// IS-IS configuration of ts.ATETop -func (s *TestSession) ConfigISIS(ocFn func(*oc.NetworkInstance_Protocol_Isis), ateFn func(*ixnet.ISIS)) { - ocFn(s.DUTConf.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(s.DUT)).GetOrCreateProtocol(PTISIS, ISISName).GetOrCreateIsis()) - if s.ATE != nil { - ateFn(s.ATEIntf1.ISIS()) - } -} - -// PushAndStart calls PushDUT and PushAndStartATE to send config to both -// devices. -func (s *TestSession) PushAndStart(t testing.TB) error { - t.Helper() - if err := s.PushDUT(context.Background(), t); err != nil { - return err - } - s.PushAndStartATE(t) - return nil -} - -// PushDUT replaces DUT config with s.dutConf. Only interfaces and the ISIS -// protocol are written. -func (s *TestSession) PushDUT(ctx context.Context, t testing.TB) error { - // Push the interfaces - for name, conf := range s.DUTConf.Interface { - _, err := ygnmi.Replace(ctx, s.DUTClient, ocpath.Root().Interface(name).Config(), conf) - if err != nil { - return fmt.Errorf("configuring interface %s: %w", name, err) - } - } - if deviations.ExplicitInterfaceInDefaultVRF(s.DUT) { - fptest.AssignToNetworkInstance(t, s.DUT, s.DUTPort1.Name(), deviations.DefaultNetworkInstance(s.DUT), 0) - fptest.AssignToNetworkInstance(t, s.DUT, s.DUTPort2.Name(), deviations.DefaultNetworkInstance(s.DUT), 0) - } - if deviations.ExplicitPortSpeed(s.DUT) { - fptest.SetPortSpeed(t, s.DUTPort1) - fptest.SetPortSpeed(t, s.DUTPort2) - } - - // Push the ISIS protocol - if _, err := ygnmi.Update(ctx, s.DUTClient, ocpath.Root().NetworkInstance(deviations.DefaultNetworkInstance(s.DUT)).Config(), &oc.NetworkInstance{ - Name: ygot.String(deviations.DefaultNetworkInstance(s.DUT)), - Type: oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE, - }); err != nil { - return fmt.Errorf("configuring network instance: %w", err) - } - dutConf := s.DUTConf.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(s.DUT)).GetOrCreateProtocol(PTISIS, ISISName) - _, err := ygnmi.Replace(ctx, s.DUTClient, ProtocolPath(s.DUT).Config(), dutConf) - if err != nil { - return fmt.Errorf("configuring ISIS: %w", err) - } - return nil -} - -// PushAndStartATE pushes the ATETop to the ATE and starts protocols on it. -func (s *TestSession) PushAndStartATE(t testing.TB) { - t.Helper() - if s.ATE == nil { - t.Fatal("Cannot run test without ATE") - } - s.ATETop.Push(t).StartProtocols(t) -} - -// AwaitAdjacency waits up to a minute for the dut to report that the ISISIntf -// link has formed any IS-IS adjacency, returning the adjacency ID or an error -// if one doesn't form. -func (s *TestSession) AwaitAdjacency() (string, error) { - intf := ISISPath(s.DUT).Interface(s.DUTPort1.Name()) - if deviations.ExplicitInterfaceInDefaultVRF(s.DUT) { - intf = ISISPath(s.DUT).Interface(s.DUTPort1.Name() + ".0") - } - query := intf.LevelAny().AdjacencyAny().AdjacencyState().State() - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - watcher := ygnmi.WatchAll(ctx, s.DUTClient, query, func(val *ygnmi.Value[oc.E_Isis_IsisInterfaceAdjState]) error { - if val == nil || !val.IsPresent() { - return ygnmi.Continue - } - v, _ := val.Val() - if v == oc.Isis_IsisInterfaceAdjState_UP { - return nil - } - return ygnmi.Continue - }) - - got, err := watcher.Await() - if err != nil { - return "", err - } - return got.Path.GetElem()[10].GetKey()["system-id"], nil -} - -// MustAdjacency waits up to a minute for an IS-IS adjacency to form between -// the DUT and the ATE; it returns the adjacency ID or calls t.Fatal no -// adjacency forms. -func (s *TestSession) MustAdjacency(t testing.TB) string { - adjID, err := s.AwaitAdjacency() - if err != nil { - t.Fatalf("Waiting for adjacency to form: %v", err) - } - return adjID -} - -// MustATEInterface returns the ATE interface for the portID, or calls t.Fatal -// if this fails. -func (s *TestSession) MustATEInterface(t testing.TB, portID string) *ondatra.Interface { - if s.ATE == nil { - t.Fatal("Cannot run test without ATE") - } - iface, ok := s.ATETop.Interfaces()[portID] - if !ok { - t.Fatalf("No ATE interface with ID %v", portID) - } - return iface -} diff --git a/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md b/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md deleted file mode 100644 index 0a0d6fe16b1..00000000000 --- a/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md +++ /dev/null @@ -1,99 +0,0 @@ -# RT-2.6: IS-IS Hello-Padding enabled at interface level - -## Summary - -* Base IS-IS functionality and adjacency establishment. -* Verifies isis adjacency by changing MTU. - -## Procedure - -* Configure IS-IS for ATE port-1 and DUT port-1. -* Configure DUT with global hello-padding enabled. -* Ensure that adjacencies are established with: - * Interface level hello padding is enabled. - * Verify that IPv4 and IPv6 IS-ISIS adjacency comes up fine. - * Verify the output of ST path displaying the status of ISIS hello padding. - * If we change the MTU on either side, then adjacency should not come up. - * Verify that IPv4 and IPv6 prefixes that are advertised by ATE correctly installed into DUTs route and forwarding table. - * TODO-Verify the Hellos are sent with Padding during adjacency turn-up if the padding is enabled adaptively/sometimes. - * Ensure that IPv4 and IPv6 prefixes that are advertised as part of an (emulated) neighboring system are installed into the DUT routing table, and validate that packets are sent and received to them. - -## Config Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * global/config/authentication-check - * global/config/net - * global/config/level-capability - * global/config/hello-padding - * global/afi-safi/af/config/enabled - * levels/level/config/level-number - * levels/level/config/enabled - * levels/level/authentication/config/enabled - * levels/level/authentication/config/auth-mode - * levels/level/authentication/config/auth-password - * levels/level/authentication/config/auth-type - * interfaces/interface/config/interface-id - * interfaces/interface/config/enabled - * interfaces/interface/config/circuit-type - * interfaces/interface/timers/config/csnp-interval - * interfaces/interface/timers/config/lsp-pacing-interval - * interfaces/interface/levels/level/config/level-number - * interfaces/interface/levels/level/timers/config/hello-interval - * interfaces/interface/levels/level/timers/config/hello-multiplier - * interfaces/interface/levels/level/hello-authentication/config/auth-mode - * interfaces/interface/levels/level/hello-authentication/config/auth-password - * interfaces/interface/levels/level/hello-authentication/config/auth-type - * interfaces/interface/levels/level/hello-authentication/config/enabled - * interfaces/interface/afi-safi/af/config/afi-name - * interfaces/interface/afi-safi/af/config/safi-name - * interfaces/interface/afi-safi/af/config/metric - * interfaces/interface/afi-safi/af/config/enabled - -## Telemetry Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * global/state/hello-padding - * interfaces/interface/state/hello-padding - * interfaces/interface/levels/level/adjacencies/adjacency/state/adjacency-state - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv4-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv6-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/system-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/area-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/dis-system-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/local-extended-circuit-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/multi-topology - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-circuit-type - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-extended-circuit-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-snpa - * interfaces/interface/levels/level/adjacencies/adjacency/state/nlpid - * interfaces/interface/levels/level/adjacencies/adjacency/state/priority - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-status - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-support - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-suppress - * interfaces/interface/levels/level/afi-safi/af/state/afi-name - * interfaces/interface/levels/level/afi-safi/af/state/metric - * interfaces/interface/levels/level/afi-safi/af/state/safi-name - * interfaces/interface/levels/level/afi-safi/af/state/metric - * levels/level/system-level-counters/state/auth-fails - * levels/level/system-level-counters/state/auth-type-fails - * levels/level/system-level-counters/state/corrupted-lsps - * levels/level/system-level-counters/state/database-overloads - * levels/level/system-level-counters/state/exceed-max-seq-nums - * levels/level/system-level-counters/state/id-len-mismatch - * levels/level/system-level-counters/state/lsp-errors - * levels/level/system-level-counters/state/manual-address-drop-from-area - * levels/level/system-level-counters/state/max-area-address-mismatches - * levels/level/system-level-counters/state/own-lsp-purges - * levels/level/system-level-counters/state/part-changes - * levels/level/system-level-counters/state/seq-num-skips - * levels/level/system-level-counters/state/spf-runs diff --git a/feature/experimental/isis/otg_tests/isis_interface_level_passive_test/README.md b/feature/experimental/isis/otg_tests/isis_interface_level_passive_test/README.md deleted file mode 100644 index 6e80f5f2985..00000000000 --- a/feature/experimental/isis/otg_tests/isis_interface_level_passive_test/README.md +++ /dev/null @@ -1,102 +0,0 @@ -# RT-2.11: IS-IS Passive is enabled at the area level - -## Summary - -* Verify isis adjacency with passive enabled under level. - -## Topology - -* ATE:port1 <-> port1:DUT:port2 <-> ATE:port2 - -## Procedure - -* Configure IS-IS for ATE port-1 and DUT port-1. -* Configure DUT interface with IS-IS passive configured at area level 2. - * Verify that IS-IS adjacency is not coming up in level-2 area for IPv4 and IPV6 address families. -* Undo the IS-IS passive configuration under level 2 - * Verify that IS-IS adjacency for IPv4 and IPV6 address families are coming up in the level-2 area. - * Verify that IPv4 and IPv6 prefixes that are advertised by ATE are correctly installed into DUTs route and forwarding table. - * Ensure that IPv4 and IPv6 prefixes that are advertised as part of an (emulated) neighboring system are installed into the DUT routing table, and validate that packets are sent and received to them. - * TODO-Verify the output of ST path displaying the interface as passive in ISIS database/adj table - -## Config Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * global/config/authentication-check - * global/config/net - * global/config/level-capability - * global/config/hello-padding - * global/afi-safi/af/config/enabled - * levels/level/config/level-number - * levels/level/config/enabled - * levels/level/authentication/config/enabled - * levels/level/authentication/config/auth-mode - * levels/level/authentication/config/auth-password - * levels/level/authentication/config/auth-type - * interfaces/interface/config/interface-id - * interfaces/interface/config/enabled - * interfaces/interface/config/circuit-type - * interfaces/interface/config/passive - * interfaces/interface/timers/config/csnp-interval - * interfaces/interface/timers/config/lsp-pacing-interval - * interfaces/interface/levels/level/config/level-number - * interfaces/interface/levels/level/config/passive - * interfaces/interface/levels/level/timers/config/hello-interval - * interfaces/interface/levels/level/timers/config/hello-multiplier - * interfaces/interface/levels/level/hello-authentication/config/auth-mode - * interfaces/interface/levels/level/hello-authentication/config/auth-password - * interfaces/interface/levels/level/hello-authentication/config/auth-type - * interfaces/interface/levels/level/hello-authentication/config/enabled - * interfaces/interface/afi-safi/af/config/afi-name - * interfaces/interface/afi-safi/af/config/safi-name - * interfaces/interface/afi-safi/af/config/metric - * interfaces/interface/afi-safi/af/config/enabled - -## Telemetry Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * interfaces/interface/state/passive - * interfaces/interface/levels/level/state/passive - * interfaces/interface/levels/level/adjacencies/adjacency/state/adjacency-state - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv4-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv6-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/system-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/area-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/dis-system-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/local-extended-circuit-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/multi-topology - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-circuit-type - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-extended-circuit-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-snpa - * interfaces/interface/levels/level/adjacencies/adjacency/state/nlpid - * interfaces/interface/levels/level/adjacencies/adjacency/state/priority - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-status - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-support - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-suppress - * interfaces/interface/levels/level/afi-safi/af/state/afi-name - * interfaces/interface/levels/level/afi-safi/af/state/metric - * interfaces/interface/levels/level/afi-safi/af/state/safi-name - * interfaces/interface/levels/level/afi-safi/af/state/metric - * levels/level/system-level-counters/state/auth-fails - * levels/level/system-level-counters/state/auth-type-fails - * levels/level/system-level-counters/state/corrupted-lsps - * levels/level/system-level-counters/state/database-overloads - * levels/level/system-level-counters/state/exceed-max-seq-nums - * levels/level/system-level-counters/state/id-len-mismatch - * levels/level/system-level-counters/state/lsp-errors - * levels/level/system-level-counters/state/manual-address-drop-from-area - * levels/level/system-level-counters/state/max-area-address-mismatches - * levels/level/system-level-counters/state/own-lsp-purges - * levels/level/system-level-counters/state/part-changes - * levels/level/system-level-counters/state/seq-num-skips - * levels/level/system-level-counters/state/spf-runs diff --git a/feature/experimental/isis/otg_tests/isis_metric_style_wide_not_enabled_test/README.md b/feature/experimental/isis/otg_tests/isis_metric_style_wide_not_enabled_test/README.md deleted file mode 100644 index 4347c71375c..00000000000 --- a/feature/experimental/isis/otg_tests/isis_metric_style_wide_not_enabled_test/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# RT-2.8: IS-IS metric style wide not enabled - -## Summary - -* Base IS-IS functionality and adjacency establishment. -* Verifies route metric with wide metric disabled on DUT. - -## Procedure - -* TestISISWideMetricNotEnabled - - * Configure IS-IS for ATE port-1 and DUT port-1. - * Do not configure metric style wide under the area level. - * Enable wide metric style on ATE. - * Advertise ISIS prefixes from ATE with wide metrics (value > 63). - * Verify that IS-IS adjacency for IPv4 and IPV6 address family is coming up. - * Verify that IPv4 and IPv6 prefixes that are advertised by ATE correctly installed into DUTs route and forwarding table. - * TODO-Verify that the metrics of the IPv4 and IPv6 prefixes is 63. - * Ensure that IPv4 and IPv6 prefixes that are advertised as part of an (emulated) neighboring system are installed into the DUT routing table, and validate that packets are sent and received to them. - - -## Config Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * global/config/authentication-check - * global/config/net - * global/config/level-capability - * global/config/hello-padding - * global/afi-safi/af/config/enabled - * levels/level/config/level-number - * levels/level/config/enabled - * levels/level/config/metric-style - * levels/level/authentication/config/enabled - * levels/level/authentication/config/auth-mode - * levels/level/authentication/config/auth-password - * levels/level/authentication/config/auth-type - * interfaces/interface/config/interface-id - * interfaces/interface/config/enabled - * interfaces/interface/config/circuit-type - * interfaces/interface/config/passive - * interfaces/interface/timers/config/csnp-interval - * interfaces/interface/timers/config/lsp-pacing-interval - * interfaces/interface/levels/level/config/level-number - * interfaces/interface/levels/level/config/passive - * interfaces/interface/levels/level/timers/config/hello-interval - * interfaces/interface/levels/level/timers/config/hello-multiplier - * interfaces/interface/levels/level/hello-authentication/config/auth-mode - * interfaces/interface/levels/level/hello-authentication/config/auth-password - * interfaces/interface/levels/level/hello-authentication/config/auth-type - * interfaces/interface/levels/level/hello-authentication/config/enabled - * interfaces/interface/afi-safi/af/config/afi-name - * interfaces/interface/afi-safi/af/config/safi-name - * interfaces/interface/afi-safi/af/config/enabled - -## Telemetry Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * levels/level/state/metric-style - * interfaces/interface/levels/level/adjacencies/adjacency/state/adjacency-state - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv4-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv6-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/system-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/area-address - * interfaces/interface/levels/level/adjacencies/adjacency/state/dis-system-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/local-extended-circuit-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/multi-topology - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-circuit-type - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-extended-circuit-id - * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-snpa - * interfaces/interface/levels/level/adjacencies/adjacency/state/nlpid - * interfaces/interface/levels/level/adjacencies/adjacency/state/priority - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-status - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-support - * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-suppress - * interfaces/interface/levels/level/afi-safi/af/state/afi-name - * interfaces/interface/levels/level/afi-safi/af/state/metric - * interfaces/interface/levels/level/afi-safi/af/state/safi-name - * interfaces/interface/levels/level/afi-safi/af/state/metric - * levels/level/system-level-counters/state/auth-fails - * levels/level/system-level-counters/state/auth-type-fails - * levels/level/system-level-counters/state/corrupted-lsps - * levels/level/system-level-counters/state/database-overloads - * levels/level/system-level-counters/state/exceed-max-seq-nums - * levels/level/system-level-counters/state/id-len-mismatch - * levels/level/system-level-counters/state/lsp-errors - * levels/level/system-level-counters/state/manual-address-drop-from-area - * levels/level/system-level-counters/state/max-area-address-mismatches - * levels/level/system-level-counters/state/own-lsp-purges - * levels/level/system-level-counters/state/part-changes - * levels/level/system-level-counters/state/seq-num-skips - * levels/level/system-level-counters/state/spf-runs diff --git a/feature/experimental/policy/policy_base/feature.textproto b/feature/experimental/policy/policy_base/feature.textproto deleted file mode 100644 index e0799b0980c..00000000000 --- a/feature/experimental/policy/policy_base/feature.textproto +++ /dev/null @@ -1,208 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_policy_policy_base" - version: 1 -} - -# Policy base - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/config/policy-id" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/config/type" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/state/policy-id" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/state/type" -} - -# Rules base - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/config/sequence-id" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/state/sequence-id" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/state/matched-pkts" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/state/matched-octets" -} - -# Action base - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/config/discard" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/state/discard" -} - -# Interface base - -config_path { - path: "/network-instances/network-instance/policy-forwarding/interfaces/interface/config/interface-id" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/interfaces/interface/state/interface-id" -} - -# L2 rules - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/config/ethertype" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/config/source-mac" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/config/source-mac-mask" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/config/destination-mac" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/config/destination-mac-mask" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/state/ethertype" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/state/source-mac" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/state/source-mac-mask" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/state/destination-mac" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/l2/state/destination-mac-mask" -} - -# IPv4 rules - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/config/source-address" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/config/destination-address" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/config/dscp" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/config/dscp-set" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/config/protocol" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/config/hop-limit" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/state/source-address" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/state/destination-address" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/state/dscp" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/state/dscp-set" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/state/protocol" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/state/hop-limit" -} - -# IPv6 rules - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/source-address" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/source-flow-label" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/destination-address" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/destination-flow-label" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/dscp" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/dscp-set" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/protocol" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/hop-limit" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/source-address" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/source-flow-label" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/destination-address" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/destination-flow-label" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/dscp" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/dscp-set" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/protocol" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/state/hop-limit" -} - -# Transport rules - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/transport/config/source-port" -} -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/transport/config/destination-port" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/transport/state/source-port" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/transport/state/destination-port" -} - diff --git a/feature/experimental/policy/policy_vrf_selection/feature.textproto b/feature/experimental/policy/policy_vrf_selection/feature.textproto deleted file mode 100644 index a5262ef5612..00000000000 --- a/feature/experimental/policy/policy_vrf_selection/feature.textproto +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_policy_policy_vrf_selection" - version: 1 -} - -# Interface - -config_path { - path: "/network-instances/network-instance/policy-forwarding/interfaces/interface/config/apply-vrf-selection-policy" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/interfaces/interface/state/apply-vrf-selection-policy" -} - -# VRF actions - -config_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/config/network-instance" -} -telemetry_path { - path: "/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/state/network-instance" -} - - -feature_profile_dependency { - name: "bgp_policybase" - version: 1 -} diff --git a/feature/experimental/replay/tests/presession_test/README.md b/feature/experimental/replay/tests/presession_test/README.md deleted file mode 100644 index 2fcd2fc461d..00000000000 --- a/feature/experimental/replay/tests/presession_test/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Replay-1.0: Record/replay presession test - -## Summary - -This is an example record/replay test. -At this time, no vendor is expected to run this test. diff --git a/feature/gnmi/otg_tests/telemetry_basic_check_test/telemetry_basic_check_test.go b/feature/gnmi/otg_tests/telemetry_basic_check_test/telemetry_basic_check_test.go index e66ca0d9af4..8747345ceac 100644 --- a/feature/gnmi/otg_tests/telemetry_basic_check_test/telemetry_basic_check_test.go +++ b/feature/gnmi/otg_tests/telemetry_basic_check_test/telemetry_basic_check_test.go @@ -328,18 +328,17 @@ func TestQoSCounters(t *testing.T) { path: qosQueuePath + "dropped-pkts", counters: gnmi.LookupAll(t, dut, queues.DroppedPkts().State()), }} - if !deviations.QOSDroppedOctets(dut) { - cases = append(cases, - struct { - desc string - path string - counters []*ygnmi.Value[uint64] - }{ - desc: "DroppedOctets", - path: qosQueuePath + "dropped-octets", - counters: gnmi.LookupAll(t, dut, queues.DroppedOctets().State()), - }) - } + cases = append(cases, + struct { + desc string + path string + counters []*ygnmi.Value[uint64] + }{ + desc: "DroppedOctets", + path: qosQueuePath + "dropped-octets", + counters: gnmi.LookupAll(t, dut, queues.DroppedOctets().State()), + }) + for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { diff --git a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto index 693fd78a761..7eae9761928 100644 --- a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto +++ b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto @@ -13,6 +13,7 @@ platform_exceptions: { ipv4_missing_enabled: true interface_counters_from_container: true subinterface_packet_counters_missing: true + interface_counters_update_delayed: true } } platform_exceptions: { diff --git a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go index cf9310999ee..9cc8591a9ab 100644 --- a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go +++ b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go @@ -244,6 +244,31 @@ func fetchInAndOutPkts(t *testing.T, dut *ondatra.DUTDevice, i1, i2 *interfaces. return inPkts, outPkts } +func waitForCountersUpdate(t *testing.T, dut *ondatra.DUTDevice, i1, i2 *interfaces.InterfacePath, + inTarget, outTarget uint64) (map[string]uint64, map[string]uint64) { + inWatcher := gnmi.Watch(t, dut, i1.Counters().InUnicastPkts().State(), time.Second*60, func(v *ygnmi.Value[uint64]) bool { + got, present := v.Val() + return present && got >= inTarget + }) + outWatcher := gnmi.Watch(t, dut, i2.Counters().OutUnicastPkts().State(), + time.Second*60, func(v *ygnmi.Value[uint64]) bool { + got, present := v.Val() + return present && got >= outTarget + }) + + inPktsV, ok := inWatcher.Await(t) + if !ok { + t.Fatalf("InPkts counter did not update in time") + } + outPktsV, ok := outWatcher.Await(t) + if !ok { + t.Fatalf("OutPkts counter did not update in time") + } + inPkts, _ := inPktsV.Val() + outPkts, _ := outPktsV.Val() + return map[string]uint64{"parent": inPkts}, map[string]uint64{"parent": outPkts} +} + func TestIntfCounterUpdate(t *testing.T) { dut := ondatra.DUT(t, "dut") dp1 := dut.Port(t, "port1") @@ -378,7 +403,14 @@ func TestIntfCounterUpdate(t *testing.T) { } } - dutInPktsAfterTraffic, dutOutPktsAfterTraffic := fetchInAndOutPkts(t, dut, i1, i2) + var dutInPktsAfterTraffic, dutOutPktsAfterTraffic map[string]uint64 + if deviations.InterfaceCountersUpdateDelayed(dut) { + dutInPktsAfterTraffic, dutOutPktsAfterTraffic = waitForCountersUpdate(t, dut, i1, i2, + dutInPktsBeforeTraffic["parent"]+ateInPkts["parent"], + dutOutPktsBeforeTraffic["parent"]+ateOutPkts["parent"]) + } else { + dutInPktsAfterTraffic, dutOutPktsAfterTraffic = fetchInAndOutPkts(t, dut, i1, i2) + } t.Logf("inPkts: %v and outPkts: %v after traffic: ", dutInPktsAfterTraffic, dutOutPktsAfterTraffic) for k := range dutInPktsAfterTraffic { diff --git a/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go b/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go index 30d20401fc6..d709bd4adaa 100644 --- a/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go +++ b/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go @@ -197,7 +197,7 @@ func getSubCompPath(t *testing.T, dut *ondatra.DUTDevice) *tpb.Path { } activeRP := controllerCards[0] if len(controllerCards) == 2 { - _, activeRP = components.FindStandbyRP(t, dut, controllerCards) + _, activeRP = components.FindStandbyControllerCard(t, dut, controllerCards) } useNameOnly := deviations.GNOISubcomponentPath(dut) return components.GetSubcomponentPath(activeRP, useNameOnly) diff --git a/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go b/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go index 7a2bfcfc27a..27bbc03efb5 100644 --- a/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go +++ b/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go @@ -18,12 +18,15 @@ import ( "testing" "time" + comps "github.com/openconfig/featureprofiles/internal/components" + "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/system" hpb "github.com/openconfig/gnoi/healthz" spb "github.com/openconfig/gnoi/system" tpb "github.com/openconfig/gnoi/types" "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi/oc" ) var ( @@ -31,13 +34,15 @@ var ( ondatra.NOKIA: "sr_qos_mgr", ondatra.ARISTA: "IpRib", ondatra.JUNIPER: "rpd", + ondatra.CISCO: "ifmgr", } components = map[ondatra.Vendor]string{ ondatra.ARISTA: "Chassis", - ondatra.CISCO: "Chassis", + ondatra.CISCO: "Rack 0", ondatra.JUNIPER: "CHASSIS0", ondatra.NOKIA: "Chassis", } + componentName = map[string]string{} ) func TestMain(m *testing.M) { @@ -86,9 +91,29 @@ func TestCopyingDebugFiles(t *testing.T) { t.Logf("Wait 60 seconds for process to restart ...") time.Sleep(60 * time.Second) - componentName := map[string]string{"name": components[dut.Vendor()]} + ccList := comps.FindComponentsByType(t, dut, oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_CONTROLLER_CARD) + t.Logf("Found CONTROLLER_CARD list: %v", ccList) + var activeCC string + if deviations.ChassisGetRPCUnsupported(dut) { + if len(ccList) < 2 { + switch dut.Vendor() { + case ondatra.CISCO: + activeCC = "0/RP0/CPU0" + } + } else { + standbyControllerName, activeControllerName := comps.FindStandbyControllerCard(t, dut, ccList) + t.Logf("Standby RP: %v, Active RP: %v", standbyControllerName, activeControllerName) + activeCC = activeControllerName + } + componentName = map[string]string{"name": activeCC + "-" + processName[dut.Vendor()]} // example: 0/RP0/CPU0-ifmgr + } else { + componentName = map[string]string{"name": components[dut.Vendor()]} + } + t.Logf("Component Name: %v", componentName) + req := &hpb.GetRequest{ Path: &tpb.Path{ + Origin: "openconfig", Elem: []*tpb.PathElem{ { Name: "components", @@ -106,10 +131,10 @@ func TestCopyingDebugFiles(t *testing.T) { case ondatra.ARISTA: t.Log("Skip logging validResponse for Arista") default: - t.Logf("Response: %v", (validResponse)) + t.Logf("Response: %v", validResponse) } if err != nil { - t.Fatalf("Unexpected error on healthz get response after restart of %v: %v", processName[dut.Vendor()], err) + t.Errorf("Unexpected error on healthz get response after restart of %v: %v", processName[dut.Vendor()], err) } } @@ -120,6 +145,7 @@ func TestChassisComponentArtifacts(t *testing.T) { // Execute Healthz Check RPC for the chassis component. chkReq := &hpb.CheckRequest{ Path: &tpb.Path{ + Origin: "openconfig", Elem: []*tpb.PathElem{ { Name: "components", diff --git a/feature/gnoi/system/tests/copying_debug_files_test/metadata.textproto b/feature/gnoi/system/tests/copying_debug_files_test/metadata.textproto index 4d3c878aa43..fc3f0cd55ac 100644 --- a/feature/gnoi/system/tests/copying_debug_files_test/metadata.textproto +++ b/feature/gnoi/system/tests/copying_debug_files_test/metadata.textproto @@ -5,3 +5,11 @@ uuid: "3265de19-8fb8-4b0c-8a71-a75df008aa61" plan_id: "gNOI-5.3" description: "Copying Debug Files" testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + chassis_get_rpc_unsupported: true + } +} \ No newline at end of file diff --git a/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go b/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go index 53824b90d0c..18ccb12057d 100644 --- a/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go +++ b/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go @@ -95,7 +95,7 @@ func TestStandbyControllerCardReboot(t *testing.T) { t.Skipf("Not enough controller cards for the test on %v: got %v, want at least %v", dut.Model(), got, want) } - rpStandby, rpActive := components.FindStandbyRP(t, dut, controllerCards) + rpStandby, rpActive := components.FindStandbyControllerCard(t, dut, controllerCards) t.Logf("Detected rpStandby: %v, rpActive: %v", rpStandby, rpActive) gnoiClient := dut.RawAPIs().GNOI(t) diff --git a/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go b/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go index 4ce309a06c4..d40c60d8f67 100644 --- a/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go +++ b/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go @@ -85,7 +85,7 @@ func TestSupervisorSwitchover(t *testing.T) { t.Skipf("Not enough controller cards for the test on %v: got %v, want at least %v", dut.Model(), got, want) } - rpStandbyBeforeSwitch, rpActiveBeforeSwitch := components.FindStandbyRP(t, dut, controllerCards) + rpStandbyBeforeSwitch, rpActiveBeforeSwitch := components.FindStandbyControllerCard(t, dut, controllerCards) t.Logf("Detected rpStandby: %v, rpActive: %v", rpStandbyBeforeSwitch, rpActiveBeforeSwitch) switchoverReady := gnmi.OC().Component(rpActiveBeforeSwitch).SwitchoverReady() @@ -150,7 +150,7 @@ func TestSupervisorSwitchover(t *testing.T) { } t.Logf("RP switchover time: %.2f seconds", time.Since(startSwitchover).Seconds()) - rpStandbyAfterSwitch, rpActiveAfterSwitch := components.FindStandbyRP(t, dut, controllerCards) + rpStandbyAfterSwitch, rpActiveAfterSwitch := components.FindStandbyControllerCard(t, dut, controllerCards) t.Logf("Found standbyRP after switchover: %v, activeRP: %v", rpStandbyAfterSwitch, rpActiveAfterSwitch) if got, want := rpActiveAfterSwitch, rpStandbyBeforeSwitch; got != want { diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/README.md b/feature/gribi/otg_tests/backup_nhg_action_pbf/README.md similarity index 100% rename from feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/README.md rename to feature/gribi/otg_tests/backup_nhg_action_pbf/README.md diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/backup_nhg_action_pbf_test.go b/feature/gribi/otg_tests/backup_nhg_action_pbf/backup_nhg_action_pbf_test.go similarity index 100% rename from feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/backup_nhg_action_pbf_test.go rename to feature/gribi/otg_tests/backup_nhg_action_pbf/backup_nhg_action_pbf_test.go diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto b/feature/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto similarity index 100% rename from feature/experimental/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto rename to feature/gribi/otg_tests/backup_nhg_action_pbf/metadata.textproto diff --git a/feature/experimental/gribi/otg_tests/dut_daemon_failure/README.md b/feature/gribi/otg_tests/dut_daemon_failure/README.md similarity index 100% rename from feature/experimental/gribi/otg_tests/dut_daemon_failure/README.md rename to feature/gribi/otg_tests/dut_daemon_failure/README.md diff --git a/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go b/feature/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go similarity index 100% rename from feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go rename to feature/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go diff --git a/feature/experimental/gribi/otg_tests/dut_daemon_failure/metadata.textproto b/feature/gribi/otg_tests/dut_daemon_failure/metadata.textproto similarity index 100% rename from feature/experimental/gribi/otg_tests/dut_daemon_failure/metadata.textproto rename to feature/gribi/otg_tests/dut_daemon_failure/metadata.textproto diff --git a/feature/gribi/otg_tests/encap_frr_with_reencap_vrf_test/encap_frr_with_reencap_vrf_test.go b/feature/gribi/otg_tests/encap_frr_with_reencap_vrf_test/encap_frr_with_reencap_vrf_test.go index fdd5e3329a7..8bcefca44bb 100644 --- a/feature/gribi/otg_tests/encap_frr_with_reencap_vrf_test/encap_frr_with_reencap_vrf_test.go +++ b/feature/gribi/otg_tests/encap_frr_with_reencap_vrf_test/encap_frr_with_reencap_vrf_test.go @@ -97,8 +97,12 @@ const ( ipv4OuterSrc222Addr = "198.51.100.222" gribiIPv4EntryVRF1111 = "203.0.113.1" gribiIPv4EntryVRF1112 = "203.0.113.2" + gribiIPv4EntryVRF1113 = "203.100.113.1" + gribiIPv4EntryVRF1114 = "203.100.113.2" gribiIPv4EntryVRF2221 = "203.0.113.100" gribiIPv4EntryVRF2222 = "203.0.113.101" + gribiIPv4EntryVRF2223 = "203.100.113.100" + gribiIPv4EntryVRF2224 = "203.100.113.101" gribiIPv4EntryEncapVRF = "138.0.11.0" dutAreaAddress = "49.0001" @@ -249,13 +253,6 @@ func dutInterface(p *ondatra.Port, dut *ondatra.DUTDevice) *oc.Interface { i.Enabled = ygot.Bool(true) } - if p.PMD() == ondatra.PMD100GBASEFR { - e := i.GetOrCreateEthernet() - e.AutoNegotiate = ygot.Bool(false) - e.DuplexMode = oc.Ethernet_DuplexMode_FULL - e.PortSpeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB - } - ipv4, ok := portsIPv4[id] if !ok { return nil @@ -1142,11 +1139,10 @@ func TestEncapFrr(t *testing.T) { args.client.Modify().AddEntry(t, fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithIndex(1300).WithDecapsulateHeader(fluent.IPinIP).WithEncapsulateHeader(fluent.IPinIP). - WithIPinIP(ipv4OuterSrc222Addr, gribiIPv4EntryVRF2221).WithNextHopNetworkInstance(niTEVRF222), + WithIPinIP(ipv4OuterSrc222Addr, gribiIPv4EntryVRF2223).WithNextHopNetworkInstance(niTEVRF222), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithIndex(1301).WithDecapsulateHeader(fluent.IPinIP).WithEncapsulateHeader(fluent.IPinIP). - WithIPinIP(ipv4OuterSrc222Addr, gribiIPv4EntryVRF2222).WithNextHopNetworkInstance(niTEVRF222), - + WithIPinIP(ipv4OuterSrc222Addr, gribiIPv4EntryVRF2224).WithNextHopNetworkInstance(niTEVRF222), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(1000).AddNextHop(1300, 1), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). @@ -1155,14 +1151,34 @@ func TestEncapFrr(t *testing.T) { if err := awaitTimeout(ctx, t, args.client, 2*time.Minute); err != nil { t.Logf("Could not program entries via client, got err, check error codes: %v", err) } + res := args.client.Results(t) + operIndexList := []uint64{1000, 1001} + for _, operIndex := range operIndexList { + chk.HasResult(t, res, + fluent.OperationResult(). + WithOperationType(constants.Add). + WithNextHopOperation(operIndex). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + chk.HasResult(t, res, + fluent.OperationResult(). + WithOperationType(constants.Add). + WithNextHopGroupOperation(operIndex). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + } } if tc.TestID == "teVrf111NoMatch" { args.client.Modify().AddEntry(t, fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(201).WithEncapsulateHeader(fluent.IPinIP).WithIPinIP(ipv4OuterSrc111Addr, "203.100.113.1"). + WithIndex(201).WithEncapsulateHeader(fluent.IPinIP).WithIPinIP(ipv4OuterSrc111Addr, gribiIPv4EntryVRF1113). WithNextHopNetworkInstance(niTEVRF111), fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). - WithIndex(202).WithEncapsulateHeader(fluent.IPinIP).WithIPinIP(ipv4OuterSrc111Addr, "203.100.113.2"). + WithIndex(202).WithEncapsulateHeader(fluent.IPinIP).WithIPinIP(ipv4OuterSrc111Addr, gribiIPv4EntryVRF1114). WithNextHopNetworkInstance(niTEVRF111), fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithID(101).AddNextHop(201, 1).AddNextHop(202, 3).WithBackupNHG(2001), @@ -1170,6 +1186,31 @@ func TestEncapFrr(t *testing.T) { if err := awaitTimeout(ctx, t, args.client, 2*time.Minute); err != nil { t.Logf("Could not program entries via client, got err, check error codes: %v", err) } + res := args.client.Results(t) + chk.HasResult(t, res, + fluent.OperationResult(). + WithOperationType(constants.Add). + WithNextHopOperation(201). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + chk.HasResult(t, res, + fluent.OperationResult(). + WithOperationType(constants.Add). + WithNextHopOperation(202). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + chk.HasResult(t, res, + fluent.OperationResult(). + WithOperationType(constants.Add). + WithNextHopGroupOperation(101). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) } captureState = startCapture(t, args, tc.CapturePortList) diff --git a/feature/experimental/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/README.md b/feature/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/README.md similarity index 100% rename from feature/experimental/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/README.md rename to feature/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/README.md diff --git a/feature/experimental/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/fib_failed_due_to_hw_res_exhaust_test.go b/feature/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/fib_failed_due_to_hw_res_exhaust_test.go similarity index 100% rename from feature/experimental/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/fib_failed_due_to_hw_res_exhaust_test.go rename to feature/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/fib_failed_due_to_hw_res_exhaust_test.go diff --git a/feature/experimental/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/metadata.textproto b/feature/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/metadata.textproto similarity index 100% rename from feature/experimental/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/metadata.textproto rename to feature/gribi/otg_tests/fib_failed_due_to_hw_res_exhaust_test/metadata.textproto diff --git a/feature/gribi/otg_tests/gribi_route_test/gribi_route_test.go b/feature/gribi/otg_tests/gribi_route_test/gribi_route_test.go index 2038b0e1899..194bcc77717 100644 --- a/feature/gribi/otg_tests/gribi_route_test/gribi_route_test.go +++ b/feature/gribi/otg_tests/gribi_route_test/gribi_route_test.go @@ -227,6 +227,7 @@ func TestGRIBIFailover(t *testing.T) { // configureDUT configures port1-3 on the DUT. func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + fptest.ConfigureDefaultNetworkInstance(t, dut) t.Logf("configureDUT") p1 := dut.Port(t, "port1") p2 := dut.Port(t, "port2") @@ -403,6 +404,7 @@ func configureGribiRoute(t *testing.T, dut *ondatra.DUTDevice) { client.Start(ctx, t) defer client.Stop(t) gribi.FlushAll(client) + defer gribi.FlushAll(client) client.StartSending(ctx, t) gribi.BecomeLeader(t, client) diff --git a/feature/gribi/otg_tests/gribi_scaling/metadata.textproto b/feature/gribi/otg_tests/gribi_scaling/metadata.textproto index 981e65d1ab9..393d30f1bd5 100644 --- a/feature/gribi/otg_tests/gribi_scaling/metadata.textproto +++ b/feature/gribi/otg_tests/gribi_scaling/metadata.textproto @@ -32,7 +32,6 @@ platform_exceptions: { } deviations: { no_mix_of_tagged_and_untagged_subinterfaces: true - explicit_interface_ref_definition: true } } platform_exceptions: { diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md index d2d65948ea1..026f4dd889f 100644 --- a/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/README.md @@ -141,3 +141,22 @@ rpcs: ## Minimum DUT platform requirement vRX + +## 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: N/A + + ## State paths: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight: + +rpcs: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` \ No newline at end of file diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto index 18b3f8b387b..cb1bef25af4 100644 --- a/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_pbf_test/metadata.textproto @@ -14,7 +14,7 @@ platform_exceptions: { ipv4_missing_enabled: true interface_ref_interface_id_format: true pf_require_match_default_rule: true - pf_require_sequential_order_pbr_rules: true + pf_require_sequential_order_pbr_rules: true } } platform_exceptions: { @@ -23,7 +23,6 @@ platform_exceptions: { } deviations: { hierarchical_weight_resolution_tolerance: 0.4 - explicit_interface_ref_definition: true } } platform_exceptions: { diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md index 63bfca04b3c..d206b7660d1 100644 --- a/feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/README.md @@ -142,3 +142,21 @@ rpcs: * vRX - virtual router device +## 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: N/A + + ## State paths: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight: + +rpcs: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` \ No newline at end of file diff --git a/feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto index a7f0ebfbfb0..fb0c549af67 100644 --- a/feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto +++ b/feature/gribi/otg_tests/hierarchical_weight_resolution_test/metadata.textproto @@ -21,7 +21,6 @@ platform_exceptions: { } deviations: { hierarchical_weight_resolution_tolerance: 0.4 - explicit_interface_ref_definition: true } } platform_exceptions: { diff --git a/feature/gribi/otg_tests/mpls_in_udp/README.md b/feature/gribi/otg_tests/mpls_in_udp/README.md index ad88513609d..fde748ddc4d 100644 --- a/feature/gribi/otg_tests/mpls_in_udp/README.md +++ b/feature/gribi/otg_tests/mpls_in_udp/README.md @@ -43,122 +43,72 @@ outer_ip-ttl = "64" #### gRIBI RPC content The gRIBI client should send this proto message to the DUT to create AFT -entries. See [OC AFT Encap PR in progress](https://github.com/openconfig/public/pull/1153) -for the new OC AFT model nodes needed for this. - -TODO: The -[gRIBI v1 protobuf defintions](https://github.com/openconfig/gribi/blob/master/v1/proto/README.md) -will be generated from the afts tree. +entries. ```proto -network_instances: { - network_instance: { - afts { - # - # entries used for "group_A" - ipv6_unicast { - ipv6_entry { - prefix: "inner_ipv6_dst_A" # this is an IPv6 entry for the origin/inner packet. - next_hop_group: 100 - } - } - ipv4_unicast { - ipv4_entry { - prefix: "ipv4_inner_dst_A" # this is an IPv4 entry for the origin/inner packet. - next_hop_group: 100 - } - } - next_hop_groups { - next_hop_group { - id: 100 - next_hops { # reference to a next-hop - next_hop: { - index: 100 - } - } - } - } - next_hops { - next_hop { - index: 100 - network_instance: "group_A" - encap-headers { - encap-header { - index: 1 - pushed_mpls_label_stack: [100,] - } - } - encap-headers { - encap-header { - index: 2 - src_ip: "outer_ipv6_src" - dst_ip: "outer_ipv6_dst_A" - dst_udp_port: "outer_dst_udp_port" - ip_ttl: "outer_ip-ttl" - dscp: "outer_dscp" - } - } - } - } - # - # entries used for "group_B" - ipv6_unicast { - ipv6_entry { - prefix: "inner_ipv6_dst_B" - next_hop_group: 200 - } +# +# aft entries used for network instance "NI_A" +IPv6Entry {2001:DB8:2::2/128 (NI_A)} -> NHG#100 (DEFAULT VRF) +IPv4Entry {203.0.113.2/32 (NI_A)} -> NHG#100 (DEFAULT VRF) -> { + {NH#101, DEFAULT VRF} +} + +# this nexthop specifies a MPLS in UDP encapsulation +NH#101 -> { + encap_-_headers { + encap_header { + index: 1 + mpls { + pushed_mpls_label_stack: [101,] } - ipv4_unicast { - ipv4_entry { - prefix: "ipv4_inner_dst_B" - next_hop_group: 200 - } + } + encap_header { + index: 2 + udp_v6 { + src_ip: "outer_ipv6_src" + dst_ip: "outer_ipv6_dst_A" + dst_udp_port: "outer_dst_udp_port" + ip_ttl: "outer_ip-ttl" + dscp: "outer_dscp" } - next_hop_groups { - next_hop_group { - id: 200 - next_hops { # reference to a next-hop - next_hop: { - index: 200 - } - } - } + } + } + next_hop_group_id: "nhg_A" # new OC path /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/ + network_instance: "DEFAULT" +} + +# +# entries used for network-instance "NI_B" +IPv6Entry {2001:DB8:2::2/128 (NI_B)} -> NHG#200 (DEFAULT VRF) +IPv4Entry {203.0.113.2/32 (NI_B)} -> NHG#200 (DEFAULT VRF) -> { + {NH#201, DEFAULT VRF} +} + +NH#201 -> { + encap_headers { + encap_header { + index: 1 + mpls { + pushed_mpls_label_stack: [201,] } - next_hops { - next_hop { - index: 200 - network_instance: "group_B" - encap-headers { - encap-header { - index: 1 - type : OPENCONFIG_AFT_TYPES:MPLS - mpls { - pushed_mpls_label_stack: [200,] - } - } - } - encap-headers { - encap-header { - index: 2 - type: OPENCONFIG_AFT_TYPES:UDP - udp { - src_ip: "outer_ipv6_src" - dst_ip: "outer_ipv6_dst_B" - dst_udp_port: "outer_dst_udp_port" - ip_ttl: "outer_ip-ttl" - dscp: "outer_dscp" - } - } - } - } + } + encap_header { + index: 2 + udp_v6 { + src_ip: "outer_ipv6_src" + dst_ip: "outer_ipv6_dst_B" + dst_udp_port: "outer_dst_udp_port" + ip_ttl: "outer_ip-ttl" + dscp: "outer_dscp" } } } + next_hop_group_id: "nhg_B" + # network_instance: "DEFAULT" TODO: requires new OC path /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/network-instance } ``` * Send traffic from ATE port 1 to DUT port 1 -* Validate afts next hop counters * Using OTG, validate ATE port 2 receives MPLS-IN-UDP packets * Validate destination IPs are outer_ipv6_dst_A and outer_ipv6_dst_B * Validate MPLS label is set @@ -168,36 +118,66 @@ network_instances: { Canonical OpenConfig for policy forwarding, matching IP prefix with action encapsulate in GRE. -```yaml -openconfig-network-instance: - network-instances: - - network-instance: "group_A" - afts: - policy-forwarding: - policies: - policy: "default encap rule" - config: - policy-id: "default encap rule" - type: PBR_POLICY - rules: - rule: 1 - config: - sequence-id: 1 - ipv6: - config: - destination-address: "inner_ipv6_default" - action: - encapsulate-mpls-in-gre: # TODO: add to OC model/PR in progress - targets: - target: "default_dst_1" - config: - id: "default_dst_1" - network-instance: "DEFAULT" - source-ip: "outer_ipv6_src" - destination-ip: "outer_ipv6_dst_def" - ip-ttl: outer_ip-ttl - dscp: outer_dscp - inner-ttl-min: 2 +```json +{ + "openconfig-network-instance": { + "network-instances": [ + { + "afts": { + "policy-forwarding": { + "policies": [ + { + "config": { + "policy-id": "default encap rule", + "type": "PBR_POLICY" + }, + "policy": "default encap rule", + "rules": [ + { + "action": { + "encapsulate-headers": [ + { + "encapsulate-header": null, + "gre": { + "config": { + "destination-ip": "outer_ipv6_dst_def", + "dscp": "outer_dscp", + "id": "default_dst_1", + "ip-ttl": "outer_ip-ttl", + "source-ip": "outer_ipv6_src" + } + }, + "mpls": { + "mpls-label-stack": [ + 100 + ] + } + } + ], + "config": { + "network-instance": "DEFAULT" + } + }, + "config": { + "sequence-id": 1, + }, + "ipv6": { + "config": { + "destination-address": "inner_ipv6_default" + } + }, + "rule": 1 + } + ] + } + ] + } + }, + "network-instance": "group_A" + } + ] + } +} ``` * Generate the policy forwarding configuration @@ -263,7 +243,7 @@ openconfig-network-instance: config: destination-address: "decap_loopback_ipv6" action: - decapsulate-mpls-in-udp: TRUE + decapsulate-mpls-in-udp: TRUE ``` * Push the gNMI the policy forwarding configuration @@ -284,25 +264,47 @@ and forwarding to a specified destination using OC policy-forwarding terms. paths: # afts state paths set via gRIBI - # TODO: https://github.com/openconfig/public/pull/1153 - - #/network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/id: - #/network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/next-hop-group-id: - #/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/network-instance: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/index: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/type: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/mpls/pushed-mpls-label-stack: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/udp/src-ip: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/udp/dst-ip: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/udp/dst-udp-port: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/udp/ip-ttl: - #/network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/udp/dscp: - -# afts next-hop counters - /network-instances/network-instance/afts/next-hops/next-hop/state/counters/packets-forwarded: - /network-instances/network-instance/afts/next-hops/next-hop/state/counters/octets-forwarded: - + # TODO: need new OC for user defined next-hop-group/state/id, needed for policy-forwarding rules pointing to a NHG + # /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/next-hop-group-id: + + # TODO: new OC path for aft NHG pointing to a different network-instance + # /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/network-instance: + + # Paths added for TE-18.1.1 Match and Encapsulate using gRIBI aft modify + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/id: + /network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/index: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/index: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/state/type: + + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/mpls/state/mpls-label-stack: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v4/state/src-ip: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v4/state/dst-ip: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v4/state/dst-udp-port: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v4/state/ip-ttl: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v4/state/dscp: + + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v6/state/src-ip: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v6/state/dst-ip: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v6/state/dst-udp-port: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v6/state/ip-ttl: + /network-instances/network-instance/afts/next-hops/next-hop/encap-headers/encap-header/udp-v6/state/dscp: + + # Paths added for TE-18.1.2 Validate prefix match rule for MPLS in GRE encap using default route + /network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/config/network-instance: + /network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/config/sequence-id: + #/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/encap-headers/encap-header/mpls/config/mpls-label-stack: + #/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/encap-headers/encap-header/gre/config/destination-ip: + #/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/encap-headers/encap-header/gre/config/dscp: + #/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/encap-headers/encap-header/gre/config/id: + #/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/encap-headers/encap-header/gre/config/ip-ttl: + #/network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/encap-headers/encap-header/gre/config/source-ip: + + # Paths added for TE-18.1.3 - MPLS in GRE decapsulation set by gNMI + /network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/config/destination-address: + # TODO: /network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/config/decapsulate-mpls-in-gre: + + # Paths added for TE-18.1.4 - MPLS in UDP decapsulation set by gNMI + /network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/config/decapsulate-mpls-in-udp: rpcs: gnmi: @@ -313,9 +315,8 @@ rpcs: on_change: true gribi: gRIBI.Modify: - network-instances:network-instance:afts:next-hops:next-hop:encapsulate_header: - network-instances:network-instance:afts:next-hops:next-hop:mpls-in-udp: - network-instances:network-instance:afts:next-hops:next-hop:decapsulate_header: + afts:next-hops:next-hop:encap-headers:encap-header:udp_v6: + afts:next-hops:next-hop:encap-headers:encap-header:mpls: gRIBI.Flush: ``` diff --git a/feature/gribi/otg_tests/mpls_in_udp_scale/README.md b/feature/gribi/otg_tests/mpls_in_udp_scale/README.md new file mode 100644 index 00000000000..e2f42b8c481 --- /dev/null +++ b/feature/gribi/otg_tests/mpls_in_udp_scale/README.md @@ -0,0 +1,145 @@ +# TE-18.3 MPLS in UDP Encapsulation with QoS Scheduler Scale Test + +Building on TE-18.1 and TE-18.2, add scaling parameters + +## Topology + +* 32 ports as the 'input port set' +* 4 ports as "uplink facing" +* VLAN configurations + * input vlans are distributed evenly across the 'input port set' + +## Test setup + +TODO: Complete test environment setup steps + +inner_ipv6_dst_A = "2001:aa:bb::1/128" +inner_ipv6_dst_B = "2001:aa:bb::2/128" +inner_ipv6_default = "::/0" + +ipv4_inner_dst_A = "10.5.1.1/32" +ipv4_inner_dst_B = "10.5.1.2/32" +ipv4_inner_default = "0.0.0.0/0" + +outer_ipv6_src = "2001:f:a:1::0" +outer_ipv6_dst_A = "2001:f:c:e::1" +outer_ipv6_dst_B = "2001:f:c:e::2" +outer_ipv6_dst_def = "2001:1:1:1::0" +outer_dst_udp_port = "5555" +outer_dscp = "26" +outer_ip-ttl = "64" + +## Procedure + +### TE-18.3.1 Scale + +#### Scale targets + +* Flow scale + * 20,000 IPv4/IPv6 destinations + * 1,000 vlans + * Inner IP address space should be reused for each network-instance. + * gRIBI client update rate `flow_r` = 1 update per second + * Each gRIBI update include ip entries in batches of `flow_q` = 200 + * DUT packet forwarding updated within 1 second after adding entries + +* Scheduler (policer) scale + * 1,000 policer rates + * 20,000 policer-policies / token buckets instantiations + * Update policer-policies at 1 per `sched_r` = 60 seconds + * Update policer-policies in a batch of `sched_q` = 1,000 + * Policer-policies changes should take effect within `sched_r` / 2 time + +#### Scale profile A - many vlans + +* 20 ip destinations * 1,000 vlans = 20,000 'flows' +* Each ingress vlan has 20 policer-policies = 10,000 'token buckets' +* The 20 ip destinations are split evenly between the 20 policers +* Each policer is assigned rate limits matching one of 800 different possible limits between 1Gbps to 400Gbps in 0.5Gbps increments + +#### Scale profile B - many destinations, few vlans + +* 200 ip destinations * 100 vlans = 20,000 'flows' +* Each ingress vlan has 4 policer-policies = 4,000 'token buckets' +* The 200 ip destinations are split evenly between the 4 policers +* Each policer is assigned rate limits matching one of 800 different possible limits between 1Gbps to 400Gbps in 0.5Gbps increments + +#### Procedure - Flow Scale + +* For each scale profile, create the following subsets TE-18.1.5.n + * Configure ATE flows to send 100 pps per flow and wait for ARP + * Send traffic for q flows (destination IP prefixes) for 2 seconds + * At traffic start time, gRIBI client to send `flow_q` aft entries and their + related NHG and NH at rate `flow_r` + * Validate RIB_AND_FIB_ACK with FIB_PROGRAMMED is received from DUT within + 1 second + * Measure packet loss. Target packet loss <= 50%. + * Repeat adding 200 flows until 20,000 flows have been added + * Once reaching 20,000 flows, perform 1 iteration of modifying the first + `flow_q` flows to use different NH,NHG + +#### Procedure - Policer + Flow Scale + +* For each scale profile, create the following subsets TE-18.1.6.n + * Program all 20,000 flows + * Every `sched_r` interval use gnmi.Set to replace `sched_q` scheduler policies + * Verify packet loss changes for all flows within `sched_r` / 2 time + +#### OpenConfig Path and RPC Coverage + +```yaml +paths: + # qos scheduler config + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/config/cir: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/config/bc: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/config/queuing-behavior: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/exceed-action/config/drop: + + # qos classifier config + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/terms/term/config/id: + #/qos/classifiers/classifier/terms/term/conditions/next-hop-group/config/name: # TODO: new OC leaf to be added + + # qos input-policies config - TODO: a new OC subtree (/qos/input-policies) + # /qos/input-policies/input-policy/config/name: + # /qos/input-policies/input-policy/config/classifier: + # /qos/input-policies/input-policy/config/scheduler-policy: + + # qos interface config + #/qos/interfaces/interface/subinterface/input/config/policies: # TODO: new OC leaf-list (/qos/interfaces/interface/input/config/policies) + + # qos interface scheduler counters + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/conforming-pkts: + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/conforming-octets: + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/exceeding-pkts: + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/exceeding-octets: + + # afts next-hop counters + /network-instances/network-instance/afts/next-hops/next-hop/state/counters/packets-forwarded: + /network-instances/network-instance/afts/next-hops/next-hop/state/counters/octets-forwarded: + + # afts state paths set via gRIBI + # TODO: https://github.com/openconfig/public/pull/1153 + #/network-instances/network-instance/afts/next-hops/next-hop/mpls-in-udp/state/src-ip: + #/network-instances/network-instance/afts/next-hops/next-hop/mpls-in-udp/state/dst-ip: + #/network-instances/network-instance/afts/next-hops/next-hop/mpls-in-udp/state/ip-ttl: + #/network-instances/network-instance/afts/next-hops/next-hop/mpls-in-udp/state/dst-udp-port: + #/network-instances/network-instance/afts/next-hops/next-hop/mpls-in-udp/state/dscp: + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + replace: true + gNMI.Subscribe: + on_change: true + gribi: + gRIBI.Modify: + gRIBI.Flush: +``` + +## Required DUT platform + +* FFF diff --git a/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/README.md b/feature/gribi/otg_tests/route_addition_during_failover_test/README.md similarity index 100% rename from feature/experimental/gribi/otg_tests/route_addition_during_failover_test/README.md rename to feature/gribi/otg_tests/route_addition_during_failover_test/README.md diff --git a/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/metadata.textproto b/feature/gribi/otg_tests/route_addition_during_failover_test/metadata.textproto similarity index 100% rename from feature/experimental/gribi/otg_tests/route_addition_during_failover_test/metadata.textproto rename to feature/gribi/otg_tests/route_addition_during_failover_test/metadata.textproto diff --git a/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go b/feature/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go similarity index 100% rename from feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go rename to feature/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go diff --git a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/README.md b/feature/gribi/otg_tests/route_removal_during_failover_test/README.md similarity index 100% rename from feature/experimental/gribi/otg_tests/route_removal_during_failover_test/README.md rename to feature/gribi/otg_tests/route_removal_during_failover_test/README.md diff --git a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/metadata.textproto b/feature/gribi/otg_tests/route_removal_during_failover_test/metadata.textproto similarity index 100% rename from feature/experimental/gribi/otg_tests/route_removal_during_failover_test/metadata.textproto rename to feature/gribi/otg_tests/route_removal_during_failover_test/metadata.textproto diff --git a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go similarity index 100% rename from feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go rename to feature/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/README.md b/feature/gribi/otg_tests/vrf_policy_driven_te/README.md similarity index 100% rename from feature/experimental/gribi/otg_tests/vrf_policy_driven_te/README.md rename to feature/gribi/otg_tests/vrf_policy_driven_te/README.md diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto b/feature/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto similarity index 100% rename from feature/experimental/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto rename to feature/gribi/otg_tests/vrf_policy_driven_te/metadata.textproto diff --git a/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go b/feature/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go similarity index 100% rename from feature/experimental/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go rename to feature/gribi/otg_tests/vrf_policy_driven_te/vrf_policy_driven_te_test.go diff --git a/feature/gribi/vrf_policy_driven_te/README.md b/feature/gribi/vrf_policy_driven_te/README.md deleted file mode 100644 index 41630244a0d..00000000000 --- a/feature/gribi/vrf_policy_driven_te/README.md +++ /dev/null @@ -1,819 +0,0 @@ -# TE-17.1 VRF selection policy driven TE - -## Summary - -Test VRF selection logic involving different decapsulation and encapsulation lookup scenarios via gRIBI. - -## Topology - -ATE port-1 <------> port-1 DUT -DUT port-2 <------> port-2 ATE -DUT port-3 <------> port-3 ATE -DUT port-4 <------> port-4 ATE -DUT port-5 <------> port-5 ATE -DUT port-6 <------> port-6 ATE -DUT port-7 <------> port-7 ATE -DUT port-8 <------> port-8 ATE - -## Variables - -``` -# DSCP value that will be matched to ENCAP_TE_VRF_A -* dscp_encap_a_1 = 10 -* dscp_encap_a_2 = 18 - -# DSCP value that will be matched to ENCAP_TE_VRF_B -* dscp_encap_b_1 = 20 -* dscp_encap_b_2 = 28 - -# DSCP value that will NOT be matched to any VRF for encapsulation. -* dscp_encap_no_match = 30 - -# Magic source IP addresses used in VRF selection policy -* ipv4_outer_src_111 = 198.51.100.111 -* ipv4_outer_src_222 = 198.51.100.222 - -# Magic destination MAC address -* magic_mac = 02:00:00:00:00:01` -``` - -vrf_selection_policy_c -``` -network-instances { - network-instance { - name: DEFAULT - policy-forwarding { - policies { - policy { - policy-id: "vrf_selection_policy_c" - rules { - rule { - sequence-id: 1 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 2 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 3 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 4 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 5 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 6 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 7 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 8 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 9 - ipv4 { - protocol: 4 - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 10 - ipv4 { - protocol: 41 - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 11 - ipv4 { - protocol: 4 - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 12 - ipv4 { - protocol: 41 - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 13 - ipv4 { - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - } - action { - network-instance: "ENCAP_TE_VRF_A" - } - } - rule { - sequence-id: 14 - ipv6 { - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - } - action { - network-instance: "ENCAP_TE_VRF_A" - } - } - rule { - sequence-id: 15 - ipv4 { - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - } - action { - network-instance: "ENCAP_TE_VRF_B" - } - } - rule { - sequence-id: 16 - ipv6 { - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - } - action { - network-instance: "ENCAP_TE_VRF_B" - } - } - rule { - sequence-id: 17 - action { - network-instance: "DEFAULT" - } - } - } - } - } - } - } -} -``` - -vrf_selection_policy_w -``` -network-instances { - network-instance { - name: DEFAULT - policy-forwarding { - policies { - policy { - policy-id: "vrf_selection_policy_w" - rules { - rule { - sequence-id: 1 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 2 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 3 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 4 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_a_1, dscp_encap_a_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_A" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 5 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 6 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 7 - ipv4 { - protocol: 4 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 8 - ipv4 { - protocol: 41 - dscp-set: [dscp_encap_b_1, dscp_encap_b_2] - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "ENCAP_TE_VRF_B" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 9 - ipv4 { - protocol: 4 - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 10 - ipv4 { - protocol: 41 - source-address: "ipv4_outer_src_222" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_222" - } - } - rule { - sequence-id: 11 - ipv4 { - protocol: 4 - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 12 - ipv4 { - protocol: 41 - source-address: "ipv4_outer_src_111" - } - action { - decap-network-instance: "DECAP_TE_VRF" - post-network-instance: "DEFAULT" - decap-fallback-network-instance: "TE_VRF_111" - } - } - rule { - sequence-id: 13 - action { - network-instance: "DEFAULT" - } - } - } - } - } - } - } -} -``` - -## Baseline - -* Install the following gRIBI AFTs. - -``` -IPv4Entry {138.0.11.0/24 (ENCAP_TE_VRF_A)} -> NHG#101 (DEFAULT VRF) -> { - {NH#101, DEFAULT VRF, weight:1}, - {NH#102, DEFAULT VRF, weight:3}, - backup_next_hop_group: 200 // in case specific vendor implementation or bugs pruned the NHs. -} -IPv4Entry {138.0.11.0/24 (ENCAP_TE_VRF_B)} -> NHG#102 (DEFAULT VRF) -> { - {NH#101, DEFAULT VRF, weight:3}, - {NH#102, DEFAULT VRF, weight:1}, - backup_next_hop_group: 200 // in case specific vendor implementation or bugs pruned the NHs. -} -NH#101 -> { - encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 - ip_in_ip { - dst_ip: "203.0.113.1" - src_ip: "ipv4_outer_src_111" - } - network_instance: "TE_VRF_111" -} -NH#102 -> { - encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 - ip_in_ip { - dst_ip: "203.10.113.2" - src_ip: "ipv4_outer_src_111" - } - network_instance: "TE_VRF_111" -} - -NHG#200 (Default VRF) { - {NH#200, DEFAULT VRF, weight:1} -} -NH#200 -> { - network_instance: "DEFAULT" -} - -IPv4Entry {203.0.113.1/32 (TE_VRF_111)} -> NHG#1 (DEFAULT VRF) -> { - {NH#1, DEFAULT VRF, weight:1,ip_address=192.0.2.101}, - {NH#2, DEFAULT VRF, weight:3,ip_address=192.0.2.102}, - backup_next_hop_group: 1000 // re-encap to 203.0.113.100 -} -IPv4Entry {192.0.2.101/32 (DEFAULT VRF)} -> NHG#11 (DEFAULT VRF) -> { - {NH#11, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-2-interface}, - {NH#12, DEFAULT VRF, weight:3,mac_address:magic_mac, interface-ref:dut-port-3-interface}, -} -IPv4Entry {192.0.2.102/32 (DEFAUlT VRF)} -> NHG#12 (DEFAULT VRF) -> { - {NH#13, DEFAULT VRF, weight:2,mac_address:magic_mac, interface-ref:dut-port-4-interface}, -} - -NHG#1000 (Default VRF) { - {NH#1000, DEFAULT VRF} -} -NH#1000 -> { - decapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 - encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 - ip_in_ip { - dst_ip: "203.0.113.100" - src_ip: "ipv4_outer_src_222" - } - network_instance: "TE_VRF_222" -} - -IPv4Entry {203.0.113.100/32 (TE_VRF_222)} -> NHG#2 (DEFAULT VRF) -> { - {NH#3, DEFAULT VRF, weight:1,ip_address=192.0.2.103}, - backup_next_hop_group: 1001 // decap to DEFAULT VRF -} -IPv4Entry {192.0.2.103/32 (DEFAULT VRF)} -> NHG#13 (DEFAULT VRF) -> { - {NH#14, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-5-interface}, -} -NHG#1001 (Default VRF) { - {NH#2001, DEFAULT VRF, weight:1} -} -NH#1001 -> { - decapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 - network_instance: "DEFAULT" -} - -// 203.10.113.2 is the tunnel IP address. Note that the NHG#3 is different than NHG#1. - -IPv4Entry {203.10.113.2/32 (TE_VRF_111)} -> NHG#3 (DEFAULT VRF) -> { - {NH#4, DEFAULT VRF, weight:1,ip_address=192.0.2.104}, - backup_next_hop_group: 1002 // re-encap to 203.10.113.101 -} -IPv4Entry {192.0.2.104/32 (DEFAULT VRF)} -> NHG#14 (DEFAULT VRF) -> { - {NH#15, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-6-interface}, -} -NHG#1002 (DEFAULT VRF) { - {NH#1002, DEFAULT VRF} -} -NH#1002 -> { - decapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 - encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 - ip_in_ip { - dst_ip: "203.0.113.101" - src_ip: "ipv4_outer_src_222" - } - network_instance: "TE_VRF_222" -} -IPv4Entry {203.0.113.101/32 (TE_VRF_222)} -> NHG#4 (DEFAULT VRF) -> { - {NH#5, DEFAULT VRF, weight:1,ip_address=192.0.2.103}, - backup_next_hop_group: 1001 // decap to DEFAULT VRF -} -IPv4Entry {192.0.2.103/32 (DEFAULT VRF)} -> NHG#15 (DEFAULT VRF) -> { - {NH#16, DEFAULT VRF, weight:1,mac_address:magic_mac, interface-ref:dut-port-7-interface}, -} - -``` - -* Install a BGP route resolved by ISIS in default VRF to rout traffic out of DUT port-8. - -* Install an 0/0 static route in ENCAP_VRF_A and ENCAP_VRF_B pointing to the DEFAULT VRF. - -## Procedure - -The DUT should be reset to the baseline after each of the following tests. - -#### Test-1, match on source and protocol, no match on DSCP; flow VRF_DECAP hit -> DEFAULT - -1. Using gRIBI to install the following entries in the `DECAP_TE_VRF`: - - ``` - IPv4Entry {192.51.100.1/24 (DECAP_TE_VRF)} -> NHG#1001 (DEFAULT VRF) -> { - {NH#1001, DEFAULT VRF, weight:1} - } - NH#1001 -> { - decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 - } - ``` - -2. Apply vrf selection policy `vrf_selection_policy_w` to DUT port-1. - -3. Send the following 6in4 and 4in4 flows to DUT port-1: - - ``` - * inner_src: `ipv4_inner_src` - * inner_dst: `ipv4_inner_encap_match` - * dscp: `dscp_encap_no_match` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_no_match` - * proto: `4` - - * inner_src: `ipv6_inner_src` - * inner_dst: `ipv6_inner_encap_match` - * dscp: `dscp_encap_no_match` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_no_match` - * proto: `41` - ``` - -4. Verify that the packets have their outer v4 header stripped and are forwarded out of DUT port-8 per the BGP-ISIS routes in the DEFAULT VRF. - -5. Verify that the TTL value is copied from the outer header to the inner header. - -6. Change the subnet mask from /24 and repeat the test for the masks /32, /22, and /28 and verify again that the packets are decapped and forwarded correctly. - -7. Repeat the test with packets with a destination address that does not match the decap entry, and verify that such packets are not decapped. - -#### Test-2, match on source, protocol and DSCP, VRF_DECAP hit -> VRF_ENCAP_A miss -> DEFAULT - -1. Using gRIBI to install the following entries in the `DECAP_TE_VRF`: - - ``` - IPv4Entry {192.51.100.1/24 (DECAP_TE_VRF)} -> NHG#1001 (DEFAULT VRF) -> { - {NH#1001, DEFAULT VRF, weight:1} - } - NH#1001 -> { - decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 - } - ``` - -2. Apply vrf selection policy `vrf_selection_policy_w` to DUT port-1. - -3. Send the following 6in4 and 4in4 flows to DUT port-1: - - ``` - * inner_src: `ipv4_inner_src` - * inner_dst: `ipv4_inner_encap_no_match` - * dscp: `dscp_encap_a_1` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_a_1` - * proto: `4` - - * inner_src: `ipv6_inner_src` - * inner_dst: `ipv6_inner_encap_no_match` - * dscp: `dscp_encap_a_1` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_a_1` - * proto: `41` - ``` - -4. Verify that the packets have their outer v4 header stripped and are forwarded out of DUT port-8 per the BGP-ISIS routes in the DEFAULT VRF. - -5. Verify that the TTL value is copied from the outer header to the inner header. - -6. Change the subnet mask from /24 and repeat the test for the masks /32, /22, and /28 and verify again that the packets are decapped and forwarded correctly. - -#### Test-3, Mixed Prefix Decap gRIBI Entries - -Support for decap actions with mixed prefixes installed through gRIBI - -1. Add the following gRIBI entries: - - ``` - IPv4Entry {192.51.129.0/22 (DECAP_TE_VRF)} -> NHG#1001 (DEFAULT VRF) -> { - {NH#1001, DEFAULT VRF, weight:1} - } - IPv4Entry {192.55.200.3/32 (DECAP_TE_VRF)} -> NHG#1001 (DEFAULT VRF) -> { - {NH#1001, DEFAULT VRF, weight:1} - } - - NH#1001 -> { - decapsulate_header: OPENCONFIGAFTTYPESDECAPSULATIONHEADERTYPE_IPV4 - } - ``` - -2. Apply vrf selection policy `vrf_selection_policy_w` to DUT port-1. - -3. Send the following 6in4 and 4in4 flows to DUT port-1: - - ``` - * inner_src: `ipv4_inner_src` - * inner_dst: `ipv4_inner_encap_match` - * dscp: `dscp_encap_no_match` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `192.51.100.64` - * dscp: `dscp_encap_no_match` - * proto: `4` - - * inner_src: `ipv6_inner_src` - * inner_dst: `ipv6_inner_encap_match` - * dscp: `dscp_encap_no_match` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `192.55.200.3` - * dscp: `dscp_encap_no_match` - * proto: `41` - - * inner_src: `ipv4_inner_src` - * inner_dst: `ipv4_inner_encap_match` - * dscp: `dscp_encap_no_match` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `192.51.128.5` - * dscp: `dscp_encap_no_match` - * proto: `4` - ``` - -4. Verify that the packets have their outer v4 header stripped, and are forwarded according to the route in the DEFAULT VRF that matches the inner IP address. - -5. Repeat the test with packets with a destination address such as that does not match the decap route, and verify that such packets are not decapped. - -#### Test-4: Tunneled traffic with no decap - -Ensures that tunneled traffic is correctly forwarded when there is no match in the DECAP_VRF. The intent of this test is to ensure that the VRF selection policy correctly sends these packets to either `TE_VRF_111` or `TE_VRF_222`. - -1. Apply vrf selection policy `vrf_selection_policy_c` to DUT port-1. -2. Send 4in4 (IP protocol 4) and 6in4 (IP protocol 41) packets to DUT port-1 where - * The outer v4 header has the destination address 203.0.113.1. - * The outer v4 header has the source address ipv4_outer_src_111. - * The outer v4 header has DSCP value has `dscp_encap_no_match` and `dscp_encap_match` -3. We should expect that all egress packets (100%) are IPinIP encapped with 203.0.113.1 as the outer header, and egress on DUT port-2, port-3, port-4 and port-6 per the hierarchical weight. -4. Send 4in4 (IP protocol 4) and 6in4 (IP protocol 41) packets to DUT port-2 where - * The outer v4 header has the destination address 203.0.113.100. - * The outer v4 header has the source address ipv4_outer_src_222. - * The outer v4 header has DSCP value has `dscp_encap_no_match` and `dscp_encap_match` -We should expect that the egress traffic are 100% encapped with 203.0.113.100 as the outer header, and egress on DUT port-5. - -#### Test-5: match on "default term", send to default VRF - -Tests support for TE disabled IPinIP IPv4 (IP protocol 4) cluster traffic arriving on WAN facing ports. Specifically, this test verifies the tunnel traffic identification using ipv4_outer_src_111 and ipv4_outer_src_222 in the VRF selection policy. - -1. Apply vrf selection policy `vrf_selection_policy_w` to DUT port-1. -2. Send 6in4 and 4in4 packets to DUT port-1, where: - * The outer v4 header has the destination address 138.0.11.8. - * The outer v4 header has the source address that’s not ipv4_outer_src_111 or ipv4_outer_src_222. For example, we can use 198.100.200.123. -3. We should expect that all egress packets: - * 100% are still IPinIP (4in4) with outer v4 destination address as `138.0.11.8`. - * and, egressed out of DUT port-8 per the route in the DEFAULT VRF. -4. Send v4 packet with protocol `17` (not 6in4 or 4in4), where: - * The outer v4 header has the destination address 138.0.11.8. - * 50% of the packets with source address as ipv4_outer_src_111. - * 50% of the packets with source address as ipv4_outer_src_222. -5. We should expect that all egress packets: - * 100% are still of protocl `17` and with outer v4 destination address as `138.0.11.8`. - * and, egressed out of DUT port-8 per the route in the DEFAULT VRF. -6. Remove the matching route (e.g. stop the BGP routes) in the DEFAULT VRF and verify that the traffic are dropped. - -#### Test-6, decap then encap - -1. Apply vrf selection policy `vrf_selection_policy_w` to DUT port-1. - -2. Send the following packets to DUT port-1: - - ``` - * inner_src: `ipv4_inner_src` - * inner_dst: `ipv4_inner_encap_match` - * dscp: `dscp_encap_a_1` - * outter_src: `ipv4_outter_src_222` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_a_1` - * proto: `4` - ``` - - ``` - * inner_src: `ipv6_inner_src` - * inner_dst: `ipv6_inner_encap_match` - * dscp: `dscp_encap_a_1` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_a_1` - * proto: `41` - ``` - -3. We should expect that all egress packets: - - * are IPinIP encapped with outer source IP as `ipv4_outter_src_111` and dscp value `dscp_encap_a_1`. - * 1/4 are with 203.0.113.1 as the outer header destination IP. - * 3/4 are with 203.10.113.2 as the outer header destination IPs. - * egress on DUT port-2, port-3, port-4 and port-6 per the hierarchical weight. - -4. Send the following packets to DUT port -1 - - ``` - * inner_src: `ipv4_inner_src` - * inner_dst: `ipv4_inner_encap_match` - * dscp: `dscp_encap_b_1` - * outter_src: `ipv4_outter_src_111` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_b_1` - * proto: `4` - - * inner_src: `ipv6_inner_src` - * inner_dst: `ipv6_inner_encap_match` - * dscp: `dscp_encap_b_1` - * outter_src: `ipv4_outter_src_222` - * outter_dst: `ipv4_outter_decap_match` - * dscp: `dscp_encap_b_1` - * proto: `41` - ``` - -5. We should expect that all egress packets: - - * are IPinIP encapped with outer source IP as `ipv4_outter_src_111` and dscp value `dscp_encap_b_1`. - * 3/4 are with 203.0.113.1 as the outer header destination IP. - * 1/4 are with 203.10.113.2 as the outer header destination IPs. - * egress on DUT port-2, port-3, port-4 and port-6 per the hierarchical weight. - - -## Config Parameter Coverage - -* network-instances/network-instance/name -* network-instances/network-instance/policy-forwarding/policies/policy/policy-id -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/sequence-id -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/protocol -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/dscp-set -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/source-address -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/protocol -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/dscp-set -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/source-address -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-network-instance -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/post-network-instance -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-fallback-network-instance - -## Telemetry Parameter Coverage - -* network-instances/network-instance/name -* network-instances/network-instance/policy-forwarding/policies/policy/policy-id -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/sequence-id -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/protocol -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/dscp-set -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/source-address -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/protocol -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/dscp-set -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/source-address -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-network-instance -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/post-network-instance -* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/decap-fallback-network-instance - -## Protocol/RPC Parameter Coverage - -* gRIBI: - * Modify - * ModifyRequest - -## Required DUT platform - -vRX \ No newline at end of file diff --git a/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go b/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go index afbb72322b5..3e6a376eb05 100644 --- a/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go +++ b/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go @@ -552,6 +552,7 @@ func (tc *testArgs) testAggregateForwardingFlow(t *testing.T, forwardingViable b tc.ate.OTG().PushConfig(t, tc.top) tc.ate.OTG().StartProtocols(t) + otgutils.WaitForARP(t, tc.ate.OTG(), tc.top, "IPv4") beforeTrafficCounters := tc.getCounters(t, "before") tc.ate.OTG().StartTraffic(t) diff --git a/feature/interface/aggregate/otg_tests/balancing_test/README.md b/feature/interface/aggregate/otg_tests/balancing_test/README.md index aceda7e25b6..d09453272e8 100644 --- a/feature/interface/aggregate/otg_tests/balancing_test/README.md +++ b/feature/interface/aggregate/otg_tests/balancing_test/README.md @@ -41,3 +41,26 @@ None ## Minimum DUT platform requirement vRX + +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths and RPC intended to be covered by this test. + +```yaml +paths: + /interfaces/interface/ethernet/config/aggregate-id: + /interfaces/interface/aggregation/config/lag-type: + /lacp/config/system-priority: + /lacp/interfaces/interface/config/name: + /lacp/interfaces/interface/config/interval: + /lacp/interfaces/interface/config/lacp-mode: + /lacp/interfaces/interface/config/system-id-mac: + /lacp/interfaces/interface/config/system-priority: + +rpcs: + gnmi: + gNMI.Set: + union_replace: false + gNMI.Subscribe: + on_change: false +``` diff --git a/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go b/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go index 07b576adf29..3ea546dc932 100644 --- a/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go +++ b/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go @@ -76,6 +76,8 @@ const ( opUp = oc.Interface_OperStatus_UP ethernetCsmacd = oc.IETFInterfaces_InterfaceType_ethernetCsmacd ieee8023adLag = oc.IETFInterfaces_InterfaceType_ieee8023adLag + trafficPps = 10000 + totalPackets = 200000 ) var ( @@ -439,7 +441,7 @@ func normalize(xs []uint64) (ys []float64, sum uint64) { return ys, sum } -var approxOpt = cmpopts.EquateApprox(0 /* frac */, 0.01 /* absolute */) +var approxOpt = cmpopts.EquateApprox(0 /* frac */, 0.1 /* absolute */) // portWants converts the nextHop wanted weights to per-port wanted // weights listed in the same order as atePorts. @@ -502,6 +504,8 @@ func (tc *testCase) testFlow(t *testing.T, l3header string) { flow := tc.top.Flows().Add().SetName(l3header) flow.Metrics().SetEnable(true) flow.Size().SetFixed(128) + flow.Rate().SetPps(trafficPps) + flow.Duration().FixedPackets().SetPackets(totalPackets) flow.Packet().Add().Ethernet().Src().SetValue(ateSrc.MAC) ipType := "IPv4" @@ -557,7 +561,7 @@ func (tc *testCase) testFlow(t *testing.T, l3header string) { beforeTrafficCounters := tc.getCounters(t, "before") tc.ate.OTG().StartTraffic(t) - time.Sleep(15 * time.Second) + time.Sleep(20 * time.Second) tc.ate.OTG().StopTraffic(t) otgutils.LogPortMetrics(t, tc.ate.OTG(), tc.top) @@ -569,6 +573,30 @@ func (tc *testCase) testFlow(t *testing.T, l3header string) { if pkts == 0 { t.Errorf("Flow sent packets: got %v, want non zero", pkts) } + + if deviations.InterfaceCountersUpdateDelayed(tc.dut) { + batch := gnmi.OCBatch() + for _, port := range tc.dutPorts[1:] { + batch.AddPaths(gnmi.OC().Interface(port.Name()).Counters()) + } + + _, ok := gnmi.Watch(t, tc.dut, batch.State(), time.Second*60, func(v *ygnmi.Value[*oc.Root]) bool { + got, present := v.Val() + if !present { + return false + } + totalPks := uint64(0) + for _, port := range tc.dutPorts[1:] { + totalPks += got.GetInterface(port.Name()).GetCounters().GetOutPkts() - beforeTrafficCounters[port.Name()].GetOutPkts() + } + return totalPks >= pkts + }).Await(t) + + if !ok { + t.Fatalf("Counters did not update in time") + } + } + afterTrafficCounters := tc.getCounters(t, "after") tc.verifyCounterDiff(t, beforeTrafficCounters, afterTrafficCounters) } diff --git a/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto b/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto index 68c8eb17c3a..f29298037aa 100644 --- a/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto +++ b/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto @@ -11,6 +11,7 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true + interface_counters_update_delayed: true } } platform_exceptions: { diff --git a/feature/interface/singleton/otg_tests/singleton_test/README.md b/feature/interface/singleton/otg_tests/singleton_test/README.md index a80de7b2ef8..d8d218db6f9 100644 --- a/feature/interface/singleton/otg_tests/singleton_test/README.md +++ b/feature/interface/singleton/otg_tests/singleton_test/README.md @@ -169,3 +169,56 @@ a new testbed configuration with the desired port types. ## Minimum DUT Platform Requirement vRX + +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths and RPC intended to be covered by this test. + +```yaml +paths: + /interfaces/interface/ethernet/state/counters/in-mac-pause-frames: + /interfaces/interface/ethernet/state/counters/out-mac-pause-frames: + /interfaces/interface/ethernet/state/mac-address: + /interfaces/interface/state/counters/in-broadcast-pkts: + /interfaces/interface/state/counters/in-discards: + /interfaces/interface/state/counters/in-errors: + /interfaces/interface/state/counters/in-multicast-pkts: + /interfaces/interface/state/counters/in-octets: + /interfaces/interface/state/counters/in-unicast-pkts: + /interfaces/interface/state/counters/in-unknown-protos: + /interfaces/interface/state/counters/out-broadcast-pkts: + /interfaces/interface/state/counters/out-discards: + /interfaces/interface/state/counters/out-errors: + /interfaces/interface/state/counters/out-multicast-pkts: + /interfaces/interface/state/counters/out-octets: + /interfaces/interface/state/counters/out-pkts: + /interfaces/interface/state/counters/out-unicast-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv4/state/mtu: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/mtu: + /interfaces/interface/state/oper-status: + /interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/ip: + /interfaces/interface/subinterfaces/subinterface/ipv4/state/counters/in-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv4/state/counters/out-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/ip: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/in-discarded-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/in-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/out-discarded-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/out-pkts: + /interfaces/interface/ethernet/state/aggregate-id: + /interfaces/interface/ethernet/state/port-speed: + /interfaces/interface/state/admin-status: + /interfaces/interface/state/description: + /interfaces/interface/state/type: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/out-forwarded-pkts: + /interfaces/interface/state/hardware-port: + /interfaces/interface/state/id: + /interfaces/interface/state/counters/in-fcs-errors: + /interfaces/interface/state/counters/carrier-transitions: + +rpcs: + gnmi: + gNMI.Set: + union_replace: false + gNMI.Subscribe: + on_change: false +``` diff --git a/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto b/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto index 76237f19190..926a5a3d560 100644 --- a/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto +++ b/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto @@ -12,6 +12,7 @@ platform_exceptions: { deviations: { ip_neighbor_missing: true ipv4_missing_enabled: true + interface_counters_update_delayed: true } } platform_exceptions: { diff --git a/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go b/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go index 4b38868f6ee..ffe41e929ff 100644 --- a/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go +++ b/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go @@ -30,6 +30,7 @@ import ( "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" otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" @@ -430,6 +431,36 @@ func (tc *testCase) testFlow(t *testing.T, packetSize uint16, configIPHeader otg t.Logf("ap1 out-octets %d -> ap2 in-octets %d", aicp1.GetCounters().GetOutOctets(), aicp2.GetCounters().GetInOctets()) } + // Flow counters + otgutils.LogFlowMetrics(t, tc.ate.OTG(), tc.top) + fp := gnmi.Get(t, tc.ate.OTG(), gnmi.OTG().Flow(flow.Name()).State()) + fpc := fp.GetCounters() + + // Pragmatic check on the average in and out packet sizes. IPv4 may + // fragment the packet unless DF bit is set. IPv6 never fragments. + // Under no circumstances should DUT send packets greater than MTU. + + octets := fpc.GetOutOctets() + ateOutPkts := fpc.GetOutPkts() + ateInPkts := fpc.GetInPkts() + + if deviations.InterfaceCountersUpdateDelayed(tc.dut) { + batch := gnmi.OCBatch() + batch.AddPaths( + gnmi.OC().Interface(p1.Name()).Counters(), + gnmi.OC().Interface(p2.Name()).Counters(), + ) + gnmi.Watch(t, tc.dut, batch.State(), time.Second*60, func(v *ygnmi.Value[*oc.Root]) bool { + got, present := v.Val() + if !present { + return false + } + diffP1 := diffCounters(p1InBefore, inCounters(got.GetInterface(p1.Name()).GetCounters())) + diffP2 := diffCounters(p2OutBefore, outCounters(got.GetInterface(p2.Name()).GetCounters())) + return (diffP1.unicast+diffP1.drop >= ateOutPkts) && (diffP2.unicast >= ateInPkts-diffP2.drop) + }).Await(t) + } + // After Traffic Unicast, Multicast, Broadcast Counter p1InAfter := inCounters(gnmi.Get(t, tc.dut, p1Counter.State())) p2OutAfter := outCounters(gnmi.Get(t, tc.dut, p2Counter.State())) @@ -449,18 +480,6 @@ func (tc *testCase) testFlow(t *testing.T, packetSize uint16, configIPHeader otg t.Errorf("Large number of outbound Broadcast packets %d, want <= 100)", p2OutDiff.broadcast) } - // Flow counters - otgutils.LogFlowMetrics(t, tc.ate.OTG(), tc.top) - fp := gnmi.Get(t, tc.ate.OTG(), gnmi.OTG().Flow(flow.Name()).State()) - fpc := fp.GetCounters() - - // Pragmatic check on the average in and out packet sizes. IPv4 may - // fragment the packet unless DF bit is set. IPv6 never fragments. - // Under no circumstances should DUT send packets greater than MTU. - - octets := fpc.GetOutOctets() - ateOutPkts := fpc.GetOutPkts() - ateInPkts := fpc.GetInPkts() if ateOutPkts == 0 { t.Error("Flow did not send any packet") } else if avg := octets / ateOutPkts; avg > uint64(tc.mtu) { diff --git a/feature/experimental/isis/otg_tests/base_adjacencies_test/README.md b/feature/isis/otg_tests/base_adjacencies_test/README.md similarity index 100% rename from feature/experimental/isis/otg_tests/base_adjacencies_test/README.md rename to feature/isis/otg_tests/base_adjacencies_test/README.md diff --git a/feature/experimental/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go b/feature/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go rename to feature/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go diff --git a/feature/experimental/isis/otg_tests/base_adjacencies_test/metadata.textproto b/feature/isis/otg_tests/base_adjacencies_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/base_adjacencies_test/metadata.textproto rename to feature/isis/otg_tests/base_adjacencies_test/metadata.textproto diff --git a/feature/isis/otg_tests/graceful_restart_helper/README.md b/feature/isis/otg_tests/graceful_restart_helper/README.md new file mode 100644 index 00000000000..9c822775000 --- /dev/null +++ b/feature/isis/otg_tests/graceful_restart_helper/README.md @@ -0,0 +1,252 @@ +# RT-2.15: IS-IS Graceful Restart Helper + +## Summary + +- test verify isis garceful restarts support in helper role + +## Testbed type + +* https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed + +## Procedure + +#### Initial Setup: + +* Connect: + * DUT port-1 to ATE port-1 + * DUT port-2 to ATE port-2 + +* Configure IPv4 and IPv6 addresses on DUT and ATE ports as shown below + * DUT port-1 IPv4 address ```dp1-v4 = 192.168.1.1/30``` + * ATE port-1 IPv4 address ```ap1-v4 = 192.168.1.2/30``` + + * DUT port-2 IPv4 address ```dp2-v4 = 192.168.1.5/30``` + * ATE port-2 IPv4 address ```ap2-v4 = 192.168.1.6/30``` + + * DUT port-1 IPv6 address ```dp1-v6 = 2001:DB8::1/126``` + * ATE port-1 IPv6 address ```ap1-v6 = 2001:DB8::2/126``` + + * DUT port-2 IPv6 address ```dp2-v6 = 2001:DB8::5/126``` + * ATE port-2 IPv6 address ```ap2-v6 = 2001:DB8::6/126``` + +* Create an "target IPv4" network i.e. ```ipv4-network = 192.168.10.0/24``` attached to ATE port-2 and inject it to ISIS. + +* Create an "target IPv6" network i.e. ```ipv6-network = 2024:db8:128:128::/64``` attached to ATE port-2 and inject it to ISIS. + +* Configure ISIS + * Configure separate ISIS emulated routers, one on each ATE ports-1, port-2 + * Enable IPv4 and IPv6 IS-IS L2 adjacency between ATE port-1 and DUT port-1, DUT port-2 and ATE port-2 in point-to-point mode. + + ```json + { + "network-instances": { + "network-instance": [ + { + "name": "DEFAULT", + "protocols": { + "protocol": [ + { + "identifier": "ISIS", + "name": "DEFAULT", + "config": { + "name": "DEFAULT", + "identifier": "ISIS" + }, + "isis": { + "global": { + "afi-safi": { + "af": [ + { + "afi-name": "IPV4", + "config": { + "afi-name": "IPV4", + "enabled": true, + "safi-name": "UNICAST" + }, + "safi-name": "UNICAST" + }, + { + "afi-name": "IPV6", + "config": { + "afi-name": "IPV6", + "enabled": true, + "safi-name": "UNICAST" + }, + "safi-name": "UNICAST" + } + ] + }, + "config": { + "level-capability": "LEVEL_2", + "net": [ + "" + ] + } + }, + "interfaces": { + "interface": [ + { + "config": { + "passive": true, + "enabled": true, + "interface-id": "Loopback0" + }, + "interface-id": "Loopback0", + "interface-ref": { + "config": { + "interface": "loopback0", + "subinterface": 0 + } + }, + "levels": { + "level": [ + { + "config": { + "level-number": 2, + "enabled": true + }, + "level-number": 2 + } + ] + } + }, + { + "config": { + "circuit-type": "POINT_TO_POINT", + "enabled": true, + "interface-id": "" + }, + "interface-id": "", + "interface-ref": { + "config": { + "interface": "", + "subinterface": 0 + } + }, + "levels": { + "level": [ + { + "afi-safi": { + "af": [ + { + "afi-name": "IPV4", + "config": { + "afi-name": "IPV4", + "metric": 10, + "safi-name": "UNICAST" + }, + "safi-name": "UNICAST" + }, + { + "afi-name": "IPV6", + "config": { + "afi-name": "IPV6", + "metric": 10, + "safi-name": "UNICAST" + }, + "safi-name": "UNICAST" + } + ] + }, + "config": { + "level-number": 2, + "enabled": true + }, + "level-number": 2, + "timers": { + "config": { + "hello-interval": 10, + "hello-multiplier": 6 + } + } + } + ] + } + } + ] + }, + "levels": { + "level": [ + { + "config": { + "level-number": 2, + "metric-style": "WIDE_METRIC", + "enabled": true + }, + "level-number": 2 + } + ] + } + } + } + ] + } + } + ] + } + } + ``` + * Enable IPv4 and IPv6 IS-IS L2 adjacency between ATE port-1 and DUT port-1, DUT port-2 and ATE port-2 in point-to-point mode.\ + * Set ISIS graceful restart helper mode on DUT + + ```json + { + "network-instances": { + "network-instance": [ + { + "name": "DEFAULT", + "protocols": { + "protocol": [ + { + "identifier": "ISIS", + "name": "DEFAULT", + "isis": { + "global": { + "graceful-restart": { + "config": { + "enabled": true, + "helper-only": true, + "restart-time": 30 + } + } + } + } + } + ] + } + } + ] + } + } + ``` + +### RT-2.15.1 [TODO: https://github.com/openconfig/featureprofiles/issues/2494] +#### GR helper + +* Generate traffic form ATE port-1 to "target IPv4" and "target IPv6" networks (ATE port-2) +* Verify traffic is recived on ATE port-2 +* Restart ISIS on ATE port-2 (Alternativly: using set_control_state to "down" for emulated isis router. Wait (restart-time - 10) sec and set it back to "up") +* Verify traffic is recived on ATE port-2 during restart time ( no losses ) +* Disable ISIS on ATE port-2 (set_control_state to "down"). Wait restart-time seconds +* Verify traffic is NOT recived on ATE port-2 (after restart-time expires) + +## 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 ## + /network-instances/network-instance/protocols/protocol/isis/global/graceful-restart/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/global/graceful-restart/config/helper-only: + /network-instances/network-instance/protocols/protocol/isis/global/graceful-restart/config/restart-time: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` + +## Required DUT platform + +* FFF \ No newline at end of file diff --git a/feature/isis/otg_tests/graceful_restart_helper/metadata.textproto b/feature/isis/otg_tests/graceful_restart_helper/metadata.textproto new file mode 100644 index 00000000000..4c84b917911 --- /dev/null +++ b/feature/isis/otg_tests/graceful_restart_helper/metadata.textproto @@ -0,0 +1,21 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "4ebdc9b9-8f58-4e33-875b-b5b2a3e0de33" +plan_id: "RT-2.15" +description: "IS-IS Graceful Restart Helper" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + omit_l2_mtu: true + isis_interface_afi_unsupported: true + isis_instance_enabled_required: true + missing_value_for_defaults: true + skip_isis_set_level: true + } +} \ No newline at end of file diff --git a/feature/experimental/isis/otg_tests/isis_change_lsp_lifetime_test/README.md b/feature/isis/otg_tests/isis_change_lsp_lifetime_test/README.md similarity index 70% rename from feature/experimental/isis/otg_tests/isis_change_lsp_lifetime_test/README.md rename to feature/isis/otg_tests/isis_change_lsp_lifetime_test/README.md index 02310135271..a7bd7a209cd 100644 --- a/feature/experimental/isis/otg_tests/isis_change_lsp_lifetime_test/README.md +++ b/feature/isis/otg_tests/isis_change_lsp_lifetime_test/README.md @@ -23,23 +23,18 @@ * Verify that the remaining lifetime of the lsp is remaining lifetime = configured lifetime - time passed since the LSP PDU generation. * Verify that once the new LSP PDU is generated the sequence number and checksum of the new LSP PDU is updated -## Config Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * global/timers/config/lsp-lifetime-interval - -## Telemetry Parameter coverage - -* For prefix: - - * /network-instances/network-instance/protocols/protocol/isis/ - -* Parameters: - - * global/timers/state/lsp-lifetime-interval - * levels/level/link-state-database/lsp/state/remaining-lifetime +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/timers/config/lsp-lifetime-interval: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/timers/state/lsp-lifetime-interval: + /network-instances/network-instance/protocols/protocol/isis/levels/level/link-state-database/lsp/state/remaining-lifetime: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` diff --git a/feature/experimental/isis/otg_tests/isis_change_lsp_lifetime_test/isis_change_lsp_lifetime_test.go b/feature/isis/otg_tests/isis_change_lsp_lifetime_test/isis_change_lsp_lifetime_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/isis_change_lsp_lifetime_test/isis_change_lsp_lifetime_test.go rename to feature/isis/otg_tests/isis_change_lsp_lifetime_test/isis_change_lsp_lifetime_test.go diff --git a/feature/experimental/isis/otg_tests/isis_change_lsp_lifetime_test/metadata.textproto b/feature/isis/otg_tests/isis_change_lsp_lifetime_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/isis_change_lsp_lifetime_test/metadata.textproto rename to feature/isis/otg_tests/isis_change_lsp_lifetime_test/metadata.textproto diff --git a/feature/experimental/isis/otg_tests/isis_drain_test/README.md b/feature/isis/otg_tests/isis_drain_test/README.md similarity index 84% rename from feature/experimental/isis/otg_tests/isis_drain_test/README.md rename to feature/isis/otg_tests/isis_drain_test/README.md index 8c2bf143e5f..67410a03579 100644 --- a/feature/experimental/isis/otg_tests/isis_drain_test/README.md +++ b/feature/isis/otg_tests/isis_drain_test/README.md @@ -12,15 +12,13 @@ Ensure that IS-IS metric change can drain traffic from a DUT trunk interface * Change the ISIS metric of trunk-2 to 1000 value. Validate that 100% of the traffic is going out of only trunk-3 and there is no traffic loss. * Revert back the ISIS metric on trunk-2. Validate that the traffic is going via both trunk-2 and trunk-3, and there is no traffic loss. -## Config Parameter Coverage - -## Telemetry Parameter Coverage - -## Protocol/RPC Parameter Coverage - -* IS-IS - * LSP - * TLV 22 metric field. +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` ## Minimum DUT Platform Requirement diff --git a/feature/experimental/isis/otg_tests/isis_drain_test/isis_drain_test.go b/feature/isis/otg_tests/isis_drain_test/isis_drain_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/isis_drain_test/isis_drain_test.go rename to feature/isis/otg_tests/isis_drain_test/isis_drain_test.go diff --git a/feature/experimental/isis/otg_tests/isis_drain_test/metadata.textproto b/feature/isis/otg_tests/isis_drain_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/isis_drain_test/metadata.textproto rename to feature/isis/otg_tests/isis_drain_test/metadata.textproto diff --git a/feature/isis/otg_tests/isis_extensions_segment_routing_test/README.md b/feature/isis/otg_tests/isis_extensions_segment_routing_test/README.md new file mode 100644 index 00000000000..23fe1fd5e7b --- /dev/null +++ b/feature/isis/otg_tests/isis_extensions_segment_routing_test/README.md @@ -0,0 +1,96 @@ +# RT-2.15 IS-IS Extensions for Segment Routing + +## Summary + +* This test case provides comprehensive coverage of IS-IS extensions for Segment Routing (SR), including: + * Node SID advertisement in IS-IS TLVs. + * SRGB and SRLB configuration and validation. + * Test coverage for Prefix SIDs and Anycast SIDs. + +## Testbed type + +* [`featureprofiles/topologies/atedut_2.testbed`](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed) + +## Procedure + +### Configuration + +1) Create the topology below: + + ``` + ATE1—DUT1–ATE2 + ``` + +2) Enable SR and MPLS: + * Enable Segment Routing for ISIS on the DUT. + * Enable MPLS forwarding on all interfaces. + * Configure appropriate IGP settings to ensure adjacency formation and prefix exchange between the DUT and ATEs. + +### SR-1.2.1: SRGB and SRLB Configuration. + +* Configure a non-default SRGB on the DUT with a specific lower and upper bound (17000-20000). +* Configure an SRLB on the DUT with a specific lower and upper bound (24000-27000). +* Verify that the DUT allocates and advertises labels for prefixes from its configured SRGB range. +* Verify that the DUT allocates and utilizes labels for adjacencies from its configured SRLB range. + +### SR-1.2.2: Node SID Validation. + +* Configure the DUT to advertise its Node SID to ATE1 and ATE2. +* Advertise prefixe (1) from ATE2 to the DUT +* Send labeled traffic transiting through the DUT (using its node-SID) matching prefix (1). +* Verify that the DUT advertises its Node SID in IS-IS TLVs. +* Verify that ATE2 receives traffic with node-SID label popped. +* Verify that traffic arrives to ATE Port 2. +* Verify that corresponding SID forwarding counters are incremented. + +### SR-1.2.3: Prefix SID Validation. + +* Configure the DUT to advertise two loopback prefixes with Prefix SIDs. +* Verify that the DUT advertises the loopback prefixes with the correct Prefix SIDs. +* Send labeled traffic from ATE1 to the loopback prefixes on the DUT +* Verify correct forwarding using Prefix SIDs. +* Verify that corresponding SID forwarding counters are incremented. + +### SR-1.2.4: Anycast SID Validation. + +* Configure the DUT to advertise an Anycast SID representing a service reachable via both loopback interfaces. +* Verify that the DUT advertises the Anycast SID. +* Send traffic from both ATEs towards the Anycast SID. +* Verify that traffic is load-balanced between the DUT's loopback interfaces based on IGP metrics. +* Verify that corresponding SID forwarding counters are incremented. + +## OpenConfig Path and RPC Coverage + +```yaml +paths: + ## Config paths + /network-instances/network-instance/mpls/global/reserved-label-blocks/reserved-label-block/config/local-id: + /network-instances/network-instance/mpls/global/reserved-label-blocks/reserved-label-block/config/lower-bound: + /network-instances/network-instance/mpls/global/reserved-label-blocks/reserved-label-block/config/upper-bound: + /network-instances/network-instance/mpls/global/interface-attributes/interface/config/mpls-enabled: + /network-instances/network-instance/segment-routing/srgbs/srgb/config/local-id: + /network-instances/network-instance/segment-routing/srgbs/srgb/config/mpls-label-blocks: + /network-instances/network-instance/segment-routing/srlbs/srlb/config/mpls-label-block: + /network-instances/network-instance/protocols/protocol/isis/global/segment-routing/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/global/segment-routing/config/srgb: + /network-instances/network-instance/protocols/protocol/isis/global/segment-routing/config/srlb: + + ## Telemetry + /network-instances/network-instance/protocols/protocol/isis/global/segment-routing/state/enabled: + /network-instances/network-instance/mpls/global/reserved-label-blocks/reserved-label-block/state/local-id: + /network-instances/network-instance/mpls/global/reserved-label-blocks/reserved-label-block/state/lower-bound: + /network-instances/network-instance/mpls/global/reserved-label-blocks/reserved-label-block/state/upper-bound: + /network-instances/network-instance/mpls/signaling-protocols/segment-routing/aggregate-sid-counters/aggregate-sid-counter/state/in-pkts: + /network-instances/network-instance/mpls/signaling-protocols/segment-routing/aggregate-sid-counters/aggregate-sid-counter/state/out-pkts: + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + replace: true + gNMI.Subscribe: + on_change: true +``` + +## Minimum DUT platform requirement +* FFF - fixed form factor \ No newline at end of file diff --git a/feature/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md b/feature/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md new file mode 100644 index 00000000000..7448bf4d1b8 --- /dev/null +++ b/feature/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md @@ -0,0 +1,92 @@ +# RT-2.6: IS-IS Hello-Padding enabled at interface level + +## Summary + +* Base IS-IS functionality and adjacency establishment. +* Verifies isis adjacency by changing MTU. + +## Procedure + +* Configure IS-IS for ATE port-1 and DUT port-1. +* Configure DUT with global hello-padding enabled. +* Ensure that adjacencies are established with: + * Interface level hello padding is enabled. + * Verify that IPv4 and IPv6 IS-ISIS adjacency comes up fine. + * Verify the output of ST path displaying the status of ISIS hello padding. + * If we change the MTU on either side, then adjacency should not come up. + * Verify that IPv4 and IPv6 prefixes that are advertised by ATE correctly installed into DUTs route and forwarding table. + * TODO-Verify the Hellos are sent with Padding during adjacency turn-up if the padding is enabled adaptively/sometimes. + * Ensure that IPv4 and IPv6 prefixes that are advertised as part of an (emulated) neighboring system are installed into the DUT routing table, and validate that packets are sent and received to them. + +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/config/authentication-check: + /network-instances/network-instance/protocols/protocol/isis/global/config/net: + /network-instances/network-instance/protocols/protocol/isis/global/config/level-capability: + /network-instances/network-instance/protocols/protocol/isis/global/config/hello-padding: + /network-instances/network-instance/protocols/protocol/isis/global/afi-safi/af/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/config/level-number: + /network-instances/network-instance/protocols/protocol/isis/levels/level/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-mode: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-password: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/interface-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/circuit-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/timers/config/csnp-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/timers/config/lsp-pacing-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/config/level-number: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/timers/config/hello-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/timers/config/hello-multiplier: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-mode: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-password: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/afi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/safi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/enabled: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/state/hello-padding: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/state/hello-padding: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/adjacency-state: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv4-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv6-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/system-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/area-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/dis-system-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/local-extended-circuit-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/multi-topology: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-circuit-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-extended-circuit-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-snpa: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/nlpid: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/priority: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-status: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-support: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-suppress: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/afi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/safi-name: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/auth-fails: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/auth-type-fails: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/corrupted-lsps: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/database-overloads: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/exceed-max-seq-nums: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/id-len-mismatch: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/lsp-errors: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/manual-address-drop-from-areas: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/max-area-address-mismatches: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/own-lsp-purges: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/part-changes: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/seq-num-skips: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/spf-runs: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` \ No newline at end of file diff --git a/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go b/feature/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go rename to feature/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go diff --git a/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto b/feature/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto rename to feature/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto diff --git a/feature/isis/otg_tests/isis_interface_level_passive_test/README.md b/feature/isis/otg_tests/isis_interface_level_passive_test/README.md new file mode 100644 index 00000000000..b0d7374a153 --- /dev/null +++ b/feature/isis/otg_tests/isis_interface_level_passive_test/README.md @@ -0,0 +1,95 @@ +# RT-2.11: IS-IS Passive is enabled at the area level + +## Summary + +* Verify isis adjacency with passive enabled under level. + +## Topology + +* ATE:port1 <-> port1:DUT:port2 <-> ATE:port2 + +## Procedure + +* Configure IS-IS for ATE port-1 and DUT port-1. +* Configure DUT interface with IS-IS passive configured at area level 2. + * Verify that IS-IS adjacency is not coming up in level-2 area for IPv4 and IPV6 address families. +* Undo the IS-IS passive configuration under level 2 + * Verify that IS-IS adjacency for IPv4 and IPV6 address families are coming up in the level-2 area. + * Verify that IPv4 and IPv6 prefixes that are advertised by ATE are correctly installed into DUTs route and forwarding table. + * Ensure that IPv4 and IPv6 prefixes that are advertised as part of an (emulated) neighboring system are installed into the DUT routing table, and validate that packets are sent and received to them. + * TODO-Verify the output of ST path displaying the interface as passive in ISIS database/adj table + +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/config/authentication-check: + /network-instances/network-instance/protocols/protocol/isis/global/config/net: + /network-instances/network-instance/protocols/protocol/isis/global/config/level-capability: + /network-instances/network-instance/protocols/protocol/isis/global/config/hello-padding: + /network-instances/network-instance/protocols/protocol/isis/global/afi-safi/af/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/config/level-number: + /network-instances/network-instance/protocols/protocol/isis/levels/level/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-mode: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-password: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/interface-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/circuit-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/passive: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/timers/config/csnp-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/timers/config/lsp-pacing-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/config/level-number: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/config/passive: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/timers/config/hello-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/timers/config/hello-multiplier: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-mode: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-password: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/afi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/safi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/enabled: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/state/passive: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/state/passive: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/adjacency-state: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv4-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv6-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/system-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/area-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/dis-system-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/local-extended-circuit-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/multi-topology: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-circuit-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-extended-circuit-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-snpa: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/nlpid: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/priority: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-status: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-support: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-suppress: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/afi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/safi-name: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/auth-fails: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/auth-type-fails: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/corrupted-lsps: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/database-overloads: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/exceed-max-seq-nums: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/id-len-mismatch: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/lsp-errors: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/manual-address-drop-from-areas: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/max-area-address-mismatches: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/own-lsp-purges: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/part-changes: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/seq-num-skips: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/spf-runs: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` \ No newline at end of file diff --git a/feature/experimental/isis/otg_tests/isis_interface_level_passive_test/isis_interface_level_passive_test.go b/feature/isis/otg_tests/isis_interface_level_passive_test/isis_interface_level_passive_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/isis_interface_level_passive_test/isis_interface_level_passive_test.go rename to feature/isis/otg_tests/isis_interface_level_passive_test/isis_interface_level_passive_test.go diff --git a/feature/experimental/isis/otg_tests/isis_interface_level_passive_test/metadata.textproto b/feature/isis/otg_tests/isis_interface_level_passive_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/isis_interface_level_passive_test/metadata.textproto rename to feature/isis/otg_tests/isis_interface_level_passive_test/metadata.textproto diff --git a/feature/experimental/isis/otg_tests/isis_interface_passive_test/README.md b/feature/isis/otg_tests/isis_interface_passive_test/README.md similarity index 99% rename from feature/experimental/isis/otg_tests/isis_interface_passive_test/README.md rename to feature/isis/otg_tests/isis_interface_passive_test/README.md index cd87a3ba503..bf600ec87b0 100644 --- a/feature/experimental/isis/otg_tests/isis_interface_passive_test/README.md +++ b/feature/isis/otg_tests/isis_interface_passive_test/README.md @@ -76,7 +76,7 @@ paths: /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/exceed-max-seq-nums: /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/id-len-mismatch: /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/lsp-errors: -/network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/manual-address-drop-from-area : +/network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/manual-address-drop-from-areas: /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/max-area-address-mismatches: /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/own-lsp-purges: /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/part-changes : diff --git a/feature/experimental/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go b/feature/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go rename to feature/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go diff --git a/feature/experimental/isis/otg_tests/isis_interface_passive_test/metadata.textproto b/feature/isis/otg_tests/isis_interface_passive_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/isis_interface_passive_test/metadata.textproto rename to feature/isis/otg_tests/isis_interface_passive_test/metadata.textproto diff --git a/feature/experimental/isis/otg_tests/isis_metric_style_wide_enabled_test/README.md b/feature/isis/otg_tests/isis_metric_style_wide_enabled_test/README.md similarity index 100% rename from feature/experimental/isis/otg_tests/isis_metric_style_wide_enabled_test/README.md rename to feature/isis/otg_tests/isis_metric_style_wide_enabled_test/README.md diff --git a/feature/experimental/isis/otg_tests/isis_metric_style_wide_enabled_test/isis_metric_style_wide_enabled_test.go b/feature/isis/otg_tests/isis_metric_style_wide_enabled_test/isis_metric_style_wide_enabled_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/isis_metric_style_wide_enabled_test/isis_metric_style_wide_enabled_test.go rename to feature/isis/otg_tests/isis_metric_style_wide_enabled_test/isis_metric_style_wide_enabled_test.go diff --git a/feature/experimental/isis/otg_tests/isis_metric_style_wide_enabled_test/metadata.textproto b/feature/isis/otg_tests/isis_metric_style_wide_enabled_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/isis_metric_style_wide_enabled_test/metadata.textproto rename to feature/isis/otg_tests/isis_metric_style_wide_enabled_test/metadata.textproto diff --git a/feature/isis/otg_tests/isis_metric_style_wide_not_enabled_test/README.md b/feature/isis/otg_tests/isis_metric_style_wide_not_enabled_test/README.md new file mode 100644 index 00000000000..49fa92ad9b2 --- /dev/null +++ b/feature/isis/otg_tests/isis_metric_style_wide_not_enabled_test/README.md @@ -0,0 +1,94 @@ +# RT-2.8: IS-IS metric style wide not enabled + +## Summary + +* Base IS-IS functionality and adjacency establishment. +* Verifies route metric with wide metric disabled on DUT. + +## Procedure + +* TestISISWideMetricNotEnabled + + * Configure IS-IS for ATE port-1 and DUT port-1. + * Do not configure metric style wide under the area level. + * Enable wide metric style on ATE. + * Advertise ISIS prefixes from ATE with wide metrics (value > 63). + * Verify that IS-IS adjacency for IPv4 and IPV6 address family is coming up. + * Verify that IPv4 and IPv6 prefixes that are advertised by ATE correctly installed into DUTs route and forwarding table. + * TODO-Verify that the metrics of the IPv4 and IPv6 prefixes is 63. + * Ensure that IPv4 and IPv6 prefixes that are advertised as part of an (emulated) neighboring system are installed into the DUT routing table, and validate that packets are sent and received to them. + +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/config/authentication-check: + /network-instances/network-instance/protocols/protocol/isis/global/config/net: + /network-instances/network-instance/protocols/protocol/isis/global/config/level-capability: + /network-instances/network-instance/protocols/protocol/isis/global/config/hello-padding: + /network-instances/network-instance/protocols/protocol/isis/global/afi-safi/af/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/config/level-number: + /network-instances/network-instance/protocols/protocol/isis/levels/level/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/config/metric-style: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-mode: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-password: + /network-instances/network-instance/protocols/protocol/isis/levels/level/authentication/config/auth-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/interface-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/circuit-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/config/passive: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/timers/config/csnp-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/timers/config/lsp-pacing-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/config/level-number: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/config/passive: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/timers/config/hello-interval: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/timers/config/hello-multiplier: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-mode: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-password: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/auth-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/hello-authentication/config/enabled: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/afi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/safi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/afi-safi/af/config/enabled: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/levels/level/state/metric-style: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/adjacency-state: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv4-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv6-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/system-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/area-address: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/dis-system-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/local-extended-circuit-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/multi-topology: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-circuit-type: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-extended-circuit-id: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-snpa: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/nlpid: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/priority: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-status: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-support: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/adjacencies/adjacency/state/restart-suppress: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/afi-name: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/safi-name: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/auth-fails: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/auth-type-fails: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/corrupted-lsps: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/database-overloads: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/exceed-max-seq-nums: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/id-len-mismatch: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/lsp-errors: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/manual-address-drop-from-areas: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/max-area-address-mismatches: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/own-lsp-purges: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/part-changes: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/seq-num-skips: + /network-instances/network-instance/protocols/protocol/isis/levels/level/system-level-counters/state/spf-runs: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` \ No newline at end of file diff --git a/feature/experimental/isis/otg_tests/isis_metric_style_wide_not_enabled_test/isis_metric_style_wide_not_enabled_test.go b/feature/isis/otg_tests/isis_metric_style_wide_not_enabled_test/isis_metric_style_wide_not_enabled_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/isis_metric_style_wide_not_enabled_test/isis_metric_style_wide_not_enabled_test.go rename to feature/isis/otg_tests/isis_metric_style_wide_not_enabled_test/isis_metric_style_wide_not_enabled_test.go diff --git a/feature/experimental/isis/otg_tests/isis_metric_style_wide_not_enabled_test/metadata.textproto b/feature/isis/otg_tests/isis_metric_style_wide_not_enabled_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/isis_metric_style_wide_not_enabled_test/metadata.textproto rename to feature/isis/otg_tests/isis_metric_style_wide_not_enabled_test/metadata.textproto diff --git a/feature/experimental/isis/otg_tests/lsp_updates_test/README.md b/feature/isis/otg_tests/lsp_updates_test/README.md similarity index 58% rename from feature/experimental/isis/otg_tests/lsp_updates_test/README.md rename to feature/isis/otg_tests/lsp_updates_test/README.md index d207d7c482a..b1f4c16e5bc 100644 --- a/feature/experimental/isis/otg_tests/lsp_updates_test/README.md +++ b/feature/isis/otg_tests/lsp_updates_test/README.md @@ -20,26 +20,21 @@ Ensure that IS-IS updates reflect parameter changes on DUT. port via configuration, update value in configuration, and ensure that ATE and DUT telemetry reflects the change. -## Config Parameter Coverage - -For prefix: /network-instances/network-instance/protocols/protocol/isis/ - -Parameters: - -* global/lsp-bit/overload-bit/config/set-bit - -## Telemetry Parameter Coverage - -* /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric - -* /network-instances/network-instance/protocols/protocol/isis/global/lsp-bit/overload-bit/state/set-bit - -## Protocol/RPC Parameter Coverage - -* IS-IS - * LSP - * Flags - overload bit (5) - * TLV 22 metric field. +## OpenConfig Path and RPC Coverage +```yaml +paths: + ## Config Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/lsp-bit/overload-bit/config/set-bit: + + ## Telemetry Parameter Coverage + /network-instances/network-instance/protocols/protocol/isis/global/lsp-bit/overload-bit/state/set-bit: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric: + +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` ## Minimum DUT Platform Requirement diff --git a/feature/experimental/isis/otg_tests/lsp_updates_test/lsp_updates_test.go b/feature/isis/otg_tests/lsp_updates_test/lsp_updates_test.go similarity index 100% rename from feature/experimental/isis/otg_tests/lsp_updates_test/lsp_updates_test.go rename to feature/isis/otg_tests/lsp_updates_test/lsp_updates_test.go diff --git a/feature/experimental/isis/otg_tests/lsp_updates_test/metadata.textproto b/feature/isis/otg_tests/lsp_updates_test/metadata.textproto similarity index 100% rename from feature/experimental/isis/otg_tests/lsp_updates_test/metadata.textproto rename to feature/isis/otg_tests/lsp_updates_test/metadata.textproto diff --git a/feature/mpls/otg_tests/static_bgp_nexthop/README.md b/feature/mpls/otg_tests/static_bgp_nexthop/README.md new file mode 100644 index 00000000000..7ed0a06fe99 --- /dev/null +++ b/feature/mpls/otg_tests/static_bgp_nexthop/README.md @@ -0,0 +1,121 @@ +# MPLS-2.2: MPLS forwarding via static LSP to BGP next-hop. + +## Summary + +Validate static LSP functionality with BGP resolved next-hop. This test verifies that the DUT can forward MPLS traffic based on a static LSP that uses a next-hop resolved via BGP. + +## Testbed type + +* [`featureprofiles/topologies/atedut_4.testbed`](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_4.testbed) + +## Procedure + +### Configuration + +1) Create the topology below: + + ``` + | | ---- | ATE Port 2 | ---- [eBGP peer] + [ ATE Port 1 ] ---- | DUT | | | + | | ---- | ATE Port 3 | + ``` + +2) Configure eBGP peer on ATE Port 2 interface and advertise `BGP-NH-V4= 203.0.200.0/24` and `BGP-NH-V6= 2001:db8:128:200::/64` +3) Configure static routes on the DUT to discard traffic destined for BGP-NH-V4 and BGP-NH-V6. These routes should point to a Null0 with an administrative distance of 254 to ensure they are less preferred than the BGP routes. This prevents the DUT from using its IGP to reach the BGP next-hops. +4) Enable MPLS forwarding. +5) Create egress static LSP for IPv4 and IPV6 traffic to pop the label and resolve the next-hop BGP-NH-V4 and BGP-NH-V6 respectivelly + +```yaml +network-instances: + - network-instance: + mpls: + lsps: + static-lsps: + - static-lsp: + config: + name: "lsp-egress-v4" + egress: + next-hop: 203.0.200.1 + incoming-label: 1000004 + - static-lsp: + config: + name: "lsp-egress-v6" + egress: + next-hop: 2001:db8:128:200::1 + incoming-label: 1000006 +``` + * Set resolve NH action for both LSPs. + +**TODO:** OC model does not support resolve next-hop option for LSPs. + +7) Configure static routes i.e. `IPV4-DST = 203.0.113.0/24` and `IPV6-DST = 2001:db8:128:128::/64` to ATE Port 3. +```yaml +network-instances: + - network-instance: + protocols: + - protocol: + static-routes: + - static: + config: + prefix: "203.0.113.0/24" + next-hops: + - next-hop: + config: + index: 1 + next-hop: "ATE PORT 3" + - static: + config: + prefix: "2001:db8:128:128::/64" + next-hops: + - next-hop: + config: + index: 1 + next-hop: "ATE PORT 3" +``` + +### MPLS-2.2.1: Verify IPv4 MPLS forwarding + +* Push the above DUT configuration. +* Start traffic flow with MPLS[lbl-1000004] and IPv4 destined to IPV4-DST. +* Verify that traffic arrives to ATE Port 2. + +### MPLS-2.2.2: Verify IPv6 MPLS forwarding + +* Push the above DUT configuration. +* Start traffic flow with MPLS[lbl-1000006] and IPv4 destined to IPV6-DST. +* Verify that traffic arrives to ATE Port 2. + +### MPLS-2.2.3: Verify IPv4 traffic discard when BGP-NH is not available. + +* Withdraw BGP-NH-V4 advertisement. +* Push the above DUT configuration. +* Start traffic flow with MPLS[lbl-1000004] and IPv4 destination set to IPV4-DST. +* Verify that traffic is discarded. + +### MPLS-2.2.4: Verify IPv6 traffic discard when BGP-NH is not available. + +* Withdraw BGP-NH-V6 advertisement. +* Push the above DUT configuration. +* Start traffic flow with MPLS[lbl-1000006] and IPv6 destination set to IPV6-DST. +* Verify that traffic is discarded. + +## OpenConfig Path and RPC Coverage + +```yaml +paths: + ## Config paths + /network-instances/network-instance/mpls/lsps/static-lsps/static-lsp/egress/config/incoming-label: + /network-instances/network-instance/mpls/lsps/static-lsps/static-lsp/egress/config/next-hop: + /network-instances/network-instance/protocols/protocol/static-routes/static/config/prefix: + /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/next-hop: + /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/index: + + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + replace: true + gNMI.Subscribe: + on_change: true +``` \ No newline at end of file diff --git a/feature/networkinstance/otg_tests/defaults_test/defaults_test.go b/feature/networkinstance/otg_tests/defaults_test/defaults_test.go index 9c1aa24c511..0e7355e012e 100644 --- a/feature/networkinstance/otg_tests/defaults_test/defaults_test.go +++ b/feature/networkinstance/otg_tests/defaults_test/defaults_test.go @@ -18,6 +18,7 @@ package ni_address_families_test import ( "fmt" + "slices" "testing" "time" @@ -103,6 +104,7 @@ var ( IPv6Len: 64, MAC: "02:00:02:01:01:01", } + kneDeviceModelList = []string{"ncptx", "ceos", "srlinux", "xrd"} ) // TestDefaultAddressFamilies verifies that both IPv4 and IPv6 are enabled by default without a need for additional @@ -181,6 +183,14 @@ func TestDefaultAddressFamilies(t *testing.T) { otgutils.WaitForARP(t, ate.OTG(), top, "IPv4") otgutils.WaitForARP(t, ate.OTG(), top, "IPv6") + // https://github.com/openconfig/featureprofiles/issues/3410 + // Below code will be removed once ixia issue is fixed. + if slices.Contains(kneDeviceModelList, dut.Model()) { + ate.OTG().StartTraffic(t) + time.Sleep(15 * time.Second) + ate.OTG().StopTraffic(t) + } + ate.OTG().StartTraffic(t) time.Sleep(15 * time.Second) ate.OTG().StopTraffic(t) diff --git a/feature/experimental/p4rt/README.md b/feature/p4rt/README.md similarity index 94% rename from feature/experimental/p4rt/README.md rename to feature/p4rt/README.md index a2dc5701736..3acc900e9fc 100644 --- a/feature/experimental/p4rt/README.md +++ b/feature/p4rt/README.md @@ -52,9 +52,9 @@ This document specifies the requirements for p4rt test implementation. `p4rtutils.P4RTNodesByPort()`. ## 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 - +rpcs: + gnmi: + gNMI.Set: + gNMI.Subscribe: ``` diff --git a/feature/experimental/p4rt/otg_tests/base_p4rt/README.md b/feature/p4rt/otg_tests/base_p4rt/README.md similarity index 73% rename from feature/experimental/p4rt/otg_tests/base_p4rt/README.md rename to feature/p4rt/otg_tests/base_p4rt/README.md index e4ca8068fb1..e690e261459 100644 --- a/feature/experimental/p4rt/otg_tests/base_p4rt/README.md +++ b/feature/p4rt/otg_tests/base_p4rt/README.md @@ -24,19 +24,16 @@ Validate that the P4RT server can accept basic configuration and Read/Write RPCs * Repeat the same steps for another FAP and verify the Table entries. - -## Config Parameter Coverage - -* /components/component/integrated-circuit/config/node-id -* /interfaces/interface/config/id - - -## Telemetry Parameter coverage - -No new telemetry covered. - - -## Protocol/RPC Parameter coverage - -No new Protocol/RPC covered. +## OpenConfig Path and RPC Coverage +```yaml +paths: + /components/component/integrated-circuit/config/node-id: + platform_type: ["INTEGRATED_CIRCUIT"] + /interfaces/interface/config/id: +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/feature/experimental/p4rt/otg_tests/base_p4rt/base_p4rt_test.go b/feature/p4rt/otg_tests/base_p4rt/base_p4rt_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/base_p4rt/base_p4rt_test.go rename to feature/p4rt/otg_tests/base_p4rt/base_p4rt_test.go diff --git a/feature/experimental/p4rt/otg_tests/base_p4rt/metadata.textproto b/feature/p4rt/otg_tests/base_p4rt/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/base_p4rt/metadata.textproto rename to feature/p4rt/otg_tests/base_p4rt/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md b/feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md similarity index 86% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md rename to feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md index a5bffb0cdd9..8c5f6f83043 100644 --- a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md +++ b/feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md @@ -14,13 +14,14 @@ Verify that GDP packets are punted with correct metadata. * Verify that the packet has the ingress_singleton_port metadata set and it corresponds to the interface ID of the port that the packet was received on. -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go b/feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go rename to feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/metadata.textproto b/feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/metadata.textproto rename to feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/README.md b/feature/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/README.md similarity index 100% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/README.md rename to feature/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/README.md diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/google_discovery_protocol_packetout_lag_test.go b/feature/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/google_discovery_protocol_packetout_lag_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/google_discovery_protocol_packetout_lag_test.go rename to feature/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/google_discovery_protocol_packetout_lag_test.go diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/metadata.textproto b/feature/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/metadata.textproto rename to feature/p4rt/otg_tests/google_discovery_protocol_packetout_lag_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md b/feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md similarity index 87% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md rename to feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md index 8d6fd5b5870..d1ba03f1f5b 100644 --- a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md +++ b/feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md @@ -15,15 +15,14 @@ Verify that GDP packets can be sent by the controller. * Repeat sending the packet in the same way but from the secondary connection. * Verify that the packet is not received on the ATE. - - -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go b/feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go rename to feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/metadata.textproto b/feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/metadata.textproto rename to feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetin_test/README.md b/feature/p4rt/otg_tests/lldp_packetin_test/README.md similarity index 85% rename from feature/experimental/p4rt/otg_tests/lldp_packetin_test/README.md rename to feature/p4rt/otg_tests/lldp_packetin_test/README.md index 4af42c8c091..e3398a89860 100644 --- a/feature/experimental/p4rt/otg_tests/lldp_packetin_test/README.md +++ b/feature/p4rt/otg_tests/lldp_packetin_test/README.md @@ -13,15 +13,14 @@ Verify that LLDP packets are punted with correct metadata. * Send an LLDP packet from the ATE and verify that it is received by the client. * Verify that the packet has the ingress_singleton_port metadata set and it corresponds to the interface ID of the port that the packet was received on. - - -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go b/feature/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go rename to feature/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetin_test/metadata.textproto b/feature/p4rt/otg_tests/lldp_packetin_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/lldp_packetin_test/metadata.textproto rename to feature/p4rt/otg_tests/lldp_packetin_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetout_test/README.md b/feature/p4rt/otg_tests/lldp_packetout_test/README.md similarity index 80% rename from feature/experimental/p4rt/otg_tests/lldp_packetout_test/README.md rename to feature/p4rt/otg_tests/lldp_packetout_test/README.md index ec9b4d9d73a..97616953d12 100644 --- a/feature/experimental/p4rt/otg_tests/lldp_packetout_test/README.md +++ b/feature/p4rt/otg_tests/lldp_packetout_test/README.md @@ -13,17 +13,13 @@ Verify that LLDP packets can be sent by the controller. * Send an LLDP packet from the client with egress_singleton_port set to one of the connected interfaces. * Verify that the LLDP packet is received on the ATE port connected to the indicated interface. - - - -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. - -## Minimum DUT platform requirement +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` vRX if the vendor implementation supports FIB-ACK simulation, otherwise FFF. \ No newline at end of file diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go b/feature/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go rename to feature/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetout_test/metadata.textproto b/feature/p4rt/otg_tests/lldp_packetout_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/lldp_packetout_test/metadata.textproto rename to feature/p4rt/otg_tests/lldp_packetout_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/performance_test/README.md b/feature/p4rt/otg_tests/performance_test/README.md similarity index 73% rename from feature/experimental/p4rt/otg_tests/performance_test/README.md rename to feature/p4rt/otg_tests/performance_test/README.md index 470f6c467be..fb7d6b31e32 100644 --- a/feature/experimental/p4rt/otg_tests/performance_test/README.md +++ b/feature/p4rt/otg_tests/performance_test/README.md @@ -15,21 +15,18 @@ Verify that both Packetin and Packetout traffic is handled by the P4RT server at * Setup packetout packets for GDP, LLDP and traceroute from the P4RT client. * Start both packetin and packetout traffic at the same rate simultaneously. * Verify no packetloss for both directions of traffic. -* Verify the metadata ID and the value for all three traffic types on the P4RT client for packetin. - - -## Config Parameter coverage - -* /components/component/integrated-circuit/config/node-id -* /interfaces/interface/config/id - - -## Telemetry Parameter coverage - -No new telemetry covered. - - -## Protocol/RPC Parameter coverage - -No new Protocol/RPC covered. +* Verify the metadata ID and the value for all three traffic types on the P4RT client for packetin. + +## OpenConfig Path and RPC Coverage +```yaml +paths: + /components/component/integrated-circuit/config/node-id: + platform_type: ["INTEGRATED_CIRCUIT"] + /interfaces/interface/config/id: +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/feature/experimental/p4rt/otg_tests/performance_test/metadata.textproto b/feature/p4rt/otg_tests/performance_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/performance_test/metadata.textproto rename to feature/p4rt/otg_tests/performance_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/performance_test/performance_test.go b/feature/p4rt/otg_tests/performance_test/performance_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/performance_test/performance_test.go rename to feature/p4rt/otg_tests/performance_test/performance_test.go diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/README.md b/feature/p4rt/otg_tests/traceroute_packetin_test/README.md similarity index 73% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_test/README.md rename to feature/p4rt/otg_tests/traceroute_packetin_test/README.md index 8a69af7d868..0aee47016e4 100644 --- a/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/README.md +++ b/feature/p4rt/otg_tests/traceroute_packetin_test/README.md @@ -16,19 +16,15 @@ Verify that Traceroute packets are punted with correct metadata. * Send IPv6 packets from the ATE with HopLimit=1 and verify that packets with HopLimit=1 are received by the client. * Verify that the packets have both ingress_singleton_port and egress_singleton_port metadata set. - -## Config Parameter coverage - -* /components/component/integrated-circuit/config/node-id -* /interfaces/interface/config/id - - -## Telemetry Parameter coverage - -No new telemetry covered. - - -## Protocol/RPC Parameter coverage - -No new Protocol/RPC covered. - +## OpenConfig Path and RPC Coverage +```yaml +paths: + /components/component/integrated-circuit/config/node-id: + platform_type: ["INTEGRATED_CIRCUIT"] + /interfaces/interface/config/id: +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/metadata.textproto b/feature/p4rt/otg_tests/traceroute_packetin_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_test/metadata.textproto rename to feature/p4rt/otg_tests/traceroute_packetin_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/packetin_test.go b/feature/p4rt/otg_tests/traceroute_packetin_test/packetin_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_test/packetin_test.go rename to feature/p4rt/otg_tests/traceroute_packetin_test/packetin_test.go diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go b/feature/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go rename to feature/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/README.md b/feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/README.md similarity index 98% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/README.md rename to feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/README.md index d15347dad27..ec980072fd7 100644 --- a/feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/README.md +++ b/feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/README.md @@ -17,7 +17,7 @@ DUT port-8 <------> port-8 ATE ## Baseline setup -* Setup equivalent to [TE-17.1 vrf_policy_driven_te](https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/README.md), including GRibi programming. +* Setup equivalent to [TE-17.1 vrf_policy_driven_te](https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/vrf_policy_driven_te/README.md), including GRibi programming. * Install a BGP route resolved by ISIS in default VRF to route traffic out of DUT port-8 for 203.0.113.0. diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/metadata.textproto b/feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/metadata.textproto rename to feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/packetin_test.go b/feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/packetin_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/packetin_test.go rename to feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/packetin_test.go diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_test.go b/feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_test.go rename to feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_test.go diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_with_vrf_selection_test.go b/feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_with_vrf_selection_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_with_vrf_selection_test.go rename to feature/p4rt/otg_tests/traceroute_packetin_with_vrf_selection_test/traceroute_packetin_with_vrf_selection_test.go diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/README.md b/feature/p4rt/otg_tests/traceroute_packetout_test/README.md similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetout_test/README.md rename to feature/p4rt/otg_tests/traceroute_packetout_test/README.md diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/metadata.textproto b/feature/p4rt/otg_tests/traceroute_packetout_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetout_test/metadata.textproto rename to feature/p4rt/otg_tests/traceroute_packetout_test/metadata.textproto diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/packetout_test.go b/feature/p4rt/otg_tests/traceroute_packetout_test/packetout_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetout_test/packetout_test.go rename to feature/p4rt/otg_tests/traceroute_packetout_test/packetout_test.go diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go b/feature/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go similarity index 100% rename from feature/experimental/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go rename to feature/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go diff --git a/feature/experimental/p4rt/tests/metadata_validation_test/README.md b/feature/p4rt/tests/metadata_validation_test/README.md similarity index 81% rename from feature/experimental/p4rt/tests/metadata_validation_test/README.md rename to feature/p4rt/tests/metadata_validation_test/README.md index 8ad072ab172..8a311ea7d05 100644 --- a/feature/experimental/p4rt/tests/metadata_validation_test/README.md +++ b/feature/p4rt/tests/metadata_validation_test/README.md @@ -23,3 +23,16 @@ Validate the P4RT server handles Metadata set in Table Entry correctly. ## Notes * [P4RT Proto](https://github.com/p4lang/p4runtime/blob/main/proto/p4/v1/p4runtime.proto) + +## OpenConfig Path and RPC Coverage +```yaml +paths: + /components/component/integrated-circuit/config/node-id: + platform_type: ["INTEGRATED_CIRCUIT"] + /interfaces/interface/config/id: +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/feature/experimental/p4rt/tests/metadata_validation_test/metadata.textproto b/feature/p4rt/tests/metadata_validation_test/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/tests/metadata_validation_test/metadata.textproto rename to feature/p4rt/tests/metadata_validation_test/metadata.textproto diff --git a/feature/experimental/p4rt/tests/metadata_validation_test/metadata_validation_test.go b/feature/p4rt/tests/metadata_validation_test/metadata_validation_test.go similarity index 100% rename from feature/experimental/p4rt/tests/metadata_validation_test/metadata_validation_test.go rename to feature/p4rt/tests/metadata_validation_test/metadata_validation_test.go diff --git a/feature/experimental/p4rt/tests/p4rt_election/README.md b/feature/p4rt/tests/p4rt_election/README.md similarity index 96% rename from feature/experimental/p4rt/tests/p4rt_election/README.md rename to feature/p4rt/tests/p4rt_election/README.md index 5b77cea3ccf..9226182e9e4 100644 --- a/feature/experimental/p4rt/tests/p4rt_election/README.md +++ b/feature/p4rt/tests/p4rt_election/README.md @@ -106,3 +106,16 @@ Validate the P4RT server handles primary election and failover. writes for clients with `election_id=9` & `election_id=10`. * TODO: Enable P4RT on an additional FAP and verify that the same set of scenarios work independently of the first FAP + +## OpenConfig Path and RPC Coverage +```yaml +paths: + /components/component/integrated-circuit/config/node-id: + platform_type: ["INTEGRATED_CIRCUIT"] + /interfaces/interface/config/id: +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/feature/experimental/p4rt/tests/p4rt_election/metadata.textproto b/feature/p4rt/tests/p4rt_election/metadata.textproto similarity index 100% rename from feature/experimental/p4rt/tests/p4rt_election/metadata.textproto rename to feature/p4rt/tests/p4rt_election/metadata.textproto diff --git a/feature/experimental/p4rt/tests/p4rt_election/p4rt_election_test.go b/feature/p4rt/tests/p4rt_election/p4rt_election_test.go similarity index 100% rename from feature/experimental/p4rt/tests/p4rt_election/p4rt_election_test.go rename to feature/p4rt/tests/p4rt_election/p4rt_election_test.go diff --git a/feature/experimental/p4rt/wbb.p4info.pb.txt b/feature/p4rt/wbb.p4info.pb.txt similarity index 100% rename from feature/experimental/p4rt/wbb.p4info.pb.txt rename to feature/p4rt/wbb.p4info.pb.txt diff --git a/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/README.md b/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/README.md index 0f026d1ced4..9b02357681f 100644 --- a/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/README.md +++ b/feature/platform/fabric/otg_tests/sampled_backplane_capacity_counters_test/README.md @@ -102,3 +102,24 @@ rpcs: ## Required DUT platform * MFF + +## 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: + /interfaces/interface/config/enabled: + /interfaces/interface/subinterfaces/subinterface/ipv4/config/enabled: + /interfaces/interface/subinterfaces/subinterface/ipv6/config/enabled: + /components/component/fabric/config/power-admin-state: + + ## State paths: N/A + +rpcs: + gnmi: + gNMI.Set: + Replace: +``` \ No newline at end of file diff --git a/feature/platform/tests/power_admin_down_up_test/README.md b/feature/platform/tests/power_admin_down_up_test/README.md index 229f9c52ed7..9ecf373081a 100644 --- a/feature/platform/tests/power_admin_down_up_test/README.md +++ b/feature/platform/tests/power_admin_down_up_test/README.md @@ -21,11 +21,27 @@ ControllerCard. to POWER_ENABLED. * Verify /components/component/state/oper-status returns to ACTIVE. -## Config Parameter coverage +## Minumum DUT platform requirement +vRX -* /components/component/{fabric|linecard|controller-card}/config/power-admin-state +## Config Parameter coverage + * /components/component/{fabric|linecard|controller-card}/config/power-admin-state ## Telemetry Parameter coverage + * /components/component/state/oper-status + * /components/component/{fabric|linecard|controller-card}/state/power-admin-state + +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths and RPC intended to be covered by this test. + +```yaml +paths: +/components/component/name: +/components/component/state/name: -* /components/component/state/oper-status -* /components/component/{fabric|linecard|controller-card}/state/power-admin-state +rpcs: + gnmi: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/feature/platform/tests/power_admin_down_up_test/metadata.textproto b/feature/platform/tests/power_admin_down_up_test/metadata.textproto index ae49957c730..58ef621af8e 100644 --- a/feature/platform/tests/power_admin_down_up_test/metadata.textproto +++ b/feature/platform/tests/power_admin_down_up_test/metadata.textproto @@ -30,3 +30,12 @@ platform_exceptions: { skip_controller_card_power_admin: true } } +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + power_disable_enable_leaf_ref_validation: true + } +} + diff --git a/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go b/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go index d536abd7f5c..9a0f3ff5e63 100644 --- a/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go +++ b/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go @@ -14,6 +14,7 @@ import ( "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) { @@ -106,7 +107,7 @@ func TestControllerCardPowerAdmin(t *testing.T) { t.Skipf("ControllerCard Component %s is already INACTIVE, hence skipping", c) } - powerDownUp(t, dut, c, oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_CONTROLLER_CARD, 3*time.Minute) + powerDownUp(t, dut, c, oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_CONTROLLER_CARD, 5*time.Minute) }) } if primary != "" { @@ -132,7 +133,11 @@ func powerDownUp(t *testing.T, dut *ondatra.DUTDevice, name string, cType oc.E_P default: t.Fatalf("Unknown component type: %s", cType.String()) } - + if deviations.PowerDisableEnableLeafRefValidation(dut) { + gnmi.Update(t, dut, c.Config(), &oc.Component{ + Name: ygot.String(name), + }) + } start := time.Now() t.Logf("Starting %s POWER_DISABLE", name) gnmi.Replace(t, dut, config, oc.Platform_ComponentPowerType_POWER_DISABLED) diff --git a/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go b/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go index b8bdc687167..c43e72e44a2 100644 --- a/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go +++ b/feature/platform/transceiver/tests/zr_low_power_mode_test/zr_low_power_mode_test.go @@ -21,6 +21,7 @@ import ( "time" "github.com/openconfig/featureprofiles/internal/cfgplugins" + "github.com/openconfig/featureprofiles/internal/components" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/samplestream" "github.com/openconfig/ondatra" @@ -30,8 +31,7 @@ import ( ) const ( - samplingInterval = 10 * time.Second - intUpdateTime = 2 * time.Minute + intUpdateTime = 2 * time.Minute ) func TestMain(m *testing.M) { @@ -82,7 +82,7 @@ func TestLowPowerMode(t *testing.T) { dut := ondatra.DUT(t, "dut") cfgplugins.InterfaceConfig(t, dut, dut.Port(t, "port1")) cfgplugins.InterfaceConfig(t, dut, dut.Port(t, "port2")) - + samplingInterval := 10 * time.Second for _, port := range []string{"port1", "port2"} { t.Run(fmt.Sprintf("Port:%s", port), func(t *testing.T) { dp := dut.Port(t, port) @@ -129,35 +129,36 @@ func TestLowPowerMode(t *testing.T) { gnmi.Await(t, dut, gnmi.OC().Interface(dp.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_DOWN) validateStreamOutput(t, allStream) - - opInst := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Instant().State(), samplingInterval) + opticalChannelName := components.OpticalChannelComponentFromPort(t, dut, dp) + samplingInterval = time.Duration(gnmi.Get(t, dut, gnmi.OC().Component(opticalChannelName).OpticalChannel().OutputPower().Interval().State())) + opInst := samplestream.New(t, dut, gnmi.OC().Component(opticalChannelName).OpticalChannel().OutputPower().Instant().State(), samplingInterval) defer opInst.Close() if opInstN := opInst.Next(); opInstN != nil { - if _, ok := opInstN.Val(); ok { + if val, ok := opInstN.Val(); ok && val != -40 { t.Fatalf("streaming /components/component/optical-channel/state/output-power/instant is not expected to be reported") } } - opAvg := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Avg().State(), samplingInterval) + opAvg := samplestream.New(t, dut, gnmi.OC().Component(opticalChannelName).OpticalChannel().OutputPower().Avg().State(), samplingInterval) defer opAvg.Close() if opAvgN := opAvg.Next(); opAvgN != nil { - if _, ok := opAvgN.Val(); ok { + if val, ok := opAvgN.Val(); ok && val != -40 { t.Fatalf("streaming /components/component/optical-channel/state/output-power/avg is not expected to be reported") } } - opMin := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Min().State(), samplingInterval) + opMin := samplestream.New(t, dut, gnmi.OC().Component(opticalChannelName).OpticalChannel().OutputPower().Min().State(), samplingInterval) defer opMin.Close() if opMinN := opMin.Next(); opMinN != nil { - if _, ok := opMinN.Val(); ok { + if val, ok := opMinN.Val(); ok && val != -40 { t.Fatalf("streaming /components/component/optical-channel/state/output-power/min is not expected to be reported") } } - opMax := samplestream.New(t, dut, gnmi.OC().Component(tr).OpticalChannel().OutputPower().Max().State(), samplingInterval) + opMax := samplestream.New(t, dut, gnmi.OC().Component(opticalChannelName).OpticalChannel().OutputPower().Max().State(), samplingInterval) defer opMax.Close() if opMaxN := opMax.Next(); opMaxN != nil { - if _, ok := opMaxN.Val(); ok { + if val, ok := opMaxN.Val(); ok && val != -40 { t.Fatalf("streaming /components/component/optical-channel/state/output-power/max is not expected to be reported") } } @@ -173,7 +174,6 @@ func TestLowPowerMode(t *testing.T) { "min": opMin, "max": opMax, } - validateOutputPower(t, powerStreamMap) cfgplugins.ValidateInterfaceConfig(t, dut, dp) }) diff --git a/feature/experimental/policy/otg_tests/prefix_set_test/README.md b/feature/policy_forwarding/otg_tests/prefix_set_test/README.md similarity index 100% rename from feature/experimental/policy/otg_tests/prefix_set_test/README.md rename to feature/policy_forwarding/otg_tests/prefix_set_test/README.md diff --git a/feature/experimental/policy/otg_tests/prefix_set_test/metadata.textproto b/feature/policy_forwarding/otg_tests/prefix_set_test/metadata.textproto similarity index 100% rename from feature/experimental/policy/otg_tests/prefix_set_test/metadata.textproto rename to feature/policy_forwarding/otg_tests/prefix_set_test/metadata.textproto diff --git a/feature/experimental/policy/otg_tests/prefix_set_test/prefix_set_test.go b/feature/policy_forwarding/otg_tests/prefix_set_test/prefix_set_test.go similarity index 100% rename from feature/experimental/policy/otg_tests/prefix_set_test/prefix_set_test.go rename to feature/policy_forwarding/otg_tests/prefix_set_test/prefix_set_test.go diff --git a/feature/experimental/policy/policy_vrf_selection/otg_tests/base_vrf_selection/README.md b/feature/policy_forwarding/policy_vrf_selection/otg_tests/base_vrf_selection/README.md similarity index 100% rename from feature/experimental/policy/policy_vrf_selection/otg_tests/base_vrf_selection/README.md rename to feature/policy_forwarding/policy_vrf_selection/otg_tests/base_vrf_selection/README.md diff --git a/feature/experimental/policy/policy_vrf_selection/otg_tests/base_vrf_selection/base_vrf_selection_test.go b/feature/policy_forwarding/policy_vrf_selection/otg_tests/base_vrf_selection/base_vrf_selection_test.go similarity index 100% rename from feature/experimental/policy/policy_vrf_selection/otg_tests/base_vrf_selection/base_vrf_selection_test.go rename to feature/policy_forwarding/policy_vrf_selection/otg_tests/base_vrf_selection/base_vrf_selection_test.go diff --git a/feature/experimental/policy/policy_vrf_selection/otg_tests/base_vrf_selection/metadata.textproto b/feature/policy_forwarding/policy_vrf_selection/otg_tests/base_vrf_selection/metadata.textproto similarity index 100% rename from feature/experimental/policy/policy_vrf_selection/otg_tests/base_vrf_selection/metadata.textproto rename to feature/policy_forwarding/policy_vrf_selection/otg_tests/base_vrf_selection/metadata.textproto diff --git a/feature/experimental/policy/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/README.md b/feature/policy_forwarding/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/README.md similarity index 100% rename from feature/experimental/policy/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/README.md rename to feature/policy_forwarding/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/README.md diff --git a/feature/experimental/policy/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/metadata.textproto b/feature/policy_forwarding/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/metadata.textproto similarity index 100% rename from feature/experimental/policy/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/metadata.textproto rename to feature/policy_forwarding/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/metadata.textproto diff --git a/feature/experimental/policy/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/protocol_dscp_rules_for_vrf_selection_test.go b/feature/policy_forwarding/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/protocol_dscp_rules_for_vrf_selection_test.go similarity index 100% rename from feature/experimental/policy/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/protocol_dscp_rules_for_vrf_selection_test.go rename to feature/policy_forwarding/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/protocol_dscp_rules_for_vrf_selection_test.go diff --git a/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go b/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go index 2e8e158c370..f0504b744a8 100644 --- a/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go +++ b/feature/qos/otg_tests/bursty_traffic_test/bursty_traffic_test.go @@ -371,22 +371,12 @@ func TestBurstyTraffic(t *testing.T) { var counterNames []string counters := make(map[string]map[string]uint64) - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } + counterNames = []string{ + "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", + "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", + "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", + "dutQosDroppedOctetsAfterTraffic", } for _, name := range counterNames { @@ -420,13 +410,12 @@ func TestBurstyTraffic(t *testing.T) { } counters["dutQosDroppedPktsBeforeTraffic"][data.queue], _ = count.Val() - if !deviations.QOSDroppedOctets(dut) { - count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) - if !ok { - t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp3.Name(), data.queue, timeout) - } - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() + count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) + if !ok { + t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp3.Name(), data.queue, timeout) } + counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() + } t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) @@ -448,9 +437,8 @@ func TestBurstyTraffic(t *testing.T) { counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } + counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) + t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) if ateTxPkts == 0 { t.Fatalf("TxPkts == 0, want >0.") @@ -490,13 +478,11 @@ func TestBurstyTraffic(t *testing.T) { } } - if !deviations.QOSDroppedOctets(dut) { - ateDropOctetCounterDiff := (counters["ateOutPkts"][data.queue] - counters["ateInPkts"][data.queue]) * uint64(data.frameSize) - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: ateDropOctetCounterDiff: %v dutDropOctetCounterDiff: %v", data.queue, ateDropOctetCounterDiff, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff < ateDropOctetCounterDiff { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutDropOctetCounterDiff, ateDropOctetCounterDiff) - } + ateDropOctetCounterDiff := (counters["ateOutPkts"][data.queue] - counters["ateInPkts"][data.queue]) * uint64(data.frameSize) + dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] + t.Logf("Queue %q: ateDropOctetCounterDiff: %v dutDropOctetCounterDiff: %v", data.queue, ateDropOctetCounterDiff, dutDropOctetCounterDiff) + if dutDropOctetCounterDiff < ateDropOctetCounterDiff { + t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutDropOctetCounterDiff, ateDropOctetCounterDiff) } } diff --git a/feature/qos/otg_tests/bursty_traffic_test/metadata.textproto b/feature/qos/otg_tests/bursty_traffic_test/metadata.textproto index 0f9af70b1d7..7ee4ccb49c0 100644 --- a/feature/qos/otg_tests/bursty_traffic_test/metadata.textproto +++ b/feature/qos/otg_tests/bursty_traffic_test/metadata.textproto @@ -17,10 +17,6 @@ platform_exceptions: { platform: { vendor: JUNIPER } - deviations: { - explicit_interface_ref_definition: true - qos_dropped_octets: true - } } platform_exceptions: { platform: { diff --git a/feature/qos/otg_tests/ingress_police_default/README.md b/feature/qos/otg_tests/ingress_police_default/README.md new file mode 100644 index 00000000000..df47044e638 --- /dev/null +++ b/feature/qos/otg_tests/ingress_police_default/README.md @@ -0,0 +1,195 @@ +# DP-2.4 Police traffic on input matching all packets using 1 rate, 2 color marker + +## Summary + +Use the gRIBI applied ip entries from TE-18.1 gRIBI. +Configure an ingress scheduler to police traffic using a 1 rate, 2 color policer and attach the scheduler to the interface without a classifier. +Lack of match conditions will cause all packets to be matched. +Send traffic to validate the policer. + +## Topology + +* [`featureprofiles/topologies/atedut_2.testbed`](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed) + +## Test setup + +Use TE-18.1 test environment setup. + +## Procedure + +### DP-2.4.1 Generate and push configuration + +* Generate config for 2 scheduler polices with an input rate limit. +* Apply scheduler to DUT subinterface with vlan. +* Use gnmi.Replace to push the config to the DUT. + +```json +{ + "openconfig-qos": { + "scheduler-policies": [ + { + "scheduler-policy": null, + "config": { + "name": "limit_1Gb" + }, + "schedulers": [ + { + "scheduler": null, + "config": { + "sequence": 1, + "type": "ONE_RATE_TWO_COLOR" + }, + "inputs": [ + { + "input": "my input policer 1Gb", + "config": { + "id": "my input policer 1Gb", + "input-type": "QUEUE", + "queue": "dummy_input_queue_A" + } + } + ], + "one-rate-two-color": { + "config": { + "cir": 1000000000, + "bc": 100000, + "queuing-behavior": "POLICE" + }, + "exceed-action": { + "config": { + "drop": true + } + } + } + } + ] + }, + { + "scheduler-policy": null, + "config": { + "name": "limit_2Gb" + }, + "schedulers": [ + { + "scheduler": null, + "config": { + "sequence": 1, + "type": "ONE_RATE_TWO_COLOR" + }, + "inputs": [ + { + "input": "my input policer 2Gb", + "config": { + "id": "my input policer 2Gb", + "input-type": "QUEUE", + "queue": "dummy_input_queue_B" + } + } + ], + "one-rate-two-color": { + "config": { + "cir": 2000000000, + "bc": 100000, + "queuing-behavior": "POLICE" + }, + "exceed-action": { + "config": { + "drop": true + } + } + } + } + ] + } + ], + # + # Interfaces input are mapped to the desired scheduler. + "interfaces": [ + { + "interface": null, + "config": { + "interface-id": "PortChannel1.100" + }, + "input": { + "scheduler-policy": { + "config": { + "name": "limit_group_A_1Gb" + } + } + } + }, + { + "interface": null, + "config": { + "interface-id": "PortChannel1.200" + }, + "input": { + "scheduler-policy": { + "config": { + "name": "limit_group_B_1Gb" + } + } + } + } + ] + } +} +``` + +### DP-2.4.2 Test traffic + +* Send traffic + * Send flow A traffic from ATE port 1 to DUT for dest_A at 0.7Gbps (note cir is 1Gbps). + * Send flow B traffic from ATE port 1 to DUT for to dest_B at 1.5Gbps (note cir is 2Gbps). + * Validate qos counters per DUT. + * Validate qos counters by ATE port. + * Validate packets are received by ATE port 2. + * Validate DUT qos interface scheduler counters count packets as conforming-pkts and conforming-octets + * Validate at OTG that 0 packets are lost on flow A and flow B + * When the outer packet is IPv6, the flow-label should be inspected on the ATE. + * If the inner packet is IPv4, the outer IPv6 flow label should be computed based on the IPv4 5 tuple src,dst address and ports, plus protocol. + * If the inner packet is IPv6, the inner flow label should be copied to the outer packet. + * To validate the flow label, use the ATE to verify that the packets for + * flow A all have the same flow label + * flow B have the same flow label + * flow A and B labels do not match + * Increase traffic on flow to dest_B to 2Gbps + * Validate that flow dest_B experiences ~50% packet loss (+/- 1%) + + +#### OpenConfig Path and RPC Coverage + +```yaml +paths: + # qos scheduler config + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/config/cir: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/config/bc: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/config/queuing-behavior: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/one-rate-two-color/exceed-action/config/drop: + + # qos interfaces config + /qos/interfaces/interface/config/interface-id: + /qos/interfaces/interface/input/scheduler-policy/config/name: + + # qos interface scheduler counters + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/conforming-pkts: + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/conforming-octets: + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/exceeding-pkts: + /qos/interfaces/interface/input/scheduler-policy/schedulers/scheduler/state/exceeding-octets: + +rpcs: + gnmi: + gNMI.Set: + union_replace: true + replace: true + gNMI.Subscribe: + on_change: true +``` + +## Required DUT platform + +* FFF + + diff --git a/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/README.md b/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/README.md index 09c58f2d08b..adbb4e22acf 100644 --- a/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/README.md +++ b/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/README.md @@ -150,3 +150,59 @@ forwards AF3, AF2, AF1, BE1 and BE0 based on weight. * /qos/interfaces/interface/output/queues/queue/state/transmit-octets * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts * /qos/interfaces/interface/output/queues/queue/state/dropped-octets + +## 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: + /qos/forwarding-groups/forwarding-group/config/name: + /qos/forwarding-groups/forwarding-group/config/output-queue: + /qos/queues/queue/config/name: + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/config/type: + /qos/classifiers/classifier/terms/term/actions/config/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set: + /qos/classifiers/classifier/terms/term/config/id: + /qos/interfaces/interface/output/queues/queue/config/name: + /qos/interfaces/interface/input/classifiers/classifier/config/name: + /qos/interfaces/interface/output/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight: + + ## State paths: + /qos/forwarding-groups/forwarding-group/state/name: + /qos/forwarding-groups/forwarding-group/state/output-queue: + /qos/queues/queue/state/name: + /qos/classifiers/classifier/state/name: + /qos/classifiers/classifier/state/type: + /qos/classifiers/classifier/terms/term/actions/state/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/state/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/state/dscp-set: + /qos/classifiers/classifier/terms/term/state/id: + /qos/interfaces/interface/output/queues/queue/state/name: + /qos/interfaces/interface/input/classifiers/classifier/state/name: + /qos/interfaces/interface/output/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/weight: + +rpcs: + gnmi: + gNMI.Set: + Replace: \ No newline at end of file diff --git a/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/metadata.textproto b/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/metadata.textproto index cf011351b89..34786e74bae 100644 --- a/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/metadata.textproto +++ b/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/metadata.textproto @@ -18,8 +18,6 @@ platform_exceptions: { vendor: JUNIPER } deviations: { - explicit_interface_ref_definition: true - qos_dropped_octets: true scheduler_input_weight_limit: true } } diff --git a/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go b/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go index 4016f751681..1ef4e4f42d5 100644 --- a/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go +++ b/feature/qos/otg_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go @@ -530,19 +530,11 @@ func TestMixedSPWrrTraffic(t *testing.T) { var counterNames []string counters := make(map[string]map[string]uint64) - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } + counterNames = []string{ + "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", + "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", + "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", + "dutQosDroppedOctetsAfterTraffic", } for _, name := range counterNames { @@ -576,13 +568,11 @@ func TestMixedSPWrrTraffic(t *testing.T) { } counters["dutQosDroppedPktsBeforeTraffic"][data.queue], _ = count.Val() - if !deviations.QOSDroppedOctets(dut) { - count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) - if !ok { - t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp3.Name(), data.queue, timeout) - } - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() + count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) + if !ok { + t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp3.Name(), data.queue, timeout) } + counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() } t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) @@ -601,9 +591,7 @@ func TestMixedSPWrrTraffic(t *testing.T) { counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } + counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) // Calculate aggregated throughput: @@ -666,14 +654,12 @@ func TestMixedSPWrrTraffic(t *testing.T) { } } - if !deviations.QOSDroppedOctets(dut) { - ateDropOctetCounterDiff := (counters["ateOutPkts"][data.queue] - counters["ateInPkts"][data.queue]) * uint64(data.frameSize) - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: ateDropOctetCounterDiff: %v dutDropOctetCounterDiff: %v", data.queue, ateDropOctetCounterDiff, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff < ateDropOctetCounterDiff { - if !deviations.DequeueDeleteNotCountedAsDrops(dut) { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutDropOctetCounterDiff, ateDropOctetCounterDiff) - } + ateDropOctetCounterDiff := (counters["ateOutPkts"][data.queue] - counters["ateInPkts"][data.queue]) * uint64(data.frameSize) + dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] + t.Logf("Queue %q: ateDropOctetCounterDiff: %v dutDropOctetCounterDiff: %v", data.queue, ateDropOctetCounterDiff, dutDropOctetCounterDiff) + if dutDropOctetCounterDiff < ateDropOctetCounterDiff { + if !deviations.DequeueDeleteNotCountedAsDrops(dut) { + t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutDropOctetCounterDiff, ateDropOctetCounterDiff) } } diff --git a/feature/qos/otg_tests/one_sp_queue_traffic_test/README.md b/feature/qos/otg_tests/one_sp_queue_traffic_test/README.md index d2cd200b781..2c357ec3166 100644 --- a/feature/qos/otg_tests/one_sp_queue_traffic_test/README.md +++ b/feature/qos/otg_tests/one_sp_queue_traffic_test/README.md @@ -136,3 +136,59 @@ Verify that DUT drops AF4, AF3, AF2, AF1, BE1 and BE0 before NC1. * /qos/interfaces/interface/output/queues/queue/state/transmit-octets * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts * /qos/interfaces/interface/output/queues/queue/state/dropped-octets + +## 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: + /qos/forwarding-groups/forwarding-group/config/name: + /qos/forwarding-groups/forwarding-group/config/output-queue: + /qos/queues/queue/config/name: + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/config/type: + /qos/classifiers/classifier/terms/term/actions/config/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set: + /qos/classifiers/classifier/terms/term/config/id: + /qos/interfaces/interface/output/queues/queue/config/name: + /qos/interfaces/interface/input/classifiers/classifier/config/name: + /qos/interfaces/interface/output/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight: + + ## State paths: + /qos/forwarding-groups/forwarding-group/state/name: + /qos/forwarding-groups/forwarding-group/state/output-queue: + /qos/queues/queue/state/name: + /qos/classifiers/classifier/state/name: + /qos/classifiers/classifier/state/type: + /qos/classifiers/classifier/terms/term/actions/state/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/state/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/state/dscp-set: + /qos/classifiers/classifier/terms/term/state/id: + /qos/interfaces/interface/output/queues/queue/state/name: + /qos/interfaces/interface/input/classifiers/classifier/state/name: + /qos/interfaces/interface/output/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/weight: + +rpcs: + gnmi: + gNMI.Set: + Replace: \ No newline at end of file diff --git a/feature/qos/otg_tests/one_sp_queue_traffic_test/metadata.textproto b/feature/qos/otg_tests/one_sp_queue_traffic_test/metadata.textproto index 5ad022dedf8..24e2c3193d3 100644 --- a/feature/qos/otg_tests/one_sp_queue_traffic_test/metadata.textproto +++ b/feature/qos/otg_tests/one_sp_queue_traffic_test/metadata.textproto @@ -17,9 +17,6 @@ platform_exceptions: { platform: { vendor: JUNIPER } - deviations: { - explicit_interface_ref_definition: true - } } platform_exceptions: { platform: { diff --git a/feature/qos/otg_tests/qos_basic_test/README.md b/feature/qos/otg_tests/qos_basic_test/README.md index 27c82a5bd18..e836aa0fc66 100644 --- a/feature/qos/otg_tests/qos_basic_test/README.md +++ b/feature/qos/otg_tests/qos_basic_test/README.md @@ -164,3 +164,59 @@ Verify that DUT supports QoS config and forward QoS traffic correctly. ## Required DUT platform * FFF + +## 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: + /qos/forwarding-groups/forwarding-group/config/name: + /qos/forwarding-groups/forwarding-group/config/output-queue: + /qos/queues/queue/config/name: + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/config/type: + /qos/classifiers/classifier/terms/term/actions/config/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set: + /qos/classifiers/classifier/terms/term/config/id: + /qos/interfaces/interface/output/queues/queue/config/name: + /qos/interfaces/interface/input/classifiers/classifier/config/name: + /qos/interfaces/interface/output/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight: + + ## State paths: + /qos/forwarding-groups/forwarding-group/state/name: + /qos/forwarding-groups/forwarding-group/state/output-queue: + /qos/queues/queue/state/name: + /qos/classifiers/classifier/state/name: + /qos/classifiers/classifier/state/type: + /qos/classifiers/classifier/terms/term/actions/state/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/state/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/state/dscp-set: + /qos/classifiers/classifier/terms/term/state/id: + /qos/interfaces/interface/output/queues/queue/state/name: + /qos/interfaces/interface/input/classifiers/classifier/state/name: + /qos/interfaces/interface/output/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/weight: + +rpcs: + gnmi: + gNMI.Set: + Replace: \ No newline at end of file diff --git a/feature/qos/otg_tests/qos_basic_test/metadata.textproto b/feature/qos/otg_tests/qos_basic_test/metadata.textproto index e85163ec382..c980b0c2817 100644 --- a/feature/qos/otg_tests/qos_basic_test/metadata.textproto +++ b/feature/qos/otg_tests/qos_basic_test/metadata.textproto @@ -19,8 +19,6 @@ platform_exceptions: { } deviations: { ecn_profile_required_definition: true - explicit_interface_ref_definition: true - qos_dropped_octets: true } } platform_exceptions: { diff --git a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go index b4ae086cc22..dbf632ad50d 100644 --- a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go +++ b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go @@ -399,24 +399,13 @@ func TestBasicConfigWithTraffic(t *testing.T) { ate.OTG().StartProtocols(t) counters := make(map[string]map[string]uint64) - var counterNames []string - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } + var counterNames = []string{ + "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", + "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", + "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", + "dutQosDroppedOctetsAfterTraffic", } for _, name := range counterNames { @@ -450,13 +439,12 @@ func TestBasicConfigWithTraffic(t *testing.T) { } counters["dutQosDroppedPktsBeforeTraffic"][data.queue], _ = count.Val() - if !deviations.QOSDroppedOctets(dut) { - count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) - if !ok { - t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp3.Name(), data.queue, timeout) - } - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() + count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) + if !ok { + t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp3.Name(), data.queue, timeout) } + counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() + } t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) @@ -476,9 +464,8 @@ func TestBasicConfigWithTraffic(t *testing.T) { counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } + counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) + t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) if ateTxPkts == 0 { @@ -519,13 +506,12 @@ func TestBasicConfigWithTraffic(t *testing.T) { } } - if !deviations.QOSDroppedOctets(dut) { - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: dutDropOctetCounterDiff: %v", data.queue, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff != 0 { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want 0", data.queue, dutDropOctetCounterDiff) - } + dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] + t.Logf("Queue %q: dutDropOctetCounterDiff: %v", data.queue, dutDropOctetCounterDiff) + if dutDropOctetCounterDiff != 0 { + t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want 0", data.queue, dutDropOctetCounterDiff) } + } // gnmi subscribe sample mode(10 and 15 seconds sample interval) for queue counters @@ -545,12 +531,11 @@ func TestBasicConfigWithTraffic(t *testing.T) { if len(droppedPkts) < minWant { t.Errorf("DroppedPkts: got %d, want >= %d", len(droppedPkts), minWant) } - if !deviations.QOSDroppedOctets(dut) { - droppedOctets := gnmi.Collect(t, gnmiOpts(t, dut, sampleInterval), gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), subscribeTimeout).Await(t) - if len(droppedOctets) < minWant { - t.Errorf("DroppedOctets: got %d, want >= %d", len(droppedOctets), minWant) - } + droppedOctets := gnmi.Collect(t, gnmiOpts(t, dut, sampleInterval), gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State(), subscribeTimeout).Await(t) + if len(droppedOctets) < minWant { + t.Errorf("DroppedOctets: got %d, want >= %d", len(droppedOctets), minWant) } + } } }) diff --git a/feature/qos/otg_tests/qos_output_queue_counters_test/README.md b/feature/qos/otg_tests/qos_output_queue_counters_test/README.md index eb8bb04af09..9fab7d0d7e8 100644 --- a/feature/qos/otg_tests/qos_output_queue_counters_test/README.md +++ b/feature/qos/otg_tests/qos_output_queue_counters_test/README.md @@ -13,7 +13,7 @@ Validate QoS interface output queue counters. * /qos/interfaces/interface/output/queues/queue/state/transmit-octets * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts * /qos/interfaces/interface/output/queues/queue/state/dropped-octets - + ## Config Parameter coverage * /interfaces/interface/config/enabled @@ -26,3 +26,59 @@ Validate QoS interface output queue counters. * /qos/interfaces/interface/output/queues/queue/state/transmit-octets * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts * /qos/interfaces/interface/output/queues/queue/state/dropped-octets + +## 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: + /qos/forwarding-groups/forwarding-group/config/name: + /qos/forwarding-groups/forwarding-group/config/output-queue: + /qos/queues/queue/config/name: + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/config/type: + /qos/classifiers/classifier/terms/term/actions/config/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set: + /qos/classifiers/classifier/terms/term/config/id: + /qos/interfaces/interface/output/queues/queue/config/name: + /qos/interfaces/interface/input/classifiers/classifier/config/name: + /qos/interfaces/interface/output/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight: + + ## State paths: + /qos/forwarding-groups/forwarding-group/state/name: + /qos/forwarding-groups/forwarding-group/state/output-queue: + /qos/queues/queue/state/name: + /qos/classifiers/classifier/state/name: + /qos/classifiers/classifier/state/type: + /qos/classifiers/classifier/terms/term/actions/state/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/state/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/state/dscp-set: + /qos/classifiers/classifier/terms/term/state/id: + /qos/interfaces/interface/output/queues/queue/state/name: + /qos/interfaces/interface/input/classifiers/classifier/state/name: + /qos/interfaces/interface/output/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/weight: + +rpcs: + gnmi: + gNMI.Set: + Replace: \ No newline at end of file diff --git a/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto b/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto index f6a3bbf0e12..75b7900893e 100644 --- a/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto +++ b/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto @@ -19,8 +19,6 @@ platform_exceptions: { } deviations: { scheduler_input_weight_limit: true - explicit_interface_ref_definition: true - qos_dropped_octets: true } } platform_exceptions: { diff --git a/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go b/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go index 3ba558b3091..82353b5eef1 100644 --- a/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go +++ b/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go @@ -178,22 +178,12 @@ func TestQoSCounters(t *testing.T) { var counterNames []string counters := make(map[string]map[string]uint64) - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } + counterNames = []string{ + "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", + "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", + "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", + "dutQosDroppedOctetsAfterTraffic", } for _, name := range counterNames { @@ -226,13 +216,12 @@ func TestQoSCounters(t *testing.T) { } counters["dutQosDroppedPktsBeforeTraffic"][data.queue], _ = count.Val() - if !deviations.QOSDroppedOctets(dut) { - count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) - if !ok { - t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp2.Name(), data.queue, timeout) - } - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() + count, ok = gnmi.Watch(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedOctets().State(), timeout, isPresent).Await(t) + if !ok { + t.Errorf("DroppedOctets count for queue %q on interface %q not available within %v", dp2.Name(), data.queue, timeout) } + counters["dutQosDroppedOctetsBeforeTraffic"][data.queue], _ = count.Val() + } ate.OTG().PushConfig(t, top) @@ -254,9 +243,8 @@ func TestQoSCounters(t *testing.T) { counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).TransmitPkts().State()) counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).TransmitOctets().State()) counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } + counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedOctets().State()) + t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) ateTxPkts := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow(trafficID).Counters().OutPkts().State()) @@ -296,12 +284,10 @@ func TestQoSCounters(t *testing.T) { } } - if !deviations.QOSDroppedOctets(dut) { - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: dutDropOctetCounterDiff: %v", data.queue, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff != 0 { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want 0", data.queue, dutDropOctetCounterDiff) - } + dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] + t.Logf("Queue %q: dutDropOctetCounterDiff: %v", data.queue, dutDropOctetCounterDiff) + if dutDropOctetCounterDiff != 0 { + t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want 0", data.queue, dutDropOctetCounterDiff) } } diff --git a/feature/qos/otg_tests/two_sp_queue_traffic_test/README.md b/feature/qos/otg_tests/two_sp_queue_traffic_test/README.md index 69c06f27d9b..4fdc68784a5 100644 --- a/feature/qos/otg_tests/two_sp_queue_traffic_test/README.md +++ b/feature/qos/otg_tests/two_sp_queue_traffic_test/README.md @@ -160,3 +160,59 @@ Verify that DUT drops AF3, AF2, AF1, BE1 and BE0 before AF4 before NC1. * /qos/interfaces/interface/output/queues/queue/state/transmit-octets * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts * /qos/interfaces/interface/output/queues/queue/state/dropped-octets + +## 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: + /qos/forwarding-groups/forwarding-group/config/name: + /qos/forwarding-groups/forwarding-group/config/output-queue: + /qos/queues/queue/config/name: + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/config/type: + /qos/classifiers/classifier/terms/term/actions/config/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set: + /qos/classifiers/classifier/terms/term/config/id: + /qos/interfaces/interface/output/queues/queue/config/name: + /qos/interfaces/interface/input/classifiers/classifier/config/name: + /qos/interfaces/interface/output/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight: + + ## State paths: + /qos/forwarding-groups/forwarding-group/state/name: + /qos/forwarding-groups/forwarding-group/state/output-queue: + /qos/queues/queue/state/name: + /qos/classifiers/classifier/state/name: + /qos/classifiers/classifier/state/type: + /qos/classifiers/classifier/terms/term/actions/state/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/state/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/state/dscp-set: + /qos/classifiers/classifier/terms/term/state/id: + /qos/interfaces/interface/output/queues/queue/state/name: + /qos/interfaces/interface/input/classifiers/classifier/state/name: + /qos/interfaces/interface/output/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/weight: + +rpcs: + gnmi: + gNMI.Set: + Replace: \ No newline at end of file diff --git a/feature/qos/otg_tests/two_sp_queue_traffic_test/metadata.textproto b/feature/qos/otg_tests/two_sp_queue_traffic_test/metadata.textproto index bc1316ff266..a439925272e 100644 --- a/feature/qos/otg_tests/two_sp_queue_traffic_test/metadata.textproto +++ b/feature/qos/otg_tests/two_sp_queue_traffic_test/metadata.textproto @@ -18,7 +18,6 @@ platform_exceptions: { vendor: JUNIPER } deviations: { - explicit_interface_ref_definition: true scheduler_input_weight_limit: true } } diff --git a/feature/qos/otg_tests/wrr_traffic_test/README.md b/feature/qos/otg_tests/wrr_traffic_test/README.md index 1a981ac4d5e..c9361579b70 100644 --- a/feature/qos/otg_tests/wrr_traffic_test/README.md +++ b/feature/qos/otg_tests/wrr_traffic_test/README.md @@ -145,3 +145,59 @@ Verify that DUT forwards AF3, AF2, AF1, BE0 and BE1 traffic based on WRR weight. * /qos/interfaces/interface/output/queues/queue/state/transmit-octets * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts * /qos/interfaces/interface/output/queues/queue/state/dropped-octets + +## 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: + /qos/forwarding-groups/forwarding-group/config/name: + /qos/forwarding-groups/forwarding-group/config/output-queue: + /qos/queues/queue/config/name: + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/config/type: + /qos/classifiers/classifier/terms/term/actions/config/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set: + /qos/classifiers/classifier/terms/term/config/id: + /qos/interfaces/interface/output/queues/queue/config/name: + /qos/interfaces/interface/input/classifiers/classifier/config/name: + /qos/interfaces/interface/output/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight: + + ## State paths: + /qos/forwarding-groups/forwarding-group/state/name: + /qos/forwarding-groups/forwarding-group/state/output-queue: + /qos/queues/queue/state/name: + /qos/classifiers/classifier/state/name: + /qos/classifiers/classifier/state/type: + /qos/classifiers/classifier/terms/term/actions/state/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/state/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/state/dscp-set: + /qos/classifiers/classifier/terms/term/state/id: + /qos/interfaces/interface/output/queues/queue/state/name: + /qos/interfaces/interface/input/classifiers/classifier/state/name: + /qos/interfaces/interface/output/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/weight: + +rpcs: + gnmi: + gNMI.Set: + Replace: \ No newline at end of file diff --git a/feature/qos/otg_tests/wrr_traffic_test/metadata.textproto b/feature/qos/otg_tests/wrr_traffic_test/metadata.textproto index d50a81212bb..f81dfe8c4b3 100644 --- a/feature/qos/otg_tests/wrr_traffic_test/metadata.textproto +++ b/feature/qos/otg_tests/wrr_traffic_test/metadata.textproto @@ -18,7 +18,6 @@ platform_exceptions: { vendor: JUNIPER } deviations: { - explicit_interface_ref_definition: true scheduler_input_weight_limit: true } } diff --git a/feature/qos/tests/qos_policy_config_test/README.md b/feature/qos/tests/qos_policy_config_test/README.md index 2a556389500..949e9c4d835 100644 --- a/feature/qos/tests/qos_policy_config_test/README.md +++ b/feature/qos/tests/qos_policy_config_test/README.md @@ -172,3 +172,59 @@ Verify QoS policy feature configuration. * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight + +## 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: + /qos/forwarding-groups/forwarding-group/config/name: + /qos/forwarding-groups/forwarding-group/config/output-queue: + /qos/queues/queue/config/name: + /qos/classifiers/classifier/config/name: + /qos/classifiers/classifier/config/type: + /qos/classifiers/classifier/terms/term/actions/config/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set: + /qos/classifiers/classifier/terms/term/config/id: + /qos/interfaces/interface/output/queues/queue/config/name: + /qos/interfaces/interface/input/classifiers/classifier/config/name: + /qos/interfaces/interface/output/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/config/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight: + + ## State paths: + /qos/forwarding-groups/forwarding-group/state/name: + /qos/forwarding-groups/forwarding-group/state/output-queue: + /qos/queues/queue/state/name: + /qos/classifiers/classifier/state/name: + /qos/classifiers/classifier/state/type: + /qos/classifiers/classifier/terms/term/actions/state/target-group: + /qos/classifiers/classifier/terms/term/conditions/ipv4/state/dscp-set: + /qos/classifiers/classifier/terms/term/conditions/ipv6/state/dscp-set: + /qos/classifiers/classifier/terms/term/state/id: + /qos/interfaces/interface/output/queues/queue/state/name: + /qos/interfaces/interface/input/classifiers/classifier/state/name: + /qos/interfaces/interface/output/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/state/name: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/priority: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/sequence: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/state/type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/id: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/input-type: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/queue: + /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/state/weight: + +rpcs: + gnmi: + gNMI.Set: + Replace: \ No newline at end of file diff --git a/feature/qos/tests/qos_policy_config_test/metadata.textproto b/feature/qos/tests/qos_policy_config_test/metadata.textproto index 2933884e6da..bb92f5f7756 100644 --- a/feature/qos/tests/qos_policy_config_test/metadata.textproto +++ b/feature/qos/tests/qos_policy_config_test/metadata.textproto @@ -9,9 +9,4 @@ platform_exceptions: { platform: { vendor: JUNIPER } - deviations: { - state_path_unsupported: true - drop_weight_leaves_unsupported: true - explicit_interface_ref_definition: true - } } diff --git a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go index e035af3e562..22cb3fe95a8 100644 --- a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go +++ b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go @@ -20,7 +20,6 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/featureprofiles/internal/qoscfg" "github.com/openconfig/ondatra" @@ -1437,13 +1436,11 @@ func testJuniperClassifierConfig(t *testing.T) { if got, want := gnmi.Get(t, dut, classifier.Type().State()), tc.classType; got != want { t.Errorf("classifier.Type().State(): got %v, want %v", got, want) } - if !deviations.StatePathsUnsupported(dut) { - if got, want := gnmi.Get(t, dut, term.Id().State()), tc.termID; got != want { - t.Errorf("term.Id().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, action.TargetGroup().State()), tc.targetGroup; got != want { - t.Errorf("action.TargetGroup().State(): got %v, want %v", got, want) - } + if got, want := gnmi.Get(t, dut, term.Id().State()), tc.termID; got != want { + t.Errorf("term.Id().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, action.TargetGroup().State()), tc.targetGroup; got != want { + t.Errorf("action.TargetGroup().State(): got %v, want %v", got, want) // This Transformer sorts a []uint8. trans := cmp.Transformer("Sort", func(in []uint8) []uint8 { @@ -1483,28 +1480,27 @@ func testJuniperClassifierConfig(t *testing.T) { targetGroup: "target-group-BE1", queueName: "0", }} - if !deviations.StatePathsUnsupported(dut) { - cases = append(cases, - struct { - desc string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - classType oc.E_Qos_Classifier_Type - termID string - dscpSet []uint8 - targetGroup string - queueName string - }{ - desc: "Input Classifier Type IPV6", - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - queueName: "0", - }) - } + cases = append(cases, + struct { + desc string + inputClassifierType oc.E_Input_Classifier_Type + classifier string + classType oc.E_Qos_Classifier_Type + termID string + dscpSet []uint8 + targetGroup string + queueName string + }{ + desc: "Input Classifier Type IPV6", + inputClassifierType: oc.Input_Classifier_Type_IPV6, + classifier: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "0", + targetGroup: "target-group-BE1", + dscpSet: []uint8{0, 1, 2, 3}, + queueName: "0", + }) + dp := dut.Port(t, "port1") ip := &oc.Interface{Name: ygot.String(dp.Name())} ip.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd @@ -1634,25 +1630,23 @@ func testJuniperSchedulerPoliciesConfig(t *testing.T) { scheduler := gnmi.OC().Qos().SchedulerPolicy("scheduler").Scheduler(tc.sequence) input := scheduler.Input(tc.inputID) - if !deviations.StatePathsUnsupported(dut) { - if got, want := gnmi.Get(t, dut, input.Id().State()), tc.inputID; got != want { - t.Errorf("input.Id().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, input.InputType().State()), oc.Input_InputType_QUEUE; got != want { - t.Errorf("input.InputType().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, input.Weight().State()), tc.weight; got != want { - t.Errorf("input.Weight().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, input.Queue().State()), tc.queueName; got != want { - t.Errorf("input.Queue().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, scheduler.Sequence().State()), tc.sequence; got != want { - t.Errorf("scheduler.Sequence().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, scheduler.Priority().State()), tc.priority; got != want { - t.Errorf("scheduler.Priority().State(): got %v, want %v", got, want) - } + if got, want := gnmi.Get(t, dut, input.Id().State()), tc.inputID; got != want { + t.Errorf("input.Id().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, input.InputType().State()), oc.Input_InputType_QUEUE; got != want { + t.Errorf("input.InputType().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, input.Weight().State()), tc.weight; got != want { + t.Errorf("input.Weight().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, input.Queue().State()), tc.queueName; got != want { + t.Errorf("input.Queue().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, scheduler.Sequence().State()), tc.sequence; got != want { + t.Errorf("scheduler.Sequence().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, scheduler.Priority().State()), tc.priority; got != want { + t.Errorf("scheduler.Priority().State(): got %v, want %v", got, want) } } @@ -1690,25 +1684,21 @@ func testJuniperSchedulerPoliciesConfig(t *testing.T) { if got, want := gnmi.Get(t, dut, wredUniform.MaxDropProbabilityPercent().State()), ecnConfig.maxDropProbabilityPercent; got != want { t.Errorf("wredUniform.MaxDropProbabilityPercent().State(): got %v, want %v", got, want) } - if !deviations.StatePathsUnsupported(dut) { - if got, want := gnmi.Get(t, dut, wredUniform.MinThreshold().State()), ecnConfig.minThreshold; got != want { - t.Errorf("wredUniform.MinThreshold().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, wredUniform.MaxThreshold().State()), ecnConfig.maxThreshold; got != want { - t.Errorf("wredUniform.MaxThreshold().State(): got %v, want %v", got, want) - } + if got, want := gnmi.Get(t, dut, wredUniform.MinThreshold().State()), ecnConfig.minThreshold; got != want { + t.Errorf("wredUniform.MinThreshold().State(): got %v, want %v", got, want) } - if !deviations.DropWeightLeavesUnsupported(dut) { - uniform.SetDrop(ecnConfig.dropEnabled) - uniform.SetWeight(ecnConfig.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) + if got, want := gnmi.Get(t, dut, wredUniform.MaxThreshold().State()), ecnConfig.maxThreshold; got != want { + t.Errorf("wredUniform.MaxThreshold().State(): got %v, want %v", got, want) + } + uniform.SetDrop(ecnConfig.dropEnabled) + uniform.SetWeight(ecnConfig.weight) + gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - if got, want := gnmi.Get(t, dut, wredUniform.Drop().State()), ecnConfig.dropEnabled; got != want { - t.Errorf("wredUniform.Drop().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, wredUniform.Weight().State()), ecnConfig.weight; got != want { - t.Errorf("wredUniform.Weight().State(): got %v, want %v", got, want) - } + if got, want := gnmi.Get(t, dut, wredUniform.Drop().State()), ecnConfig.dropEnabled; got != want { + t.Errorf("wredUniform.Drop().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, wredUniform.Weight().State()), ecnConfig.weight; got != want { + t.Errorf("wredUniform.Weight().State(): got %v, want %v", got, want) } cases := []struct { @@ -1752,16 +1742,14 @@ func testJuniperSchedulerPoliciesConfig(t *testing.T) { // Verify the policy is applied by checking the telemetry path state values. policy := gnmi.OC().Qos().Interface(dp.Name()).Output().SchedulerPolicy() outQueue := gnmi.OC().Qos().Interface(dp.Name()).Output().Queue(tc.targetGroup) - if !deviations.StatePathsUnsupported(dut) { - if got, want := gnmi.Get(t, dut, policy.Name().State()), "scheduler"; got != want { - t.Errorf("policy.Name().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, outQueue.Name().State()), tc.targetGroup; got != want { - t.Errorf("outQueue.Name().State(): got %v, want %v", got, want) - } - if got, want := gnmi.Get(t, dut, outQueue.QueueManagementProfile().State()), "DropProfile"; got != want { - t.Errorf("outQueue.QueueManagementProfile().State(): got %v, want %v", got, want) - } + if got, want := gnmi.Get(t, dut, policy.Name().State()), "scheduler"; got != want { + t.Errorf("policy.Name().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, outQueue.Name().State()), tc.targetGroup; got != want { + t.Errorf("outQueue.Name().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, outQueue.QueueManagementProfile().State()), "DropProfile"; got != want { + t.Errorf("outQueue.QueueManagementProfile().State(): got %v, want %v", got, want) } if got, want := gnmi.Get(t, dut, wredUniform.EnableEcn().State()), ecnConfig.ecnEnabled; got != want { t.Errorf("wredUniform.EnableEcn().State(): got %v, want %v", got, want) diff --git a/feature/experimental/replay/tests/diff_command_trees/README.md b/feature/replay/tests/diff_command_trees/README.md similarity index 62% rename from feature/experimental/replay/tests/diff_command_trees/README.md rename to feature/replay/tests/diff_command_trees/README.md index 91720b7d422..61ddc439b53 100644 --- a/feature/experimental/replay/tests/diff_command_trees/README.md +++ b/feature/replay/tests/diff_command_trees/README.md @@ -7,3 +7,17 @@ diff the command trees" error when applying certain gNMI config on Arista devices. At this time, no vendor is expected to run this test. + +## OpenConfig Path and RPC Coverage + +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` diff --git a/feature/experimental/replay/tests/diff_command_trees/diff_command_trees_test.go b/feature/replay/tests/diff_command_trees/diff_command_trees_test.go similarity index 100% rename from feature/experimental/replay/tests/diff_command_trees/diff_command_trees_test.go rename to feature/replay/tests/diff_command_trees/diff_command_trees_test.go diff --git a/feature/experimental/replay/tests/diff_command_trees/metadata.textproto b/feature/replay/tests/diff_command_trees/metadata.textproto similarity index 100% rename from feature/experimental/replay/tests/diff_command_trees/metadata.textproto rename to feature/replay/tests/diff_command_trees/metadata.textproto diff --git a/feature/experimental/replay/tests/p4rt_replay/README.md b/feature/replay/tests/p4rt_replay/README.md similarity index 54% rename from feature/experimental/replay/tests/p4rt_replay/README.md rename to feature/replay/tests/p4rt_replay/README.md index 6861b35f9cb..f23fe835e7e 100644 --- a/feature/experimental/replay/tests/p4rt_replay/README.md +++ b/feature/replay/tests/p4rt_replay/README.md @@ -6,3 +6,17 @@ This is an example record/replay test. It is meant to reproduce an error when replaying P4RT messages. At this time, no vendor is expected to run this test. + +## OpenConfig Path and RPC Coverage + +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` diff --git a/feature/experimental/replay/tests/p4rt_replay/metadata.textproto b/feature/replay/tests/p4rt_replay/metadata.textproto similarity index 100% rename from feature/experimental/replay/tests/p4rt_replay/metadata.textproto rename to feature/replay/tests/p4rt_replay/metadata.textproto diff --git a/feature/experimental/replay/tests/p4rt_replay/p4rt_replay_test.go b/feature/replay/tests/p4rt_replay/p4rt_replay_test.go similarity index 100% rename from feature/experimental/replay/tests/p4rt_replay/p4rt_replay_test.go rename to feature/replay/tests/p4rt_replay/p4rt_replay_test.go diff --git a/feature/replay/tests/presession_test/README.md b/feature/replay/tests/presession_test/README.md new file mode 100644 index 00000000000..f1528f687b0 --- /dev/null +++ b/feature/replay/tests/presession_test/README.md @@ -0,0 +1,20 @@ +# Replay-1.0: Record/replay presession test + +## Summary + +This is an example record/replay test. +At this time, no vendor is expected to run this test. + +## OpenConfig Path and RPC Coverage + +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` diff --git a/feature/experimental/replay/tests/presession_test/metadata.textproto b/feature/replay/tests/presession_test/metadata.textproto similarity index 100% rename from feature/experimental/replay/tests/presession_test/metadata.textproto rename to feature/replay/tests/presession_test/metadata.textproto diff --git a/feature/experimental/replay/tests/presession_test/presession_test.go b/feature/replay/tests/presession_test/presession_test.go similarity index 100% rename from feature/experimental/replay/tests/presession_test/presession_test.go rename to feature/replay/tests/presession_test/presession_test.go diff --git a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/README.md b/feature/security/aaa/kne_tests/tls_authentication_over_grpc_test/README.md similarity index 91% rename from feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/README.md rename to feature/security/aaa/kne_tests/tls_authentication_over_grpc_test/README.md index 4515b12bb87..f1e22c2734e 100644 --- a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/README.md +++ b/feature/security/aaa/kne_tests/tls_authentication_over_grpc_test/README.md @@ -25,17 +25,13 @@ and gRPC connections. * Ensure gNMI set/get requests are denied with incorrect login or incorrect password. -## Config Parameter coverage - -N/A - -## Telemetry Parameter coverage - -N/A - -## Protocol/RPC Parameter coverage - -N/A +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Set: + gNMI.Subscribe: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/metadata.textproto b/feature/security/aaa/kne_tests/tls_authentication_over_grpc_test/metadata.textproto similarity index 100% rename from feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/metadata.textproto rename to feature/security/aaa/kne_tests/tls_authentication_over_grpc_test/metadata.textproto diff --git a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go b/feature/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go similarity index 100% rename from feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go rename to feature/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go diff --git a/feature/security/gnsi/acctz/README.md b/feature/security/gnsi/acctz/README.md index b814c93a42f..2e40a67eb68 100644 --- a/feature/security/gnsi/acctz/README.md +++ b/feature/security/gnsi/acctz/README.md @@ -34,10 +34,10 @@ Create a library of device configuration to be used for all of the gNSI.acctz.v1 ## gNSI Accounting (acctz) Tests: - [ACCTZ-1.1 Record Subscribe Full](RecordSubscribeFull) -- [ACCTZ-2.1 Record Subscribe Partial](RecordSubscribePartial) +- [ACCTZ-2.1 Record Subscribe Partial](tests/record_subscribe_partial) - [ACCTZ-3.1 Record Subscribe Non-gRPC](tests/record_subscribe_non_grpc) - [ACCTZ-4.1 Record History Truncation](RecordHistoryTruncation/) -- [ACCTZ-4.2 Record Payload Truncation](RecordPayloadTruncation/) +- [ACCTZ-4.2 Record Payload Truncation](tests/record_payload_truncation) - [ACCTZ-5.1 Record Subscribe Idle Timeout](RecordSubscribeIdleTimeout/) - [ACCTZ-6.1 Record Subscribe Idle Timeout DoA](RecordSubscribeIdleTimeoutDoA/) - [ACCTZ-7.1 Accounting Authentication Failure - Multi-transaction](AccountingAuthenFailMulti/) diff --git a/feature/security/gnsi/acctz/RecordPayloadTruncation/README.md b/feature/security/gnsi/acctz/tests/record_payload_truncation/README.md similarity index 94% rename from feature/security/gnsi/acctz/RecordPayloadTruncation/README.md rename to feature/security/gnsi/acctz/tests/record_payload_truncation/README.md index 8bf0782019c..fe10d942750 100644 --- a/feature/security/gnsi/acctz/RecordPayloadTruncation/README.md +++ b/feature/security/gnsi/acctz/tests/record_payload_truncation/README.md @@ -1,4 +1,4 @@ -# ACCTZ-4.2 - gNSI.acctz.v1 (Accounting) Test Record Payload Truncation +# ACCTZ-4.2: Record Payload Truncation ## Summary diff --git a/feature/security/gnsi/acctz/tests/record_payload_truncation/metadata.textproto b/feature/security/gnsi/acctz/tests/record_payload_truncation/metadata.textproto new file mode 100644 index 00000000000..714851304ee --- /dev/null +++ b/feature/security/gnsi/acctz/tests/record_payload_truncation/metadata.textproto @@ -0,0 +1,8 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "ae09edfd-f64e-4095-b56d-021ce29b659b" +plan_id: "ACCTZ-4.2" +description: "Record Payload Truncation" +testbed: TESTBED_DUT +platform_exceptions: {} diff --git a/feature/security/gnsi/acctz/tests/record_payload_truncation/record_payload_truncation_test.go b/feature/security/gnsi/acctz/tests/record_payload_truncation/record_payload_truncation_test.go new file mode 100644 index 00000000000..ec481d3d840 --- /dev/null +++ b/feature/security/gnsi/acctz/tests/record_payload_truncation/record_payload_truncation_test.go @@ -0,0 +1,122 @@ +// 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 record_payload_truncation_test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/gnsi/acctz" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +type recordRequestResult struct { + record *acctz.RecordResponse + err error +} + +func sendOversizedPayload(t *testing.T, dut *ondatra.DUTDevice) { + // Perhaps other vendors will need a different payload/size/etc., for now we'll just send a + // giant set of network instances + static routes which should hopefully work for everyone. + ocRoot := &oc.Root{} + + for i := 0; i < 50; i++ { + ni := ocRoot.GetOrCreateNetworkInstance(fmt.Sprintf("acctz-test-ni-%d", i)) + ni.SetDescription("This is a pointlessly long description in order to make the payload bigger.") + ni.SetType(oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF) + staticProtocol := ni.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, "static") + for j := 0; j < 254; j++ { + staticProtocol.GetOrCreateStatic(fmt.Sprintf("10.%d.0.0/24", j)) + } + } + + gnmi.Update(t, dut, gnmi.OC().Config(), ocRoot) +} + +func TestAccountzRecordPayloadTruncation(t *testing.T) { + dut := ondatra.DUT(t, "dut") + startTime := time.Now() + sendOversizedPayload(t, dut) + acctzClient := dut.RawAPIs().GNSI(t).Acctz() + + acctzSubClient, err := acctzClient.RecordSubscribe(context.Background()) + if err != nil { + t.Fatalf("Failed getting accountz record subscribe client, error: %s", err) + } + + err = acctzSubClient.Send(&acctz.RecordRequest{ + Timestamp: timestamppb.New(startTime), + }) + if err != nil { + t.Fatalf("Failed sending record request, error: %s", err) + } + + for { + r := make(chan recordRequestResult) + + go func(r chan recordRequestResult) { + var response *acctz.RecordResponse + response, err = acctzSubClient.Recv() + r <- recordRequestResult{ + record: response, + err: err, + } + }(r) + + var done bool + var resp recordRequestResult + + select { + case rr := <-r: + resp = rr + case <-time.After(10 * time.Second): + done = true + } + + if done { + t.Fatal("Done receiving records and did not find our record...") + } + + if resp.err != nil { + t.Fatalf("Failed receiving record response, error: %s", resp.err) + } + + grpcServiceRecord := resp.record.GetGrpcService() + + if grpcServiceRecord.GetServiceType() != acctz.GrpcService_GRPC_SERVICE_TYPE_GNMI { + // Not our gnmi set, nothing to see here. + continue + } + + if grpcServiceRecord.RpcName != "/gnmi.gNMI/Set" { + continue + } + + if grpcServiceRecord.GetPayloadIstruncated() { + t.Log("Found truncated payload of gnmi.Set after start timestamp, success!") + break + } + } +} diff --git a/feature/security/gnsi/acctz/RecordSubscribePartial/README.md b/feature/security/gnsi/acctz/tests/record_subscribe_partial/README.md similarity index 96% rename from feature/security/gnsi/acctz/RecordSubscribePartial/README.md rename to feature/security/gnsi/acctz/tests/record_subscribe_partial/README.md index 69e685d4b76..f7b38bf2cb2 100644 --- a/feature/security/gnsi/acctz/RecordSubscribePartial/README.md +++ b/feature/security/gnsi/acctz/tests/record_subscribe_partial/README.md @@ -1,4 +1,4 @@ -# ACCTZ-2.1 - gNSI.acctz.v1 (Accounting) Test Record Subscribe Partial +# ACCTZ-2.1: Record Subscribe Partial ## Summary Test RecordSubscribe for records since a non-zero timestamp diff --git a/feature/security/gnsi/acctz/tests/record_subscribe_partial/metadata.textproto b/feature/security/gnsi/acctz/tests/record_subscribe_partial/metadata.textproto new file mode 100644 index 00000000000..bb04d5949b7 --- /dev/null +++ b/feature/security/gnsi/acctz/tests/record_subscribe_partial/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "31dbda6b-5034-4a95-880c-25e4ce0676c4" +plan_id: "ACCTZ-2.1" +description: "Record Subscribe Partial" +testbed: TESTBED_DUT \ No newline at end of file diff --git a/feature/security/gnsi/acctz/tests/record_subscribe_partial/record_subscribe_partial_test.go b/feature/security/gnsi/acctz/tests/record_subscribe_partial/record_subscribe_partial_test.go new file mode 100644 index 00000000000..51334465192 --- /dev/null +++ b/feature/security/gnsi/acctz/tests/record_subscribe_partial/record_subscribe_partial_test.go @@ -0,0 +1,201 @@ +// 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 recordsubscribepartial + +import ( + "context" + "encoding/json" + "reflect" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "google.golang.org/protobuf/testing/protocmp" + + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/security/acctz" + acctzpb "github.com/openconfig/gnsi/acctz" + "github.com/openconfig/ondatra" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type recordRequestResult struct { + record *acctzpb.RecordResponse + err error +} + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func prettyPrint(i interface{}) string { + s, _ := json.MarshalIndent(i, "", "\t") + return string(s) +} + +func TestAccountzRecordSubscribePartial(t *testing.T) { + dut := ondatra.DUT(t, "dut") + acctz.SetupUsers(t, dut, false) + var records []*acctzpb.RecordResponse + + // Put enough time between the test starting and any prior events so we can easily know where + // our records start. + time.Sleep(5 * time.Second) + + startTime := time.Now() + newRecords := acctz.SendGnmiRPCs(t, dut) + records = append(records, newRecords...) + newRecords = acctz.SendGnoiRPCs(t, dut) + records = append(records, newRecords...) + newRecords = acctz.SendGnsiRPCs(t, dut) + records = append(records, newRecords...) + newRecords = acctz.SendGribiRPCs(t, dut) + records = append(records, newRecords...) + newRecords = acctz.SendP4rtRPCs(t, dut) + records = append(records, newRecords...) + + // Quick sleep to ensure all the records have been processed/ready for us. + time.Sleep(5 * time.Second) + + // Get gNSI record subscribe client. + acctzClient := dut.RawAPIs().GNSI(t).AcctzStream() + acctzSubClient, err := acctzClient.RecordSubscribe(context.Background(), &acctzpb.RecordRequest{ + Timestamp: ×tamppb.Timestamp{ + Seconds: 0, + Nanos: 0, + }, + }) + if err != nil { + t.Fatalf("Failed sending first accountz record request, error: %s", err) + } + + firstResponse, err := acctzSubClient.Recv() + if err != nil { + t.Fatalf("Failed receiving first record response, error: %s", err) + } + + // Fetch fresh client. + acctzClient = dut.RawAPIs().GNSI(t).AcctzStream() + acctzSubClient, err = acctzClient.RecordSubscribe(context.Background(), &acctzpb.RecordRequest{ + Timestamp: firstResponse.Timestamp, + }) + if err != nil { + t.Fatalf("Failed sending second accountz record request, error: %s", err) + } + defer acctzSubClient.CloseSend() + + secondResponse, err := acctzSubClient.Recv() + if err != nil { + t.Fatalf("Failed receiving second record response, error: %s", err) + } + + if reflect.DeepEqual(firstResponse, secondResponse) { + t.Fatalf("Accountz server responded with same event on subsequent record request.") + } + + var recordIdx int + var lastTimestampUnixMillis int64 + r := make(chan recordRequestResult) + + // Ignore proto fields which are set internally by the DUT (cannot be matched exactly) + // and compare them manually later. + popts := []cmp.Option{protocmp.Transform(), + protocmp.IgnoreFields(&acctzpb.RecordResponse{}, "timestamp", "task_ids"), + protocmp.IgnoreFields(&acctzpb.AuthzDetail{}, "detail"), + protocmp.IgnoreFields(&acctzpb.SessionInfo{}, "channel_id"), + } + + for { + if recordIdx >= len(records) { + t.Log("Out of records to process...") + break + } + + // Read single acctz record from stream into channel. + go func(r chan recordRequestResult) { + var response *acctzpb.RecordResponse + response, err = acctzSubClient.Recv() + r <- recordRequestResult{ + record: response, + err: err, + } + }(r) + + var done bool + var resp recordRequestResult + + // Read acctz record from channel for evaluation. + // Timeout and exit if no records received on the channel for some time. + select { + case rr := <-r: + resp = rr + case <-time.After(10 * time.Second): + done = true + } + + if done { + t.Log("Done receiving records...") + break + } + + if resp.err != nil { + t.Fatalf("Failed receiving record response, error: %s", resp.err) + } + + if !resp.record.Timestamp.AsTime().After(startTime) { + // Skipping record, was before test start time. + continue + } + + timestamp := resp.record.Timestamp.AsTime() + if timestamp.UnixMilli() == lastTimestampUnixMillis { + // This ensures that timestamps are actually changing for each record. + t.Errorf("Timestamp is the same as the previous timestamp, this shouldn't be possible!, Record Details: %s", prettyPrint(resp.record)) + } + lastTimestampUnixMillis = timestamp.UnixMilli() + + // Verify acctz proto bits. + if diff := cmp.Diff(resp.record, records[recordIdx], popts...); diff != "" { + t.Errorf("got diff in got/want: %s", diff) + } + + // Verify record timestamp is after request timestamp. + if !timestamp.After(firstResponse.Timestamp.AsTime()) { + t.Errorf("Record timestamp is before record request timestamp %v, Record Details: %v", firstResponse.Timestamp.AsTime(), prettyPrint(resp.record)) + } + + // This channel check maybe should just go away entirely -- see: + // https://github.com/openconfig/gnsi/issues/98 + // In case of Nokia this is being set to the aaa session id just to have some hopefully + // useful info in this field to identify a "session" (even if it isn't necessarily ssh/grpc + // directly). + if resp.record.GetSessionInfo().GetChannelId() == "" { + t.Errorf("Channel Id is not populated for record: %v", prettyPrint(resp.record)) + } + + // Verify authz detail is populated for denied rpcs. + authzInfo := resp.record.GetGrpcService().GetAuthz() + if authzInfo.Status == acctzpb.AuthzDetail_AUTHZ_STATUS_DENY && authzInfo.GetDetail() == "" { + t.Errorf("Authorization detail is not populated for record: %v", prettyPrint(resp.record)) + } + + t.Logf("Processed Record: %s", prettyPrint(resp.record)) + recordIdx++ + } + + if recordIdx != len(records) { + t.Fatal("Did not process all records.") + } +} diff --git a/feature/security/gnsi/certz/client_certificates/README.md b/feature/security/gnsi/certz/client_certificates/README.md index f34513e3eac..bd09261d089 100644 --- a/feature/security/gnsi/certz/client_certificates/README.md +++ b/feature/security/gnsi/certz/client_certificates/README.md @@ -42,8 +42,8 @@ gRPC service. Perform this for both RSA and ECDSA signed CA bundles and certificates. -Perform this for the permutations of 1, 2, 10, 1000 CA -trust_bundle configurations: (## indicates the 1, 2, 10, 1000 CA testdata) +Perform this for the permutations of 1, 2, 10, 1000, 20000 CA +trust_bundle configurations: (## indicates the 1, 2, 10, 1000, 20000 CA testdata) 1) Load the correct key-type trust bundle onto the device and client system: ca-##/trust_bundle_##_rsa.pem diff --git a/feature/security/gnsi/certz/test_data/README.md b/feature/security/gnsi/certz/test_data/README.md index 736b7cd9486..3ccc3362143 100644 --- a/feature/security/gnsi/certz/test_data/README.md +++ b/feature/security/gnsi/certz/test_data/README.md @@ -10,6 +10,7 @@ Creation of test data for use in TLS tests. * ca-02 - a set of two CAs where signatures are RSA or ECDSA. * ca-10 - a set of ten CAs where signatures are RSA or ECDSA. * ca-1000 - a set of one thousand CAs where signatures are RSA or ECDSA. + * ca-20000 - a set of twenty thousand CAs where signatures are RSA or ECDSA. * server_cert.cnf/server_cert_ext.cnf - server openssl profile configuration * client_cert.cnf/client_cert_ext.cnf - client openssl profile configuration diff --git a/feature/security/gnsi/certz/test_data/cleanup.sh b/feature/security/gnsi/certz/test_data/cleanup.sh index a8afee9db65..95b7cbaf6da 100755 --- a/feature/security/gnsi/certz/test_data/cleanup.sh +++ b/feature/security/gnsi/certz/test_data/cleanup.sh @@ -1,4 +1,5 @@ #!/bin/sh -for d in 01 02 10 1000; do - rm -f ca-${d}/* +for d in 01 02 10 1000 20000; do + find ca-${d}/ -type f -exec /usr/bin/rm -f {} \; + /usr/bin/rm -rf ca-${d}/ done diff --git a/feature/security/gnsi/certz/test_data/mk_cas.sh b/feature/security/gnsi/certz/test_data/mk_cas.sh index 50dda0cdfdd..06febedb804 100755 --- a/feature/security/gnsi/certz/test_data/mk_cas.sh +++ b/feature/security/gnsi/certz/test_data/mk_cas.sh @@ -5,7 +5,7 @@ # # The list of directories of CA contents, also the count of CAs built # in each directory. -DIRS=(01 02 10 1000) +DIRS=(01 02 10 1000 20000) # The types of signatures to support for the CA Certs. TYPES=(rsa ecdsa) @@ -20,14 +20,14 @@ RSAKEYLEN=2048 LIFETIME=3650 # Create RSA and ECDSA CA keys, and associated certificates. -for d in ${DIRS[@]} ; do +for d in ${DIRS[@]} ; do if [ ! -d ca-${d} ] ; then mkdir ca-${d} fi # Create a CA key and certificate for each of the DIRS count of # keys / certs. Do this for each of the TYPES key types. for k in $(seq 1 ${d}); do - OFFSET=$(printf "%04i" ${k}) + OFFSET=$(printf "%05i" ${k}) for t in ${TYPES[@]}; do # Generate the appropriate key type keys. case ${t} in @@ -53,6 +53,11 @@ done for d in ${DIRS[@]}; do for t in ${TYPES[@]}; do cat ca-${d}/ca-*-${t}-cert.pem > ca-${d}/trust_bundle_${d}_${t}.pem + CERTS="" + for cf in ca-${d}/ca-*-${t}-cert.pem; do + CERTS="${CERTS} -certfile ${cf}" + done + openssl crl2pkcs7 -nocrl ${CERTS} -out ca-${d}/trust_bundle_${d}_${t}.p7b done done @@ -67,7 +72,7 @@ for d in ${DIRS[@]}; do mkdir ca-${d} fi for t in ${TYPES[@]}; do - OFFSET=$(printf "%04i" ${d}) + OFFSET=$(printf "%05i" ${d}) # Create both client and server cert keys for each type. # use a/b here to signal the required 2 client or server certs/keys. for g in a b; do diff --git a/feature/security/gnsi/certz/trust_bundle/README.md b/feature/security/gnsi/certz/trust_bundle/README.md index eda1bf030de..fbbee7d1e6d 100644 --- a/feature/security/gnsi/certz/trust_bundle/README.md +++ b/feature/security/gnsi/certz/trust_bundle/README.md @@ -62,6 +62,7 @@ Load the server certificate and key from each of the following CA sets: * ca-02 * ca-10 * ca-1000 + * ca-20000 Each service must be configured to use the appropriate certificate and validate that certificate using the included trust_bundle. diff --git a/feature/security/gnsi/credentialz/tests/README.md b/feature/security/gnsi/credentialz/tests/README.md index 08442078f8d..a6cd29841d9 100644 --- a/feature/security/gnsi/credentialz/tests/README.md +++ b/feature/security/gnsi/credentialz/tests/README.md @@ -169,7 +169,7 @@ and * Provide incorrect password, but correct username. * Authentication must fail. -### Credentialz-2, SSH pasword login disallowed +### Credentialz-2, SSH password login disallowed #### Setup * Set a username of `testuser` diff --git a/feature/security/gnsi/credentialz/tests/hiba_authentication/README.md b/feature/security/gnsi/credentialz/tests/hiba_authentication/README.md new file mode 100644 index 00000000000..89f3fc884c4 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/hiba_authentication/README.md @@ -0,0 +1,55 @@ +# Credentialz-5: Hiba Authentication + +## Summary + +Test that Credentialz properly configures (hiba) certificate authentication. + + +## Procedure + +* Follow the instructions for setting up a [HIBA CA](https://github.com/google/hiba/blob/main/CA.md) +* Set DUT allowed authentication types to only public key using gnsi.Credentialz +* Create a user `testuser` (with no certificate at this point) +* Set the AuthorizedPrincipalsCommand by setting the tool to `TOOL_HIBA_DEFAULT` + +* Perform the following tests and assert the expected result: + * Case 1: Failure + * Authenticate with the `testuser` username and the previously created public key via SSH + * Assert that authentication has failed (because the DUT doesn't have the Hiba host certificate at this point) + * Ensure that access rejects telemetry counter is incremented `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-rejects` + * Case 2: Success + * Configure the dut with the Hiba host certificate. + * Authenticate with the `testuser` username the previously created public key via SSH + * Assert that authentication has been successful + * Ensure telemetry values for version and created-on match the values set by + RotateHostParameters for + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:active-host-certificate-version` + and + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:active-host-certificate-created-on` + * Ensure that access accept telemetry counters are incremented after successful login + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-accepts` + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:last-access-accept` + + +## 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: + ## State Paths ## + /system/ssh-server/state/active-host-certificate-version: + /system/ssh-server/state/active-host-certificate-created-on: + /system/ssh-server/state/counters/access-accepts: + /system/ssh-server/state/counters/last-access-accept: + /system/ssh-server/state/counters/access-rejects: + +rpcs: + gnsi: + credentialz.v1.Credentialz.RotateHostParameters: +``` + + +## Minimum DUT platform requirement + +N/A \ No newline at end of file diff --git a/feature/security/gnsi/credentialz/tests/hiba_authentication/hiba_authentication_test.go b/feature/security/gnsi/credentialz/tests/hiba_authentication/hiba_authentication_test.go new file mode 100644 index 00000000000..f8678483fdb --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/hiba_authentication/hiba_authentication_test.go @@ -0,0 +1,163 @@ +// 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 hibaauthentication + +import ( + "fmt" + "os" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/featureprofiles/internal/security/credz" + "github.com/openconfig/ondatra/gnmi" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + cpb "github.com/openconfig/gnsi/credentialz" + "github.com/openconfig/ondatra" +) + +const ( + username = "testuser" + hostCertificateVersion = "v1.0" +) + +var ( + hostCertificateCreatedOn = time.Now().Unix() +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestCredentialz(t *testing.T) { + dut := ondatra.DUT(t, "dut") + target := credz.GetDutTarget(t, dut) + + // Create temporary directory for storing ssh keys/certificates. + dir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatalf("creating temp dir, err: %s", err) + } + defer func(dir string) { + err = os.RemoveAll(dir) + if err != nil { + t.Logf("error removing temp directory, error: %s", err) + } + }(dir) + + credz.CreateHibaKeys(t, dir) + credz.SetupUser(t, dut, username) + + // Set only public key authentication for our test. + credz.RotateAuthenticationTypes(t, dut, []cpb.AuthenticationType{ + cpb.AuthenticationType_AUTHENTICATION_TYPE_PUBKEY, + }) + + // Setup hiba for authorized principals command. + credz.RotateAuthorizedPrincipalCheck(t, dut, cpb.AuthorizedPrincipalCheckRequest_TOOL_HIBA_DEFAULT) + + t.Run("auth should fail hiba host certificate not present", func(t *testing.T) { + var startingRejectCounter uint64 + if !deviations.SSHServerCountersUnsupported(dut) { + startingRejectCounter, _ = credz.GetRejectTelemetry(t, dut) + } + + // Verify ssh with hiba fails as expected. + _, err := credz.SSHWithCertificate(t, target, username, fmt.Sprintf("%s/users", dir)) + if err == nil { + t.Fatalf("Dialing ssh succeeded, but we expected to fail") + } + + if !deviations.SSHServerCountersUnsupported(dut) { + endingRejectCounter, _ := credz.GetRejectTelemetry(t, dut) + if endingRejectCounter <= startingRejectCounter { + t.Fatalf("SSH server reject counter did not increment after unsuccessful login. startCounter: %v, endCounter: %v", startingRejectCounter, endingRejectCounter) + } + } + }) + + t.Run("auth should succeed ssh public key authorized for user with hiba granted certificate", func(t *testing.T) { + // Push host key/certificate to the dut. + credz.RotateAuthenticationArtifacts(t, + dut, + fmt.Sprintf("%s/hosts", dir), + fmt.Sprintf("%s/hosts", dir), + hostCertificateVersion, + uint64(hostCertificateCreatedOn), + ) + + // Setup trusted user ca on the dut. + credz.RotateTrustedUserCA(t, dut, dir) + + var startingAcceptCounter, startingLastAcceptTime uint64 + if !deviations.SSHServerCountersUnsupported(dut) { + startingAcceptCounter, startingLastAcceptTime = credz.GetAcceptTelemetry(t, dut) + } + + _, err := credz.SSHWithCertificate(t, target, username, fmt.Sprintf("%s/users", dir)) + if err != nil { + t.Fatalf("Dialing ssh failed, but we expected to succeed, errror: %s", err) + } + + // Verify ssh counters. + if !deviations.SSHServerCountersUnsupported(dut) { + endingAcceptCounter, endingLastAcceptTime := credz.GetAcceptTelemetry(t, dut) + if endingAcceptCounter <= startingAcceptCounter { + t.Fatalf("SSH server accept counter did not increment after successful login. startCounter: %v, endCounter: %v", startingAcceptCounter, endingAcceptCounter) + } + if startingLastAcceptTime == endingLastAcceptTime { + t.Fatalf("SSH server accept last timestamp did not update after successful login. Timestamp: %v", endingLastAcceptTime) + } + } + + // Verify host certificate telemetry. + sshServer := gnmi.Get(t, dut, gnmi.OC().System().SshServer().State()) + gotHostCertificateVersion := sshServer.GetActiveHostCertificateVersion() + if !cmp.Equal(gotHostCertificateVersion, hostCertificateVersion) { + t.Fatalf( + "Telemetry reports host certificate version is not correct\n\tgot: %s\n\twant: %s", + gotHostCertificateVersion, hostCertificateVersion, + ) + } + gotHostCertificateCreatedOn := sshServer.GetActiveHostCertificateCreatedOn() + if !cmp.Equal(time.Unix(0, int64(gotHostCertificateCreatedOn)), time.Unix(hostCertificateCreatedOn, 0)) { + t.Fatalf( + "Telemetry reports host certificate created on is not correct\n\tgot: %d\n\twant: %d", + gotHostCertificateCreatedOn, hostCertificateCreatedOn, + ) + } + }) + + t.Cleanup(func() { + // Cleanup to remove previous policy which only allowed key auth to make sure we don't leave dut in a + // state where we can't reset config for further tests. + credz.RotateAuthenticationTypes(t, dut, []cpb.AuthenticationType{ + cpb.AuthenticationType_AUTHENTICATION_TYPE_PASSWORD, + cpb.AuthenticationType_AUTHENTICATION_TYPE_PUBKEY, + cpb.AuthenticationType_AUTHENTICATION_TYPE_KBDINTERACTIVE, + }) + + // Remove user ca so subsequent fail cases work. + credz.RotateTrustedUserCA(t, dut, "") + + // Clear hiba for authorized principals command. + credz.RotateAuthorizedPrincipalCheck(t, dut, cpb.AuthorizedPrincipalCheckRequest_TOOL_UNSPECIFIED) + + // Remove host artifacts from the dut. + credz.RotateAuthenticationArtifacts(t, dut, "", "", "", 0) + }) +} diff --git a/feature/security/gnsi/credentialz/tests/hiba_authentication/metadata.textproto b/feature/security/gnsi/credentialz/tests/hiba_authentication/metadata.textproto new file mode 100644 index 00000000000..d27061b81a2 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/hiba_authentication/metadata.textproto @@ -0,0 +1,15 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "4083a01e-9b52-44c0-aa5c-994e78be66fe" +plan_id: "Credentialz-5" +description: "Hiba Authentication" +testbed: TESTBED_DUT +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + ssh_server_counters_unsupported: true + } +} diff --git a/feature/security/gnsi/credentialz/tests/host_certificates/README.md b/feature/security/gnsi/credentialz/tests/host_certificates/README.md new file mode 100644 index 00000000000..de9e92bb424 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/host_certificates/README.md @@ -0,0 +1,45 @@ +# Credentialz-3: Host Certificates + +## Summary + +Test that Credentialz can properly fetch and push SSH host certificates, and that the DUT sends +this certificate during SSH authentication. + + +## Procedure + +* Fetch the DUT's public key using gnsi.Credentialz + * If DUT doesnt have one, generate and set the private key using gnsi.Credentialz. +* Sign the DUT's public key with the ca key to create a host certificate. +* Add the newly created certificate to the DUT using gnsi.Credentialz +* Perform the following tests and assert the expected result: + * Case 1: Success + * SSH to the device and assert that the host key returned is the host key that was + pushed in the test set up + * Ensure telemetry values for version and created-on match the values set by + RotateHostParameters for + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:active-host-certificate-version` + and + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:active-host-certificate-created-on` + + +## 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: + ## State Paths ## + /system/ssh-server/state/active-host-certificate-version: + /system/ssh-server/state/active-host-certificate-created-on: + +rpcs: + gnsi: + credentialz.v1.Credentialz.GetPublicKeys: + credentialz.v1.Credentialz.RotateHostParameters: +``` + + +## Minimum DUT platform requirement + +N/A \ No newline at end of file diff --git a/feature/security/gnsi/credentialz/tests/host_certificates/host_certificates_test.go b/feature/security/gnsi/credentialz/tests/host_certificates/host_certificates_test.go new file mode 100644 index 00000000000..bedcfbe31ef --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/host_certificates/host_certificates_test.go @@ -0,0 +1,116 @@ +// 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 hostcertificates + +import ( + "fmt" + "net" + "os" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/ondatra/gnmi" + + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/security/credz" + "github.com/openconfig/ondatra" + "golang.org/x/crypto/ssh" +) + +const ( + hostCertificateVersion = "v1.0" +) + +var ( + hostCertificateCreatedOn = time.Now().Unix() +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestCredentialz(t *testing.T) { + dut := ondatra.DUT(t, "dut") + target := credz.GetDutTarget(t, dut) + + // Create temporary directory for storing ssh keys/certificates. + dir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatalf("Creating temp dir, err: %s", err) + } + defer func(dir string) { + err = os.RemoveAll(dir) + if err != nil { + t.Logf("Error removing temp directory, error: %s", err) + } + }(dir) + + // Create ssh keys/certificates for CA & host. + credz.CreateSSHKeyPair(t, dir, "ca") + credz.CreateSSHKeyPair(t, dir, "dut") + + credz.RotateAuthenticationArtifacts(t, dut, dir, "", hostCertificateVersion, uint64(hostCertificateCreatedOn)) + dutKey := credz.GetDutPublicKey(t, dut) + credz.CreateHostCertificate(t, dir, dutKey) + credz.RotateAuthenticationArtifacts(t, dut, "", dir, hostCertificateVersion, uint64(hostCertificateCreatedOn)) + + t.Run("dut should return signed host certificate", func(t *testing.T) { + certificateContents, err := os.ReadFile(fmt.Sprintf("%s/dut-cert.pub", dir)) + if err != nil { + t.Fatalf("Failed reading host signed certificate, error: %s", err) + } + wantHostKey, _, _, _, err := ssh.ParseAuthorizedKey(certificateContents) + if err != nil { + t.Fatalf("Failed parsing host certificate authorized (cert)key: %s", err) + } + + // Verify correct host certificate is returned by the dut. + _, err = ssh.Dial( + "tcp", + target, + &ssh.ClientConfig{ + User: "admin", + Auth: []ssh.AuthMethod{}, + HostKeyCallback: func(hostname string, remote net.Addr, gotHostKey ssh.PublicKey) error { + if !cmp.Equal(gotHostKey, wantHostKey) { + t.Fatalf("Host presented key (cert) that does not match expected host certificate. got: %v, want: %v", gotHostKey, wantHostKey) + } + return nil + }, + }, + ) + if err == nil { + t.Fatal("Dial ssh succeeded, but we expected failure.") + } + + // Verify host certificate telemetry values. + sshServer := gnmi.Get(t, dut, gnmi.OC().System().SshServer().State()) + gotHostCertificateVersion := sshServer.GetActiveHostCertificateVersion() + if !cmp.Equal(gotHostCertificateVersion, hostCertificateVersion) { + t.Fatalf( + "Telemetry reports host certificate version is not correct\n\tgot: %s\n\twant: %s", + gotHostCertificateVersion, hostCertificateVersion, + ) + } + gotHostCertificateCreatedOn := sshServer.GetActiveHostCertificateCreatedOn() + if !cmp.Equal(time.Unix(0, int64(gotHostCertificateCreatedOn)), time.Unix(hostCertificateCreatedOn, 0)) { + t.Fatalf( + "Telemetry reports host certificate created on is not correct\n\tgot: %d\n\twant: %d", + gotHostCertificateCreatedOn, hostCertificateCreatedOn, + ) + } + }) +} diff --git a/feature/security/gnsi/credentialz/tests/host_certificates/metadata.textproto b/feature/security/gnsi/credentialz/tests/host_certificates/metadata.textproto new file mode 100644 index 00000000000..b0cbb9220fc --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/host_certificates/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "91120b0a-91ea-493c-8046-f52176ec2029" +plan_id: "Credentialz-3" +description: "Host Certificates" +testbed: TESTBED_DUT diff --git a/feature/security/gnsi/credentialz/tests/password_console_login/README.md b/feature/security/gnsi/credentialz/tests/password_console_login/README.md new file mode 100644 index 00000000000..312968bb057 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/password_console_login/README.md @@ -0,0 +1,40 @@ +# Credentialz-1: Password console login + +## Summary + +Test that Credentialz properly creates users and the associated password and that the DUT handles +authentication of those users properly. + + +## Procedure + +* Set a username of `testuser` with a password having following restrictions: + * Must be 24-32 characters long. + * Must use 4 of the 5 character classes ([a-z], [A-Z], [0-9], [!@#$%^&*(){}[]\|:;'"], [ ]). +* Perform the following tests and assert the expected result: + * Case 1: Success + * Authenticate with the `testuser` username and password created in the first step above. + * Authentication must result in success with a prompt. + * Case 2: Failure + * Authenticate with the `testuser` username and an *incorrect* password of `password` + * Assert that authentication has failed + * Case 3: Failure + * Authenticate with the invalid username `username` and a valid (for a different username) + password created in the first step above. + * Assert that authentication has failed + + +## 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 +rpcs: + gnsi: + credentialz.v1.Credentialz.RotateAccountCredentials: +``` + + +## Minimum DUT platform requirement + +N/A diff --git a/feature/security/gnsi/credentialz/tests/password_console_login/metadata.textproto b/feature/security/gnsi/credentialz/tests/password_console_login/metadata.textproto new file mode 100644 index 00000000000..790ee493aec --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/password_console_login/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "902e381c-8196-436e-8f5b-f945e57ff855" +plan_id: "Credentialz-1" +description: "Password console login" +testbed: TESTBED_DUT diff --git a/feature/security/gnsi/credentialz/tests/password_console_login/password_console_login_test.go b/feature/security/gnsi/credentialz/tests/password_console_login/password_console_login_test.go new file mode 100644 index 00000000000..574578fcf12 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/password_console_login/password_console_login_test.go @@ -0,0 +1,110 @@ +// 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 passwordconsolelogin + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/ondatra/gnmi" + + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/security/credz" + "github.com/openconfig/ondatra" +) + +const ( + username = "testuser" + passwordVersion = "v1.0" +) + +var ( + passwordCreatedOn = time.Now().Unix() +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestCredentialz(t *testing.T) { + dut := ondatra.DUT(t, "dut") + target := credz.GetDutTarget(t, dut) + + // Setup test user and password. + credz.SetupUser(t, dut, username) + password := credz.GeneratePassword() + credz.RotateUserPassword(t, dut, username, password, passwordVersion, uint64(passwordCreatedOn)) + + testCases := []struct { + name string + loginUser string + loginPassword string + expectFail bool + }{ + { + name: "auth should succeed", + loginUser: username, + loginPassword: password, + expectFail: false, + }, + { + name: "auth should fail bad username", + loginUser: "notadmin", + loginPassword: password, + expectFail: true, + }, + { + name: "auth should fail bad password", + loginUser: username, + loginPassword: "notthepassword", + expectFail: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Verify ssh succeeds/fails based on expected result. + client, err := credz.SSHWithPassword(target, tc.loginUser, tc.loginPassword) + if tc.expectFail { + if err == nil { + t.Fatalf("Dialing ssh succeeded, but we expected to fail.") + } + return + } + if err != nil { + t.Fatalf("Failed dialing ssh, error: %s", err) + } + defer client.Close() + + // Verify password telemetry. + userState := gnmi.Get(t, dut, gnmi.OC().System().Aaa().Authentication().User(username).State()) + gotPasswordVersion := userState.GetPasswordVersion() + if !cmp.Equal(gotPasswordVersion, passwordVersion) { + t.Fatalf( + "Telemetry reports password version is not correctn\tgot: %s\n\twant: %s", + gotPasswordVersion, passwordVersion, + ) + } + gotPasswordCreatedOn := userState.GetPasswordCreatedOn() + if !cmp.Equal(time.Unix(0, int64(gotPasswordCreatedOn)), time.Unix(passwordCreatedOn, 0)) { + t.Fatalf( + "Telemetry reports password created on is not correct\n\tgot: %d\n\twant: %d", + gotPasswordCreatedOn, passwordCreatedOn, + ) + } + }) + } +} diff --git a/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/README.md b/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/README.md new file mode 100644 index 00000000000..b594291d517 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/README.md @@ -0,0 +1,71 @@ +# Credentialz-2: SSH Password Login Disallowed + +## Summary + +Test that Credentialz properly disallows password based SSH authentication when configured to do +so, furthermore, ensure that certificate based SSH authentication is allowed, and properly +accounted for. + + +## Procedure + +* Create a ssh CA keypair with `ssh-keygen -f /tmp/ca` +* Create a user keypair with `ssh-keygen -t ed25519` +* Sign the user public key into a certificate using the CA using `ssh-keygen -s + /tmp/ca -I testuser -n principal_name -V +52w user.pub`. You will + find your certificate ending in `-cert.pub` +* Set DUT TrustedUserCAKeys using gnsi.Credentialz with the CA public key +* Set a username of `testuser` with a password having following restrictions: + * Must be 24-32 characters long. + * Must use 4 of the 5 character classes ([a-z], [A-Z], [0-9], [!@#$%^&*(){}[]\|:;'"], [ ]). +* Set DUT authentication types to permit only public key (PUBKEY) using gnsi.Credentialz +* Set DUT authorized_users for `testuser` with a principal of `my_principal` (configured above + when signing public key) +* Perform the following tests and assert the expected result: + * Case 1: Failure + * Authenticate with the `testuser` username and password created above + via SSH + * Assert that authentication has failed + * Ensure that access failure telemetry counters are incremented + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-rejects` + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:last-access-reject` + * Case 2: Success + * Authenticate with the `testuser` username and password created above + via console + * Assert that authentication has been successful (password authentication was only + disallowed for SSH) + * Ensure that access accept telemetry counters are incremented + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-accepts` + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:last-access-accept` + * Case 3: Success + * Authenticate with the `testuser` and certificate created above + * Assert that authentication has been successful + * Assert that gnsi accounting recorded the principal (`my_principal`) from the + certificate rather than the SSH username (`testuser`) + * Ensure that access accept telemetry counters are incremented + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-accepts` + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:last-access-accept` + + +## 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: + ## State Paths ## + /system/ssh-server/state/counters/access-rejects: + /system/ssh-server/state/counters/last-access-reject: + /system/ssh-server/state/counters/access-accepts: + /system/ssh-server/state/counters/last-access-accept: + +rpcs: + gnsi: + credentialz.v1.Credentialz.RotateAccountCredentials: + credentialz.v1.Credentialz.RotateHostParameters: +``` + + +## Minimum DUT platform requirement + +N/A \ No newline at end of file diff --git a/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/metadata.textproto b/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/metadata.textproto new file mode 100644 index 00000000000..afd3a143542 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/metadata.textproto @@ -0,0 +1,16 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "4632f134-71e6-46a2-ac2a-b1ff6a3444e6" +plan_id: "Credentialz-2" +description: "SSH Password Login Disallowed" +testbed: TESTBED_DUT + +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + ssh_server_counters_unsupported: true + } +} \ No newline at end of file diff --git a/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/ssh_password_login_disallowed_test.go b/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/ssh_password_login_disallowed_test.go new file mode 100644 index 00000000000..424d92a9e46 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/ssh_password_login_disallowed/ssh_password_login_disallowed_test.go @@ -0,0 +1,188 @@ +// 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 sshpasswordlogindisallowed + +import ( + "context" + "os" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "testing" + "time" + + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/security/credz" + acctzpb "github.com/openconfig/gnsi/acctz" + cpb "github.com/openconfig/gnsi/credentialz" + "github.com/openconfig/ondatra" +) + +const ( + username = "testuser" + userPrincipal = "my_principal" + command = "show version" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestCredentialz(t *testing.T) { + dut := ondatra.DUT(t, "dut") + target := credz.GetDutTarget(t, dut) + recordStartTime := timestamppb.New(time.Now()) + + // Create temporary directory for storing ssh keys/certificates. + dir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatalf("Creating temp dir, err: %s", err) + } + defer func(dir string) { + err = os.RemoveAll(dir) + if err != nil { + t.Logf("Error removing temp directory, error: %s", err) + } + }(dir) + + // Create ssh keys/certificates for CA & testuser. + credz.CreateSSHKeyPair(t, dir, "ca") + credz.CreateSSHKeyPair(t, dir, username) + credz.CreateUserCertificate(t, dir, userPrincipal) + + // Setup user and password. + credz.SetupUser(t, dut, username) + password := credz.GeneratePassword() + credz.RotateUserPassword(t, dut, username, password, "v1.0", uint64(time.Now().Unix())) + + credz.RotateTrustedUserCA(t, dut, dir) + credz.RotateAuthenticationTypes(t, dut, []cpb.AuthenticationType{ + cpb.AuthenticationType_AUTHENTICATION_TYPE_PUBKEY, + }) + credz.RotateAuthorizedPrincipal(t, dut, username, userPrincipal) + + t.Run("auth should fail ssh password authentication disallowed", func(t *testing.T) { + var startingRejectCounter, startingLastRejectTime uint64 + if !deviations.SSHServerCountersUnsupported(dut) { + startingRejectCounter, startingLastRejectTime = credz.GetRejectTelemetry(t, dut) + } + + // Verify ssh with password fails as expected. + _, err := credz.SSHWithPassword(target, username, password) + if err == nil { + t.Fatalf("Dialing ssh succeeded, but we expected to fail.") + } + + // Verify ssh counters. + if !deviations.SSHServerCountersUnsupported(dut) { + endingRejectCounter, endingLastRejectTime := credz.GetRejectTelemetry(t, dut) + if endingRejectCounter <= startingRejectCounter { + t.Fatalf("SSH server reject counter did not increment after unsuccessful login. startCounter: %v, endCounter: %v", startingRejectCounter, endingRejectCounter) + } + if startingLastRejectTime == endingLastRejectTime { + t.Fatalf("SSH server reject last timestamp did not update after unsuccessful login. Timestamp: %v", endingLastRejectTime) + } + } + }) + + t.Run("auth should succeed ssh certificate authentication allowed", func(t *testing.T) { + var startingAcceptCounter, startingLastAcceptTime uint64 + if !deviations.SSHServerCountersUnsupported(dut) { + startingAcceptCounter, startingLastAcceptTime = credz.GetAcceptTelemetry(t, dut) + } + + // Verify ssh with certificate succeeds. + conn, err := credz.SSHWithCertificate(t, target, username, dir) + if err != nil { + t.Fatalf("Dialing ssh failed, but we expected to succeed, error: %s", err) + } + defer conn.Close() + + // Send command for accounting. + sess, err := conn.NewSession() + if err != nil { + t.Fatalf("Failed creating ssh session, error: %s", err) + } + defer sess.Close() + sess.Run(command) + + // Verify ssh counters. + if !deviations.SSHServerCountersUnsupported(dut) { + endingAcceptCounter, endingLastAcceptTime := credz.GetAcceptTelemetry(t, dut) + if endingAcceptCounter <= startingAcceptCounter { + t.Fatalf("SSH server accept counter did not increment after successful login. startCounter: %v, endCounter: %v", startingAcceptCounter, endingAcceptCounter) + } + if startingLastAcceptTime == endingLastAcceptTime { + t.Fatalf("SSH server accept last timestamp did not update after successful login. Timestamp: %v", endingLastAcceptTime) + } + } + + // Verify accounting record. + acctzClient := dut.RawAPIs().GNSI(t).AcctzStream() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + acctzSubClient, err := acctzClient.RecordSubscribe(ctx, &acctzpb.RecordRequest{Timestamp: recordStartTime}) + if err != nil { + t.Fatalf("Failed sending accountz record request, error: %s", err) + } + defer acctzSubClient.CloseSend() + + var foundRecord bool + for { + acctzResponse, err := acctzSubClient.Recv() + if err != nil { + if status.Code(err) == codes.DeadlineExceeded { + t.Log("Done receiving records...") + break + } + t.Fatalf( + "Failed receiving from accountz record subscribe client, "+ + "this could mean we didn't find the user identity and eventually timed "+ + "out with no more records to review, or another server error. Error: %s", + err, + ) + } + + // Skip non-ssh records. + if acctzResponse.GetCmdService() == nil { + continue + } + + reportedIdentity := acctzResponse.GetSessionInfo().GetUser().GetIdentity() + if reportedIdentity == username { + t.Logf("Found Record: %s", credz.PrettyPrint(acctzResponse)) + foundRecord = true + break + } + } + if !foundRecord { + t.Fatalf("Did not find accounting record for %s", username) + } + }) + + t.Cleanup(func() { + // Cleanup to remove previous policy which only allowed key auth to make sure we don't + // leave dut in a state where we can't reset config for further tests. + credz.RotateAuthenticationTypes(t, dut, []cpb.AuthenticationType{ + cpb.AuthenticationType_AUTHENTICATION_TYPE_PASSWORD, + cpb.AuthenticationType_AUTHENTICATION_TYPE_PUBKEY, + cpb.AuthenticationType_AUTHENTICATION_TYPE_KBDINTERACTIVE, + }) + }) +} diff --git a/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/README.md b/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/README.md new file mode 100644 index 00000000000..fe13bbdb82f --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/README.md @@ -0,0 +1,52 @@ +# Credentialz-4: SSH Public Key Authentication + +## Summary + +Test that Credentialz properly configures authorized SSH public keys for a given user, and that +the DUT properly allows or disallows authentication based on the configured settings. + + +## Procedure + +* Create a user ssh keypair with `ssh-keygen` +* Set a username of `testuser` +* Perform the following tests and assert the expected result: + * Case 1: Failure + * Attempt to ssh into the server with the `testuser` username, presenting the ssh key. + * Assert that authentication has failed (because the key is not authorized) + * Case 2: Success + * Configure the previously created ssh public key as an authorized key for the + `testuser` using gnsi.Credentialz/AuthorizedKeysRequest + * Authenticate with the `testuser` username and the previously created public key via SSH + * Assert that authentication has been successful + * Ensure telemetry values for version and created-on match the values set by + RotateHostParameters for + `/oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:users/oc-sys:user/oc-sys:state:authorized-keys-list-version` + and + `/oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:users/oc-sys:user/oc-sys:state:authorized-keys-list-created-on` + * Ensure that access accept telemetry counters are incremented + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-accepts` + `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:last-access-accept` + + +## 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: + ## State Paths ## + /system/aaa/authentication/users/user/state/authorized-keys-list-version: + /system/aaa/authentication/users/user/state/authorized-keys-list-created-on: + /system/ssh-server/state/counters/access-accepts: + /system/ssh-server/state/counters/last-access-accept: + +rpcs: + gnsi: + credentialz.v1.Credentialz.RotateAccountCredentials: +``` + + +## Minimum DUT platform requirement + +N/A \ No newline at end of file diff --git a/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/metadata.textproto b/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/metadata.textproto new file mode 100644 index 00000000000..3281da1a9d9 --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/metadata.textproto @@ -0,0 +1,16 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "3e6294aa-8f9d-4c8d-9041-4a2f4cd84c36" +plan_id: "Credentialz-4" +description: "SSH Public Key Authentication" +testbed: TESTBED_DUT + +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + ssh_server_counters_unsupported: true + } +} \ No newline at end of file diff --git a/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/ssh_public_key_authentication_test.go b/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/ssh_public_key_authentication_test.go new file mode 100644 index 00000000000..781acf4e6fb --- /dev/null +++ b/feature/security/gnsi/credentialz/tests/ssh_public_key_authentication/ssh_public_key_authentication_test.go @@ -0,0 +1,123 @@ +// 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 sshpublickeyauthentication + +import ( + "os" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/openconfig/featureprofiles/internal/security/credz" + + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" +) + +const ( + username = "testuser" + authorizedKeysListVersion = "v1.0" +) + +var ( + authorizedKeysListCreatedOn = time.Now().Unix() +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestCredentialz(t *testing.T) { + dut := ondatra.DUT(t, "dut") + target := credz.GetDutTarget(t, dut) + + // Create temporary directory for storing ssh keys/certificates. + dir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatalf("Creating temp dir, err: %s", err) + } + defer func(dir string) { + err = os.RemoveAll(dir) + if err != nil { + t.Logf("Error removing temp directory, error: %s", err) + } + }(dir) + + credz.CreateSSHKeyPair(t, dir, username) + credz.SetupUser(t, dut, username) + + t.Run("auth should fail ssh public key not authorized for user", func(t *testing.T) { + _, err := credz.SSHWithKey(t, target, username, dir) + if err == nil { + t.Fatalf("Dialing ssh succeeded, but we expected to fail.") + } + }) + + t.Run("auth should succeed ssh public key authorized for user", func(t *testing.T) { + // Push authorized key to the dut. + credz.RotateAuthorizedKey(t, + dut, + dir, + username, + authorizedKeysListVersion, + uint64(authorizedKeysListCreatedOn)) + + var startingAcceptCounter, startingLastAcceptTime uint64 + if !deviations.SSHServerCountersUnsupported(dut) { + startingAcceptCounter, startingLastAcceptTime = credz.GetAcceptTelemetry(t, dut) + } + + // Verify ssh with key succeeds. + _, err := credz.SSHWithKey(t, target, username, dir) + if err != nil { + t.Fatalf("Dialing ssh failed, but we expected to succeed. error: %v", err) + } + + // Verify ssh counters. + if !deviations.SSHServerCountersUnsupported(dut) { + endingAcceptCounter, endingLastAcceptTime := credz.GetAcceptTelemetry(t, dut) + if endingAcceptCounter <= startingAcceptCounter { + t.Fatalf("SSH server accept counter did not increment after successful login. startCounter: %v, endCounter: %v", startingAcceptCounter, endingAcceptCounter) + } + if startingLastAcceptTime == endingLastAcceptTime { + t.Fatalf("SSH server accept last timestamp did not update after successful login. Timestamp: %v", endingLastAcceptTime) + } + } + + // Verify authorized keys telemetry. + userState := gnmi.Get(t, dut, gnmi.OC().System().Aaa().Authentication().User(username).State()) + gotAuthorizedKeysListVersion := userState.GetAuthorizedKeysListVersion() + if !cmp.Equal(gotAuthorizedKeysListVersion, authorizedKeysListVersion) { + t.Fatalf( + "Telemetry reports authorized keys list version is not correct\n\tgot: %s\n\twant: %s", + gotAuthorizedKeysListVersion, authorizedKeysListVersion, + ) + } + gotAuthorizedKeysListCreatedOn := userState.GetAuthorizedKeysListCreatedOn() + if !cmp.Equal(time.Unix(0, int64(gotAuthorizedKeysListCreatedOn)), time.Unix(authorizedKeysListCreatedOn, 0)) { + t.Fatalf( + "Telemetry reports authorized keys list version on is not correct\n\tgot: %d\n\twant: %d", + gotAuthorizedKeysListCreatedOn, authorizedKeysListCreatedOn, + ) + } + }) + + t.Cleanup(func() { + // Cleanup user authorized key after test. + credz.RotateAuthorizedKey(t, dut, "", username, "", 0) + }) +} diff --git a/internal/components/components.go b/internal/components/components.go index c2e6a8b2896..e13fd064046 100644 --- a/internal/components/components.go +++ b/internal/components/components.go @@ -171,9 +171,9 @@ func (y Y) FindByType(ctx context.Context, want oc.Component_Type_Union) ([]stri return names, nil } -// FindStandbyRP gets a list of two components and finds out the active and standby rp. -func FindStandbyRP(t *testing.T, dut *ondatra.DUTDevice, supervisors []string) (string, string) { - var activeRP, standbyRP string +// FindStandbyControllerCard gets a list of two components and finds out the active and standby controller_cards. +func FindStandbyControllerCard(t *testing.T, dut *ondatra.DUTDevice, supervisors []string) (string, string) { + var activeCC, standbyCC string for _, supervisor := range supervisors { watch := gnmi.Watch(t, dut, gnmi.OC().Component(supervisor).RedundantRole().State(), 10*time.Minute, func(val *ygnmi.Value[oc.E_Platform_ComponentRedundantRole]) bool { return val.IsPresent() @@ -184,19 +184,19 @@ func FindStandbyRP(t *testing.T, dut *ondatra.DUTDevice, supervisors []string) ( role := gnmi.Get(t, dut, gnmi.OC().Component(supervisor).RedundantRole().State()) t.Logf("Component(supervisor).RedundantRole().Get(t): %v, Role: %v", supervisor, role) if role == standbyController { - standbyRP = supervisor + standbyCC = supervisor } else if role == activeController { - activeRP = supervisor + activeCC = supervisor } else { t.Fatalf("Expected controller %s to be active or standby, got %v", supervisor, role) } } - if standbyRP == "" || activeRP == "" { - t.Fatalf("Expected non-empty activeRP and standbyRP, got activeRP: %v, standbyRP: %v", activeRP, standbyRP) + if standbyCC == "" || activeCC == "" { + t.Fatalf("Expected non-empty activeCC and standbyCC, got activeCC: %v, standbyCC: %v", activeCC, standbyCC) } - t.Logf("Detected activeRP: %v, standbyRP: %v", activeRP, standbyRP) + t.Logf("Detected activeCC: %v, standbyCC: %v", activeCC, standbyCC) - return standbyRP, activeRP + return standbyCC, activeCC } // OpticalChannelComponentFromPort finds the optical channel component for a port. diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 3e2a221ac20..ec1248c56ad 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -1151,6 +1151,12 @@ func ComponentMfgDateUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetComponentMfgDateUnsupported() } +// InterfaceCountersUpdateDelayed returns true if telemetry for interface counters +// does not return the latest counter values. +func InterfaceCountersUpdateDelayed(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetInterfaceCountersUpdateDelayed() +} + // OTNChannelTribUnsupported returns true if TRIB parameter is unsupported under OTN channel configuration func OTNChannelTribUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetOtnChannelTribUnsupported() @@ -1165,3 +1171,18 @@ func EthChannelIngressParametersUnsupported(dut *ondatra.DUTDevice) bool { func EthChannelAssignmentCiscoNumbering(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetEthChannelAssignmentCiscoNumbering() } + +// ChassisGetRPCUnsupported returns true if a Healthz Get RPC against the Chassis component is unsupported +func ChassisGetRPCUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetChassisGetRpcUnsupported() +} + +// PowerDisableEnableLeafRefValidation returns true if definition of leaf-ref is not supported. +func PowerDisableEnableLeafRefValidation(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetPowerDisableEnableLeafRefValidation() +} + +// SSHServerCountersUnsupported is to skip checking ssh server counters. +func SSHServerCountersUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetSshServerCountersUnsupported() +} diff --git a/internal/gnoi/gnoi.go b/internal/gnoi/gnoi.go index 48eec464b83..cf7892ecea6 100644 --- a/internal/gnoi/gnoi.go +++ b/internal/gnoi/gnoi.go @@ -40,6 +40,7 @@ var ( }, ondatra.CISCO: { GRIBI: "emsd", + OCAGENT: "emsd", P4RT: "emsd", ROUTING: "emsd", }, diff --git a/internal/otg_helpers/otg_flow_helpers/otgflowhelpers.go b/internal/otg_helpers/otg_flow_helpers/otgflowhelpers.go new file mode 100644 index 00000000000..81b3024fa01 --- /dev/null +++ b/internal/otg_helpers/otg_flow_helpers/otgflowhelpers.go @@ -0,0 +1,216 @@ +// Package otgflowhelpers provides helper functions to create different flows on traffic generator. +package otgflowhelpers + +import ( + "github.com/open-traffic-generator/snappi/gosnappi" +) + +// Iana Ethertype is the IANA Ethertype for MPLS, IPv4 and IPv6. +const ( + IanaMPLSEthertype = 34887 + IanaIPv4Ethertype = 2048 + IanaIPv6Ethertype = 34525 +) + +/* +Flow is a struct to hold Flow parameters. +TxNames and RxNames should be set to a valid OTG endpoint name. +Creating basic IPv4 Flow. + +top = gosnappi.NewConfig() + + FlowIPv4 = &Flow{ + TxNames: []string{"interface1"}, + RxNames: []string{"interface2"}, + FrameSize: 1500, + FlowName: "IPv4Flow", + EthFlow: &EthFlowParams{SrcMAC: "00:11:22:33:44:55", DstMAC: "00:11:22:33:44:66"}, + IPv4Flow: &IPv4FlowParams{IPv4Src: "192.0.2.1", IPv4Dst: "192.0.2.129", IPv4DstCount: 10}, + } + +FlowIPv4.CreateFlow(top) +FlowIPv4.AddEthHeader() +FlowIPv4.AddIPv4Header() +*/ +type Flow struct { + TxNames []string + RxNames []string + FrameSize uint32 + FlowName string + VLANFlow *VLANFlowParams + GREFlow *GREFlowParams + EthFlow *EthFlowParams + IPv4Flow *IPv4FlowParams + IPv6Flow *IPv6FlowParams + TCPFlow *TCPFlowParams + UDPFlow *UDPFlowParams + MPLSFlow *MPLSFlowParams + flow gosnappi.Flow +} + +// GREFlowParams is a struct to hold Ethernet traffic parameters. +type GREFlowParams struct { + Protocol uint32 +} + +// VLANFlowParams is a struct to hold VLAN traffic parameters. +type VLANFlowParams struct { + VLANId uint32 +} + +// EthFlowParams is a struct to hold Ethernet traffic parameters. +type EthFlowParams struct { + SrcMAC string + DstMAC string + SrcMACCount uint32 +} + +// IPv4FlowParams is a struct to hold IPv4 traffic parameters. +type IPv4FlowParams struct { + IPv4Src string + IPv4Dst string + IPv4SrcCount uint32 + IPv4DstCount uint32 + TTL uint32 +} + +// IPv6FlowParams is a struct to hold IPv6 traffic parameters. +type IPv6FlowParams struct { + IPv6Src string + IPv6Dst string + IPv6SrcCount uint32 + IPv6DstCount uint32 + HopLimit uint32 +} + +// TCPFlowParams is a struct to hold TCP traffic parameters. +type TCPFlowParams struct { + TCPSrcPort uint32 + TCPDstPort uint32 + TCPSrcCount uint32 + TCPDstCount uint32 +} + +// UDPFlowParams is a struct to hold UDP traffic parameters. +type UDPFlowParams struct { + UDPSrcPort uint32 + UDPDstPort uint32 + UDPSrcCount uint32 + UDPDstCount uint32 +} + +// MPLSFlowParams is a struct to hold MPLS traffic parameters. +type MPLSFlowParams struct { + MPLSLabel uint32 + MPLSExp uint32 +} + +// CreateFlow defines Tx and Rx end points for traffic flow. +func (f *Flow) CreateFlow(top gosnappi.Config) { + f.flow = top.Flows().Add().SetName(f.FlowName) + f.flow.Metrics().SetEnable(true) + f.flow.TxRx().Device(). + SetTxNames(f.TxNames). + SetRxNames(f.RxNames) + f.flow.Size().SetFixed(f.FrameSize) +} + +// AddEthHeader adds an Ethernet header to the flow. +func (f *Flow) AddEthHeader() { + eth := f.flow.Packet().Add().Ethernet() + eth.Src().SetValue(f.EthFlow.SrcMAC) + eth.Dst().SetValue(f.EthFlow.DstMAC) +} + +// AddGREHeader adds a GRE header to the flow. +func (f *Flow) AddGREHeader() { + greHdr := f.flow.Packet().Add().Gre() + switch f.GREFlow.Protocol { + case IanaMPLSEthertype: + greHdr.Protocol().SetValue(IanaMPLSEthertype) + case IanaIPv4Ethertype: + greHdr.Protocol().SetValue(IanaIPv4Ethertype) + case IanaIPv6Ethertype: + greHdr.Protocol().SetValue(IanaIPv6Ethertype) + default: + greHdr.Protocol().SetValue(IanaIPv4Ethertype) + } +} + +// AddVlanHeader adds a VLAN header to the flow. +func (f *Flow) AddVlanHeader() { + f.flow.Packet().Add().Vlan().Id().SetValue(f.VLANFlow.VLANId) +} + +// AddMPLSHeader adds an MPLS header to the flow. +func (f *Flow) AddMPLSHeader() { + mplsHdr := f.flow.Packet().Add().Mpls() + mplsHdr.Label().SetValue(f.MPLSFlow.MPLSLabel) + mplsHdr.TrafficClass().SetValue(f.MPLSFlow.MPLSExp) +} + +// AddIPv4Header adds an IPv4 header to the flow. +func (f *Flow) AddIPv4Header() { + ipv4Hdr := f.flow.Packet().Add().Ipv4() + if f.IPv4Flow.IPv4SrcCount != 0 { + ipv4Hdr.Src().Increment().SetStart(f.IPv4Flow.IPv4Src).SetCount(f.IPv4Flow.IPv4SrcCount) + } else { + ipv4Hdr.Src().SetValue(f.IPv4Flow.IPv4Src) + } + if f.IPv4Flow.IPv4DstCount != 0 { + ipv4Hdr.Dst().Increment().SetStart(f.IPv4Flow.IPv4Dst).SetCount(f.IPv4Flow.IPv4DstCount) + } else { + ipv4Hdr.Dst().SetValue(f.IPv4Flow.IPv4Dst) + } + if f.IPv4Flow.TTL != 0 { + ipv4Hdr.TimeToLive().SetValue(f.IPv4Flow.TTL) + } +} + +// AddIPv6Header adds an IPv6 header to the flow. +func (f *Flow) AddIPv6Header() { + ipv6Hdr := f.flow.Packet().Add().Ipv6() + if f.IPv6Flow.IPv6SrcCount != 0 { + ipv6Hdr.Src().Increment().SetStart(f.IPv6Flow.IPv6Src).SetCount(f.IPv6Flow.IPv6SrcCount) + } else { + ipv6Hdr.Src().SetValue(f.IPv6Flow.IPv6Src) + } + if f.IPv6Flow.IPv6DstCount != 0 { + ipv6Hdr.Dst().Increment().SetStart(f.IPv6Flow.IPv6Dst).SetCount(f.IPv6Flow.IPv6DstCount) + } else { + ipv6Hdr.Dst().SetValue(f.IPv6Flow.IPv6Dst) + } + if f.IPv6Flow.HopLimit != 0 { + ipv6Hdr.HopLimit().SetValue(f.IPv6Flow.HopLimit) + } +} + +// AddTCPHeader adds a TCP header to the flow. +func (f *Flow) AddTCPHeader() { + tcpHdr := f.flow.Packet().Add().Tcp() + if f.TCPFlow.TCPSrcCount != 0 { + tcpHdr.SrcPort().Increment().SetStart(f.TCPFlow.TCPSrcPort).SetCount(f.TCPFlow.TCPSrcCount) + } else { + tcpHdr.SrcPort().SetValue(f.TCPFlow.TCPSrcPort) + } + if f.TCPFlow.TCPDstCount != 0 { + tcpHdr.DstPort().Increment().SetStart(f.TCPFlow.TCPDstPort).SetCount(f.TCPFlow.TCPDstCount) + } else { + tcpHdr.DstPort().SetValue(f.TCPFlow.TCPDstPort) + } +} + +// AddUDPHeader adds a UDP header to the flow. +func (f *Flow) AddUDPHeader() { + udpHdr := f.flow.Packet().Add().Udp() + if f.UDPFlow.UDPSrcCount != 0 { + udpHdr.SrcPort().Increment().SetStart(f.UDPFlow.UDPSrcPort).SetCount(f.UDPFlow.UDPSrcCount) + } else { + udpHdr.SrcPort().SetValue(f.UDPFlow.UDPSrcPort) + } + if f.UDPFlow.UDPDstCount != 0 { + udpHdr.DstPort().Increment().SetStart(f.UDPFlow.UDPDstPort).SetCount(f.UDPFlow.UDPDstCount) + } else { + udpHdr.DstPort().SetValue(f.UDPFlow.UDPDstPort) + } +} diff --git a/internal/security/credz/credz.go b/internal/security/credz/credz.go new file mode 100644 index 00000000000..4625c51afb0 --- /dev/null +++ b/internal/security/credz/credz.go @@ -0,0 +1,663 @@ +// 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 credz provides helper APIs to simplify writing credentialz test cases. +package credz + +import ( + "context" + "encoding/json" + "fmt" + "math/rand" + "os" + "os/exec" + "strings" + "testing" + "time" + + cpb "github.com/openconfig/gnsi/credentialz" + tpb "github.com/openconfig/kne/proto/topo" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/binding" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "golang.org/x/crypto/ssh" +) + +const ( + lowercase = "abcdefghijklmnopqrstuvwxyz" + uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + digits = "0123456789" + symbols = "!@#$%^&*(){}[]\\|:;\"'" + space = " " + userKey = "testuser" + dutKey = "dut" + caKey = "ca" + minPasswordLength = 24 + maxPasswordLength = 32 + defaultSSHPort = 22 +) + +var ( + charClasses = []string{lowercase, uppercase, digits, symbols, space} +) + +// PrettyPrint prints rpc requests/responses in a pretty format. +func PrettyPrint(i interface{}) string { + s, _ := json.MarshalIndent(i, "", "\t") + return string(s) +} + +// SetupUser setup user for credentialz tests. +func SetupUser(t *testing.T, dut *ondatra.DUTDevice, username string) { + auth := &oc.System_Aaa_Authentication{} + user := auth.GetOrCreateUser(username) + user.SetRole(oc.AaaTypes_SYSTEM_DEFINED_ROLES_SYSTEM_ROLE_ADMIN) + gnmi.Update(t, dut, gnmi.OC().System().Aaa().Authentication().Config(), auth) +} + +// GeneratePassword creates a password with following restrictions: +// - Must be 24-32 characters long. +// - Must use 4 of the 5 character classes ([a-z], [A-Z], [0-9], [!@#$%^&*(){}[]\|:;'"], [ ]). +func GeneratePassword() string { + // Create random length between 24-32 characters long. + length := minPasswordLength + rand.Intn(maxPasswordLength-minPasswordLength+1) + + // Randomly select 4 out of 5 character classes by shuffling the list. + rand.Shuffle(len(charClasses), func(i, j int) { + charClasses[i], charClasses[j] = charClasses[j], charClasses[i] + }) + selectedClasses := charClasses[:4] + + var password strings.Builder + + // Add one random character from each selected class. + for _, class := range selectedClasses { + password.WriteByte(class[rand.Intn(len(class))]) + } + + // Fill remaining characters for the password. + for password.Len() < length { + classIndex := rand.Intn(len(charClasses)) + class := charClasses[classIndex] + password.WriteByte(class[rand.Intn(len(class))]) + } + + return password.String() +} + +func sendHostParametersRequest(t *testing.T, dut *ondatra.DUTDevice, request *cpb.RotateHostParametersRequest) { + credzClient := dut.RawAPIs().GNSI(t).Credentialz() + credzRotateClient, err := credzClient.RotateHostParameters(context.Background()) + if err != nil { + t.Fatalf("Failed fetching credentialz rotate host parameters client, error: %s", err) + } + t.Logf("Sending credentialz rotate host request: %s", PrettyPrint(request)) + err = credzRotateClient.Send(request) + if err != nil { + t.Fatalf("Failed sending credentialz rotate host parameters request, error: %s", err) + } + _, err = credzRotateClient.Recv() + if err != nil { + t.Fatalf("Failed receiving credentialz rotate host parameters response, error: %s", err) + } + err = credzRotateClient.Send(&cpb.RotateHostParametersRequest{ + Request: &cpb.RotateHostParametersRequest_Finalize{ + Finalize: request.GetFinalize(), + }, + }) + if err != nil { + t.Fatalf("Failed sending credentialz rotate host parameters finalize request, error: %s", err) + } + // Brief sleep for finalize to get processed. + time.Sleep(time.Second) +} + +func sendAccountCredentialsRequest(t *testing.T, dut *ondatra.DUTDevice, request *cpb.RotateAccountCredentialsRequest) { + credzClient := dut.RawAPIs().GNSI(t).Credentialz() + credzRotateClient, err := credzClient.RotateAccountCredentials(context.Background()) + if err != nil { + t.Fatalf("Failed fetching credentialz rotate account credentials client, error: %s", err) + } + t.Logf("Sending credentialz rotate account request: %s", PrettyPrint(request)) + err = credzRotateClient.Send(request) + if err != nil { + t.Fatalf("Failed sending credentialz rotate account credentials request, error: %s", err) + } + _, err = credzRotateClient.Recv() + if err != nil { + t.Fatalf("Failed receiving credentialz rotate account credentials response, error: %s", err) + } + err = credzRotateClient.Send(&cpb.RotateAccountCredentialsRequest{ + Request: &cpb.RotateAccountCredentialsRequest_Finalize{ + Finalize: request.GetFinalize(), + }, + }) + if err != nil { + t.Fatalf("Failed sending credentialz rotate account credentials finalize request, error: %s", err) + } + // Brief sleep for finalize to get processed. + time.Sleep(time.Second) +} + +// RotateUserPassword apply password for the specified username on the dut. +func RotateUserPassword(t *testing.T, dut *ondatra.DUTDevice, username, password, version string, createdOn uint64) { + request := &cpb.RotateAccountCredentialsRequest{ + Request: &cpb.RotateAccountCredentialsRequest_Password{ + Password: &cpb.PasswordRequest{ + Accounts: []*cpb.PasswordRequest_Account{ + { + Account: username, + Password: &cpb.PasswordRequest_Password{ + Value: &cpb.PasswordRequest_Password_Plaintext{ + Plaintext: password, + }, + }, + Version: version, + CreatedOn: createdOn, + }, + }, + }, + }, + } + + sendAccountCredentialsRequest(t, dut, request) +} + +// RotateAuthorizedPrincipal apply authorized principal for the specified username on the dut. +func RotateAuthorizedPrincipal(t *testing.T, dut *ondatra.DUTDevice, username, userPrincipal string) { + request := &cpb.RotateAccountCredentialsRequest{ + Request: &cpb.RotateAccountCredentialsRequest_User{ + User: &cpb.AuthorizedUsersRequest{ + Policies: []*cpb.UserPolicy{ + { + Account: username, + AuthorizedPrincipals: &cpb.UserPolicy_SshAuthorizedPrincipals{ + AuthorizedPrincipals: []*cpb.UserPolicy_SshAuthorizedPrincipal{ + { + AuthorizedUser: userPrincipal, + }, + }, + }, + Version: "v1.0", + CreatedOn: uint64(time.Now().Unix()), + }, + }, + }, + }, + } + + sendAccountCredentialsRequest(t, dut, request) +} + +// RotateAuthorizedKey read user key contents from the specified directory & apply it as authorized key on the dut. +func RotateAuthorizedKey(t *testing.T, dut *ondatra.DUTDevice, dir, username, version string, createdOn uint64) { + var keyContents []*cpb.AccountCredentials_AuthorizedKey + + if dir != "" { + data, err := os.ReadFile(fmt.Sprintf("%s/%s.pub", dir, userKey)) + if err != nil { + t.Fatalf("Failed reading private key contents, error: %s", err) + } + keyContents = append(keyContents, &cpb.AccountCredentials_AuthorizedKey{ + AuthorizedKey: data, + KeyType: cpb.KeyType_KEY_TYPE_ED25519, + }) + } + request := &cpb.RotateAccountCredentialsRequest{ + Request: &cpb.RotateAccountCredentialsRequest_Credential{ + Credential: &cpb.AuthorizedKeysRequest{ + Credentials: []*cpb.AccountCredentials{ + { + Account: username, + AuthorizedKeys: keyContents, + Version: version, + CreatedOn: createdOn, + }, + }, + }, + }, + } + + sendAccountCredentialsRequest(t, dut, request) +} + +// RotateTrustedUserCA read CA key contents from the specified directory & apply it on the dut. +func RotateTrustedUserCA(t *testing.T, dut *ondatra.DUTDevice, dir string) { + var keyContents []*cpb.PublicKey + + if dir != "" { + data, err := os.ReadFile(fmt.Sprintf("%s/%s.pub", dir, caKey)) + if err != nil { + t.Fatalf("Failed reading ca public key contents, error: %s", err) + } + keyContents = append(keyContents, &cpb.PublicKey{ + PublicKey: data, + KeyType: cpb.KeyType_KEY_TYPE_ED25519, + }) + } + request := &cpb.RotateHostParametersRequest{ + Request: &cpb.RotateHostParametersRequest_SshCaPublicKey{ + SshCaPublicKey: &cpb.CaPublicKeyRequest{ + SshCaPublicKeys: keyContents, + Version: "v1.0", + CreatedOn: uint64(time.Now().Unix()), + }, + }, + } + + sendHostParametersRequest(t, dut, request) +} + +// RotateAuthenticationTypes apply specified host authentication types on the dut. +func RotateAuthenticationTypes(t *testing.T, dut *ondatra.DUTDevice, authTypes []cpb.AuthenticationType) { + request := &cpb.RotateHostParametersRequest{ + Request: &cpb.RotateHostParametersRequest_AuthenticationAllowed{ + AuthenticationAllowed: &cpb.AllowedAuthenticationRequest{ + AuthenticationTypes: authTypes, + }, + }, + } + + sendHostParametersRequest(t, dut, request) +} + +// RotateAuthenticationArtifacts read dut key/certificate contents from the specified directory & apply it as host authentication artifacts on the dut. +func RotateAuthenticationArtifacts(t *testing.T, dut *ondatra.DUTDevice, keyDir, certDir, version string, createdOn uint64) { + var artifactContents []*cpb.ServerKeysRequest_AuthenticationArtifacts + + if keyDir != "" { + data, err := os.ReadFile(fmt.Sprintf("%s/%s", keyDir, dutKey)) + if err != nil { + t.Fatalf("Failed reading host private key, error: %s", err) + } + artifactContents = append(artifactContents, &cpb.ServerKeysRequest_AuthenticationArtifacts{ + PrivateKey: data, + }) + } + + if certDir != "" { + data, err := os.ReadFile(fmt.Sprintf("%s/%s-cert.pub", certDir, dutKey)) + if err != nil { + t.Fatalf("Failed reading host signed certificate, error: %s", err) + } + artifactContents = append(artifactContents, &cpb.ServerKeysRequest_AuthenticationArtifacts{ + Certificate: data, + }) + } + + request := &cpb.RotateHostParametersRequest{ + Request: &cpb.RotateHostParametersRequest_ServerKeys{ + ServerKeys: &cpb.ServerKeysRequest{ + AuthArtifacts: artifactContents, + Version: version, + CreatedOn: createdOn, + }, + }, + } + + sendHostParametersRequest(t, dut, request) +} + +// RotateAuthorizedPrincipalCheck apply specified authorized principal tool on the dut. +func RotateAuthorizedPrincipalCheck(t *testing.T, dut *ondatra.DUTDevice, tool cpb.AuthorizedPrincipalCheckRequest_Tool) { + request := &cpb.RotateHostParametersRequest{ + Request: &cpb.RotateHostParametersRequest_AuthorizedPrincipalCheck{ + AuthorizedPrincipalCheck: &cpb.AuthorizedPrincipalCheckRequest{ + Tool: tool, + }, + }, + } + + sendHostParametersRequest(t, dut, request) +} + +// GetRejectTelemetry retrieve ssh reject telemetry counters from the dut. +func GetRejectTelemetry(t *testing.T, dut *ondatra.DUTDevice) (uint64, uint64) { + sshCounters := gnmi.Get(t, dut, gnmi.OC().System().SshServer().Counters().State()) + return sshCounters.GetAccessRejects(), sshCounters.GetLastAccessReject() +} + +// GetAcceptTelemetry retrieve ssh accept telemetry counters from the dut. +func GetAcceptTelemetry(t *testing.T, dut *ondatra.DUTDevice) (uint64, uint64) { + sshCounters := gnmi.Get(t, dut, gnmi.OC().System().SshServer().Counters().State()) + return sshCounters.GetAccessAccepts(), sshCounters.GetLastAccessAccept() +} + +// GetDutTarget returns ssh target for the dut to be used in credentialz tests. +func GetDutTarget(t *testing.T, dut *ondatra.DUTDevice) string { + var serviceDUT interface { + Service(string) (*tpb.Service, error) + } + err := binding.DUTAs(dut.RawAPIs().BindingDUT(), &serviceDUT) + if err != nil { + t.Log("DUT does not support `Service` function, will attempt to use dut name field") + return fmt.Sprintf("%s:%d", dut.Name(), defaultSSHPort) + } + dutSSHService, err := serviceDUT.Service("ssh") + if err != nil { + t.Fatal(err) + } + return fmt.Sprintf("%s:%d", dutSSHService.GetOutsideIp(), dutSSHService.GetOutside()) +} + +// GetDutPublicKey retrieve single host public key from the dut. +func GetDutPublicKey(t *testing.T, dut *ondatra.DUTDevice) []byte { + credzClient := dut.RawAPIs().GNSI(t).Credentialz() + req := &cpb.GetPublicKeysRequest{} + response, err := credzClient.GetPublicKeys(context.Background(), req) + if err != nil { + t.Fatalf("Failed fetching fetching credentialz public keys, error: %s", err) + } + if len(response.PublicKeys) < 1 { + return nil + } + return response.PublicKeys[0].PublicKey +} + +// CreateSSHKeyPair creates ssh keypair with a filename of keyName in the specified directory. +// Keypairs can be created for ca/dut/testuser as per individual credentialz test requirements. +func CreateSSHKeyPair(t *testing.T, dir, keyName string) { + sshCmd := exec.Command( + "ssh-keygen", + "-t", "ed25519", + "-f", keyName, + "-C", keyName, + "-q", "-N", "", + ) + sshCmd.Dir = dir + err := sshCmd.Run() + if err != nil { + t.Fatalf("Failed generating %s key pair, error: %s", keyName, err) + } +} + +// CreateUserCertificate creates ssh user certificate in the specified directory. +func CreateUserCertificate(t *testing.T, dir, userPrincipal string) { + userCertCmd := exec.Command( + "ssh-keygen", + "-s", caKey, + "-I", userKey, + "-n", userPrincipal, + "-V", "+52w", + fmt.Sprintf("%s.pub", userKey), + ) + userCertCmd.Dir = dir + err := userCertCmd.Run() + if err != nil { + t.Fatalf("Failed generating user cert, error: %s", err) + } +} + +// CreateHostCertificate takes in dut key contents & creates ssh host certificate in the specified directory. +func CreateHostCertificate(t *testing.T, dir string, dutKeyContents []byte) { + err := os.WriteFile(fmt.Sprintf("%s/%s.pub", dir, dutKey), dutKeyContents, 0o777) + if err != nil { + t.Fatalf("Failed writing dut public key to temp dir, error: %s", err) + } + cmd := exec.Command( + "ssh-keygen", + "-s", caKey, // sign using this ca key + "-I", dutKey, // key identity + "-h", // create host (not user) certificate + "-n", "dut.test.com", // principal(s) + "-V", "+52w", // validity + fmt.Sprintf("%s.pub", dutKey), + ) + cmd.Dir = dir + err = cmd.Run() + if err != nil { + t.Fatalf("Failed generating dut cert, error: %s", err) + } +} + +func createHibaKeysCopy(t *testing.T, dir string) { + keyFiles := []string{ + "ca", + "ca.pub", + "hosts/dut", + "hosts/dut.pub", + "hosts/dut-cert.pub", + "users/testuser", + "users/testuser.pub", + "users/testuser-cert.pub", + } + err := os.Mkdir(fmt.Sprintf("%s/hosts", dir), 0o700) + if err != nil { + t.Fatalf("Failed ensuring hosts dir in temp dir, error: %s", err) + } + err = os.Mkdir(fmt.Sprintf("%s/users", dir), 0o700) + if err != nil { + t.Fatalf("Failed ensuring users dir in temp dir, error: %s", err) + } + + for _, keyFile := range keyFiles { + var input []byte + input, err = os.ReadFile(keyFile) + if err != nil { + t.Errorf("Error reading file %v, error: %s", keyFile, err) + return + } + err = os.WriteFile(fmt.Sprintf("%s/%s", dir, keyFile), input, 0o600) + if err != nil { + t.Fatalf("Failed copying key file %s to temp test dir, error: %s", keyFile, err) + } + } +} + +func createHibaKeysGen(t *testing.T, dir string) { + caCmd := exec.Command( + "hiba-ca.sh", + "-c", + "-d", dir, // output to the temp dir + "--", // pass the rest to ssh-keygen + "-q", "-N", "", // quiet, empty passphrase + + ) + caCmd.Dir = dir + err := caCmd.Run() + if err != nil { + t.Fatalf("Failed generating ca key pair, error: %s", err) + } + + userKeyCmd := exec.Command( + "hiba-ca.sh", + "-c", + "-d", dir, + "-u", "-I", userKey, + "--", + "-q", "-N", "", + ) + userKeyCmd.Dir = dir + err = userKeyCmd.Run() + if err != nil { + t.Fatalf("Failed generating user key pair, error: %s", err) + } + + dutKeyCmd := exec.Command( + "hiba-ca.sh", + "-c", + "-d", dir, + "-h", "-I", dutKey, + "--", + "-q", "-N", "", + ) + dutKeyCmd.Dir = dir + err = dutKeyCmd.Run() + if err != nil { + t.Fatalf("Failed generating dut key pair, error: %s", err) + } + + prodIdentityCmd := exec.Command( + "hiba-gen", + "-i", + "-f", fmt.Sprintf("%s/policy/identities/prod", dir), + "domain", "example.com", + ) + prodIdentityCmd.Dir = dir + err = prodIdentityCmd.Run() + if err != nil { + t.Fatalf("Failed creating prod identity, error: %s", err) + } + + shellGrantCmd := exec.Command( + "hiba-gen", + "-f", fmt.Sprintf("%s/policy/grants/shell", dir), + "domain", "example.com", + ) + shellGrantCmd.Dir = dir + err = shellGrantCmd.Run() + if err != nil { + t.Fatalf("Failed creating shell grant, error: %s", err) + } + + grantShellToUserCmd := exec.Command( + "hiba-ca.sh", + "-d", dir, + "-p", + "-I", userKey, + "-H", "shell", + ) + grantShellToUserCmd.Dir = dir + err = grantShellToUserCmd.Run() + if err != nil { + t.Fatalf("Failed granting shell grant to testuser, error: %s", err) + } + + createHostCertCmd := exec.Command( + "hiba-ca.sh", + "-d", dir, + "-s", + "-h", + "-I", dutKey, + "-H", "prod", + "-V", "+52w", + ) + createHostCertCmd.Dir = dir + err = createHostCertCmd.Run() + if err != nil { + t.Fatalf("Failed creating host certificate, error: %s", err) + } + + createUserCertCmd := exec.Command( + "hiba-ca.sh", + "-d", dir, + "-s", + "-u", + "-I", userKey, + "-H", "shell", + ) + createUserCertCmd.Dir = dir + err = createUserCertCmd.Run() + if err != nil { + t.Fatalf("Failed creating user certificate, error: %s", err) + } +} + +// CreateHibaKeys creates/copies hiba granted keys/certificates in the specified directory. +// If hiba tool is not installed on the testbed, ensure following files (generated after executing steps +// from https://github.com/google/hiba/blob/main/CA.md) are present in the test directory : +// feature/security/gnsi/credentialz/tests/hiba_authentication/ca, +// feature/security/gnsi/credentialz/tests/hiba_authentication/ca.pub, +// feature/security/gnsi/credentialz/tests/hiba_authentication/hosts/dut, +// feature/security/gnsi/credentialz/tests/hiba_authentication/hosts/dut.pub, +// feature/security/gnsi/credentialz/tests/hiba_authentication/hosts/dut-cert.pub, +// feature/security/gnsi/credentialz/tests/hiba_authentication/users/testuser, +// feature/security/gnsi/credentialz/tests/hiba_authentication/users/testuser.pub, +// feature/security/gnsi/credentialz/tests/hiba_authentication/users/testuser-cert.pub, +func CreateHibaKeys(t *testing.T, dir string) { + hibaCa, _ := exec.LookPath("hiba-ca.sh") + hibaGen, _ := exec.LookPath("hiba-gen") + if hibaCa == "" || hibaGen == "" { + t.Log("hiba-ca and/or hiba-gen not found on path, will try to use certs in local test dir if present.") + createHibaKeysCopy(t, dir) + } else { + createHibaKeysGen(t, dir) + } +} + +// SSHWithPassword dials ssh with password based authentication to be used in credentialz tests. +func SSHWithPassword(target, username, password string) (*ssh.Client, error) { + return ssh.Dial( + "tcp", + target, + &ssh.ClientConfig{ + User: username, + Auth: []ssh.AuthMethod{ + ssh.Password(password), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + }, + ) +} + +// SSHWithCertificate dials ssh with user certificate to be used in credentialz tests. +func SSHWithCertificate(t *testing.T, target, username, dir string) (*ssh.Client, error) { + privateKeyContents, err := os.ReadFile(fmt.Sprintf("%s/%s", dir, userKey)) + if err != nil { + t.Fatalf("Failed reading private key contents, error: %s", err) + } + signer, err := ssh.ParsePrivateKey(privateKeyContents) + if err != nil { + t.Fatalf("Failed parsing private key, error: %s", err) + } + certificateContents, err := os.ReadFile(fmt.Sprintf("%s/%s-cert.pub", dir, userKey)) + if err != nil { + t.Fatalf("Failed reading certificate contents, error: %s", err) + } + certificate, _, _, _, err := ssh.ParseAuthorizedKey(certificateContents) + if err != nil { + t.Fatalf("Failed parsing certificate contents, error: %s", err) + } + certificateSigner, err := ssh.NewCertSigner(certificate.(*ssh.Certificate), signer) + if err != nil { + t.Fatalf("Failed creating certificate signer, error: %s", err) + } + + return ssh.Dial( + "tcp", + target, + &ssh.ClientConfig{ + User: username, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(certificateSigner), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + }, + ) +} + +// SSHWithKey dials ssh with key based authentication to be used in credentialz tests. +func SSHWithKey(t *testing.T, target, username, dir string) (*ssh.Client, error) { + privateKeyContents, err := os.ReadFile(fmt.Sprintf("%s/%s", dir, userKey)) + if err != nil { + t.Fatalf("Failed reading private key contents, error: %s", err) + } + signer, err := ssh.ParsePrivateKey(privateKeyContents) + if err != nil { + t.Fatalf("Failed parsing private key, error: %s", err) + } + + return ssh.Dial( + "tcp", + target, + &ssh.ClientConfig{ + User: username, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + }, + ) +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 9d5973aaa2e..84bd6041252 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -621,6 +621,16 @@ message Metadata { bool eth_channel_ingress_parameters_unsupported = 222; // Cisco numbering for eth channel assignment starts from 1 instead of 0 bool eth_channel_assignment_cisco_numbering = 223; + // Devices needs time to update interface counters. + bool interface_counters_update_delayed = 224; + // device does not support a Healthz GET RPC against Chassis level component like "CHASSIS" or "Rack 0" + bool chassis_get_rpc_unsupported = 225; + // Leaf-ref validation for list keys which is enforced for Cisco and hence deviation + // b/373581140 + bool power_disable_enable_leaf_ref_validation = 226; + // Device does not support ssh server counters. + bool ssh_server_counters_unsupported = 227; + // 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 2472d35b23b..488651737cf 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.2 -// protoc v5.28.0 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // 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 @@ -903,6 +902,15 @@ type Metadata_Deviations struct { EthChannelIngressParametersUnsupported bool `protobuf:"varint,222,opt,name=eth_channel_ingress_parameters_unsupported,json=ethChannelIngressParametersUnsupported,proto3" json:"eth_channel_ingress_parameters_unsupported,omitempty"` // Cisco numbering for eth channel assignment starts from 1 instead of 0 EthChannelAssignmentCiscoNumbering bool `protobuf:"varint,223,opt,name=eth_channel_assignment_cisco_numbering,json=ethChannelAssignmentCiscoNumbering,proto3" json:"eth_channel_assignment_cisco_numbering,omitempty"` + // Devices needs time to update interface counters. + InterfaceCountersUpdateDelayed bool `protobuf:"varint,224,opt,name=interface_counters_update_delayed,json=interfaceCountersUpdateDelayed,proto3" json:"interface_counters_update_delayed,omitempty"` + // device does not support a Healthz GET RPC against Chassis level component like "CHASSIS" or "Rack 0" + ChassisGetRpcUnsupported bool `protobuf:"varint,225,opt,name=chassis_get_rpc_unsupported,json=chassisGetRpcUnsupported,proto3" json:"chassis_get_rpc_unsupported,omitempty"` + // Leaf-ref validation for list keys which is enforced for Cisco and hence deviation + // b/373581140 + PowerDisableEnableLeafRefValidation bool `protobuf:"varint,226,opt,name=power_disable_enable_leaf_ref_validation,json=powerDisableEnableLeafRefValidation,proto3" json:"power_disable_enable_leaf_ref_validation,omitempty"` + // Device does not support ssh server counters. + SshServerCountersUnsupported bool `protobuf:"varint,227,opt,name=ssh_server_counters_unsupported,json=sshServerCountersUnsupported,proto3" json:"ssh_server_counters_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -2351,6 +2359,34 @@ func (x *Metadata_Deviations) GetEthChannelAssignmentCiscoNumbering() bool { return false } +func (x *Metadata_Deviations) GetInterfaceCountersUpdateDelayed() bool { + if x != nil { + return x.InterfaceCountersUpdateDelayed + } + return false +} + +func (x *Metadata_Deviations) GetChassisGetRpcUnsupported() bool { + if x != nil { + return x.ChassisGetRpcUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetPowerDisableEnableLeafRefValidation() bool { + if x != nil { + return x.PowerDisableEnableLeafRefValidation + } + return false +} + +func (x *Metadata_Deviations) GetSshServerCountersUnsupported() bool { + if x != nil { + return x.SshServerCountersUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2414,1014 +2450,1033 @@ 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, 0xe6, 0x7d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, - 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x07, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x80, 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, + 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x07, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x52, 0x07, 0x74, 0x65, 0x73, + 0x74, 0x62, 0x65, 0x64, 0x12, 0x60, 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x5f, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2f, 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, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x52, 0x07, 0x74, 0x65, 0x73, 0x74, - 0x62, 0x65, 0x64, 0x12, 0x60, 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, - 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2f, 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, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, - 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2c, 0x0a, 0x12, - 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x65, - 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x70, 0x61, 0x74, 0x68, 0x50, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x73, 0x74, 0x1a, 0xb8, 0x01, 0x0a, 0x08, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2e, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, - 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x52, - 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x61, 0x72, 0x64, 0x77, - 0x61, 0x72, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4d, - 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x6f, 0x66, - 0x74, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, - 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, - 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, - 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xb9, 0x75, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x45, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x18, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, - 0x6c, 0x34, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x75, 0x64, 0x70, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x4c, 0x34, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x55, 0x64, 0x70, 0x12, 0x3a, - 0x0a, 0x19, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x72, 0x65, 0x63, 0x65, - 0x69, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x17, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x63, 0x65, - 0x69, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x28, 0x68, 0x69, - 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6c, - 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x25, 0x68, 0x69, - 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x1f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x5f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, 0x73, - 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x26, 0x69, 0x73, - 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, - 0x65, 0x6c, 0x31, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x69, 0x73, 0x69, 0x73, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x31, 0x44, - 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x41, - 0x0a, 0x1d, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x74, 0x6f, - 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x69, 0x73, 0x69, 0x73, 0x53, 0x69, 0x6e, 0x67, 0x6c, - 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, 0x69, 0x73, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x26, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x49, - 0x73, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, 0x69, 0x53, - 0x61, 0x66, 0x69, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x54, 0x0a, 0x27, 0x69, 0x73, 0x69, - 0x73, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, 0x73, - 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, - 0x58, 0x0a, 0x29, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, - 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x25, 0x69, 0x73, 0x69, 0x73, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, - 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x21, 0x69, 0x73, 0x69, - 0x73, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x53, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x70, 0x5f, 0x6e, 0x65, 0x69, 0x67, 0x68, - 0x62, 0x6f, 0x72, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x11, 0x69, 0x70, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x4d, 0x69, 0x73, - 0x73, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x13, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x12, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x72, - 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x37, 0x0a, 0x18, 0x6f, 0x73, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, 0x5f, 0x72, - 0x70, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x6f, 0x73, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, 0x52, 0x70, 0x12, 0x50, - 0x0a, 0x25, 0x6c, 0x6c, 0x64, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6c, - 0x6c, 0x64, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x12, 0x55, 0x0a, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x67, 0x70, 0x5f, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x15, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x23, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x42, 0x67, 0x70, 0x4c, 0x61, - 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x47, 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x34, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x1d, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, - 0x6e, 0x68, 0x5f, 0x64, 0x6d, 0x61, 0x63, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x69, - 0x70, 0x76, 0x36, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x47, 0x72, 0x69, 0x62, - 0x69, 0x4e, 0x68, 0x44, 0x6d, 0x61, 0x63, 0x12, 0x45, 0x0a, 0x1f, 0x65, 0x63, 0x6e, 0x5f, 0x70, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1c, 0x65, 0x63, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, - 0x0a, 0x1f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, - 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, 0x70, 0x76, 0x36, 0x44, 0x69, 0x73, - 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x50, 0x6b, 0x74, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x77, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x64, - 0x72, 0x6f, 0x70, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x1c, 0x63, 0x6c, - 0x69, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, 0x6e, - 0x63, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x6f, 0x63, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x18, 0x63, 0x6c, 0x69, 0x54, 0x61, 0x6b, 0x65, 0x73, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, - 0x65, 0x6e, 0x63, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x4f, 0x63, 0x12, 0x3f, 0x0a, 0x1c, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x77, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x19, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, - 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x3b, 0x0a, 0x1a, 0x73, - 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x69, 0x64, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x17, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x43, 0x68, 0x69, 0x70, 0x49, 0x64, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x25, 0x62, 0x61, 0x63, 0x6b, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x61, 0x70, - 0x61, 0x63, 0x69, 0x74, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x46, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x21, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x2b, 0x6e, 0x6f, 0x5f, 0x6d, 0x69, 0x78, - 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x75, - 0x6e, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x6e, 0x6f, 0x4d, - 0x69, 0x78, 0x4f, 0x66, 0x54, 0x61, 0x67, 0x67, 0x65, 0x64, 0x41, 0x6e, 0x64, 0x55, 0x6e, 0x74, - 0x61, 0x67, 0x67, 0x65, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x77, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x25, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x14, 0x73, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x21, 0x65, 0x78, 0x70, 0x6c, - 0x69, 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, - 0x65, 0x66, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x26, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x1e, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x1d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x18, 0x27, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x78, 0x70, 0x6c, 0x69, - 0x63, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x29, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x50, 0x6f, - 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x65, 0x78, 0x70, 0x6c, 0x69, - 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x6e, - 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x18, 0x2a, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1d, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x72, - 0x66, 0x12, 0x2c, 0x0a, 0x12, 0x71, 0x6f, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, - 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x71, - 0x6f, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x12, - 0x4f, 0x0a, 0x24, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, - 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x5f, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, - 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x74, 0x72, - 0x79, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x22, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x6d, - 0x61, 0x63, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x2e, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1d, 0x67, 0x72, 0x69, 0x62, 0x69, 0x4d, 0x61, 0x63, 0x4f, 0x76, 0x65, 0x72, 0x72, - 0x69, 0x64, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, - 0x12, 0x4a, 0x0a, 0x22, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x66, - 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x56, 0x0a, 0x28, - 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, - 0x67, 0x6e, 0x6f, 0x69, 0x46, 0x61, 0x62, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x6e, 0x74, 0x70, 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x31, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x6e, - 0x74, 0x70, 0x4e, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x72, 0x66, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x6f, 0x6d, - 0x69, 0x74, 0x5f, 0x6c, 0x32, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x6f, 0x6d, 0x69, 0x74, 0x4c, 0x32, 0x4d, 0x74, 0x75, 0x12, 0x46, 0x0a, 0x20, 0x73, 0x6b, - 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x61, - 0x72, 0x64, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x33, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x41, 0x64, 0x6d, - 0x69, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, - 0x13, 0x62, 0x67, 0x70, 0x5f, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x62, 0x67, 0x70, 0x54, - 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4d, 0x0a, - 0x24, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x61, 0x6c, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x6c, 0x69, 0x6e, - 0x6b, 0x51, 0x75, 0x61, 0x6c, 0x57, 0x61, 0x69, 0x74, 0x41, 0x66, 0x74, 0x65, 0x72, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, - 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x65, 0x6d, 0x70, 0x74, - 0x79, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x3f, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x12, 0x56, 0x0a, 0x28, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x40, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x24, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x62, 0x67, 0x70, - 0x5f, 0x6d, 0x64, 0x35, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x72, 0x65, - 0x73, 0x65, 0x74, 0x18, 0x41, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x62, 0x67, 0x70, 0x4d, 0x64, - 0x35, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x4b, - 0x0a, 0x23, 0x64, 0x65, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x73, 0x5f, - 0x64, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x42, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x64, 0x65, 0x71, - 0x75, 0x65, 0x75, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x65, 0x64, 0x41, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x67, - 0x72, 0x69, 0x62, 0x69, 0x5f, 0x72, 0x69, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, - 0x18, 0x43, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x67, 0x72, 0x69, 0x62, 0x69, 0x52, 0x69, 0x62, - 0x61, 0x63, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x61, 0x67, 0x67, 0x72, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x18, 0x44, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x41, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, - 0x3b, 0x0a, 0x1a, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x45, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x17, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, - 0x0a, 0x16, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x47, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, - 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x50, 0x61, 0x74, 0x68, 0x12, 0x4c, 0x0a, 0x23, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x48, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x56, 0x72, 0x66, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x76, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x49, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, - 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x56, 0x6c, 0x61, 0x6e, 0x49, 0x64, - 0x12, 0x58, 0x0a, 0x2a, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x6f, 0x76, - 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x72, - 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x4a, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x67, 0x72, 0x69, 0x62, 0x69, 0x4d, 0x61, 0x63, 0x4f, 0x76, - 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x4b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x6f, 0x73, 0x5f, 0x6f, - 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x71, 0x6f, 0x73, - 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x18, 0x4d, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x70, 0x75, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x30, 0x18, 0x4e, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x53, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x30, 0x12, 0x5f, 0x0a, 0x2d, 0x67, - 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x18, 0x4f, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x28, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x6f, 0x76, - 0x65, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x55, - 0x73, 0x65, 0x72, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x18, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x24, 0x70, 0x34, 0x72, 0x74, 0x5f, 0x75, - 0x6e, 0x73, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x5f, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x18, 0x51, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x70, 0x34, 0x72, 0x74, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x62, 0x6b, 0x75, 0x70, 0x5f, - 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x52, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, 0x6b, 0x75, - 0x70, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x43, 0x6f, 0x64, 0x65, 0x12, 0x49, 0x0a, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x6e, - 0x68, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x76, 0x72, 0x66, 0x5f, - 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x18, 0x53, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1d, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4e, 0x68, 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x73, 0x56, 0x72, 0x66, 0x57, 0x69, 0x74, 0x68, 0x44, 0x65, 0x63, 0x61, 0x70, 0x12, - 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x18, 0x55, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, 0x69, 0x73, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x23, 0x70, 0x34, 0x72, 0x74, 0x5f, 0x6d, 0x6f, 0x64, - 0x69, 0x66, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x56, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1f, 0x70, 0x34, 0x72, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x5e, 0x0a, 0x2d, 0x6f, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, - 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x70, - 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x5f, 0x6f, 0x72, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x63, - 0x61, 0x72, 0x64, 0x18, 0x57, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x6f, 0x73, 0x43, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x73, 0x53, 0x75, - 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x4f, 0x72, 0x4c, 0x69, 0x6e, 0x65, 0x63, 0x61, - 0x72, 0x64, 0x12, 0x42, 0x0a, 0x1e, 0x6f, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, - 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x63, 0x68, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x6f, 0x73, 0x43, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x73, 0x43, - 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x12, 0x57, 0x0a, 0x2a, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6c, 0x31, 0x5f, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6c, 0x32, 0x5f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x65, 0x4c, 0x31, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x32, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, - 0x57, 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x64, 0x5f, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x5f, 0x6f, 0x73, - 0x70, 0x66, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5c, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x23, 0x62, 0x67, 0x70, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x4f, 0x73, 0x70, 0x66, 0x53, - 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x4e, 0x0a, 0x24, 0x70, 0x34, 0x72, 0x74, - 0x5f, 0x67, 0x64, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x64, 0x6f, - 0x74, 0x31, 0x71, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x18, 0x5d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x34, 0x72, 0x74, 0x47, 0x64, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x44, 0x6f, 0x74, 0x31, 0x71, 0x53, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x2a, 0x61, 0x74, 0x65, 0x5f, - 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x5e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x61, 0x74, - 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x65, - 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x73, 0x0a, 0x38, 0x69, - 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x60, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, 0x69, - 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x4c, 0x73, - 0x70, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x12, 0x4f, 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, - 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x62, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, - 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x53, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x5f, - 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x63, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x23, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x2b, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, 0x74, - 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, - 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x64, - 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x66, - 0x61, 0x62, 0x72, 0x69, 0x63, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, 0x6c, - 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x75, - 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6c, 0x69, - 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x74, 0x69, 0x6c, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2c, 0x0a, + 0x12, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x74, + 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x70, 0x61, 0x74, 0x68, 0x50, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x65, 0x73, 0x74, 0x1a, 0xb8, 0x01, 0x0a, 0x08, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2e, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, + 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6f, 0x6e, 0x64, 0x61, 0x74, + 0x72, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, + 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x61, 0x72, 0x64, + 0x77, 0x61, 0x72, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x6f, + 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, + 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, + 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, + 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xe5, 0x77, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x18, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x5f, 0x6c, 0x34, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x75, 0x64, 0x70, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x4c, 0x34, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x55, 0x64, 0x70, 0x12, + 0x3a, 0x0a, 0x19, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x17, 0x70, 0x72, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x28, 0x68, + 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, + 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x25, 0x68, + 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x57, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6c, 0x65, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x1f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, + 0x74, 0x69, 0x5f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, + 0x73, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x26, 0x69, + 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x65, + 0x76, 0x65, 0x6c, 0x31, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x69, 0x73, 0x69, + 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x31, + 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, + 0x41, 0x0a, 0x1d, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x74, + 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x69, 0x73, 0x69, 0x73, 0x53, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, 0x69, 0x73, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x26, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x49, 0x73, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, 0x69, + 0x53, 0x61, 0x66, 0x69, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x54, 0x0a, 0x27, 0x69, 0x73, + 0x69, 0x73, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, + 0x73, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x12, 0x58, 0x0a, 0x29, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x25, 0x69, 0x73, 0x69, 0x73, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x21, 0x69, 0x73, + 0x69, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x70, 0x5f, 0x6e, 0x65, 0x69, 0x67, + 0x68, 0x62, 0x6f, 0x72, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x11, 0x69, 0x70, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x4d, 0x69, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x13, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x6f, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x6f, + 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x37, 0x0a, 0x18, 0x6f, 0x73, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, 0x5f, + 0x72, 0x70, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x6f, 0x73, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x62, 0x79, 0x52, 0x70, 0x12, + 0x50, 0x0a, 0x25, 0x6c, 0x6c, 0x64, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, + 0x65, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, + 0x6c, 0x6c, 0x64, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x12, 0x55, 0x0a, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x67, 0x70, + 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x15, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x23, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x42, 0x67, 0x70, 0x4c, + 0x61, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x47, 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x1d, 0x69, 0x70, 0x76, 0x36, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x67, 0x72, 0x69, 0x62, 0x69, + 0x5f, 0x6e, 0x68, 0x5f, 0x64, 0x6d, 0x61, 0x63, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, + 0x69, 0x70, 0x76, 0x36, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x47, 0x72, 0x69, + 0x62, 0x69, 0x4e, 0x68, 0x44, 0x6d, 0x61, 0x63, 0x12, 0x45, 0x0a, 0x1f, 0x65, 0x63, 0x6e, 0x5f, + 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1c, 0x65, 0x63, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x45, 0x0a, 0x1f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, + 0x64, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x69, 0x70, 0x76, 0x36, 0x44, 0x69, + 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x64, 0x50, 0x6b, 0x74, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, + 0x64, 0x72, 0x6f, 0x70, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x1c, 0x63, + 0x6c, 0x69, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, + 0x6e, 0x63, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x6f, 0x63, 0x18, 0x1d, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x18, 0x63, 0x6c, 0x69, 0x54, 0x61, 0x6b, 0x65, 0x73, 0x50, 0x72, 0x65, 0x63, 0x65, + 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x4f, 0x63, 0x12, 0x3f, 0x0a, 0x1c, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x19, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, + 0x74, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x3b, 0x0a, 0x1a, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x69, 0x64, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x17, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x43, 0x68, 0x69, 0x70, 0x49, 0x64, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x25, 0x62, 0x61, 0x63, + 0x6b, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x61, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x46, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x21, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x2b, 0x6e, 0x6f, 0x5f, 0x6d, 0x69, + 0x78, 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x61, 0x6e, 0x64, 0x5f, + 0x75, 0x6e, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x6e, 0x6f, + 0x4d, 0x69, 0x78, 0x4f, 0x66, 0x54, 0x61, 0x67, 0x67, 0x65, 0x64, 0x41, 0x6e, 0x64, 0x55, 0x6e, + 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x77, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x25, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x14, 0x73, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x21, 0x65, 0x78, 0x70, + 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, + 0x72, 0x65, 0x66, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x26, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x1d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x27, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x78, 0x70, 0x6c, + 0x69, 0x63, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, + 0x29, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x50, + 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x65, 0x78, 0x70, 0x6c, + 0x69, 0x63, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x69, + 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x18, 0x2a, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x1d, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, + 0x72, 0x66, 0x12, 0x2c, 0x0a, 0x12, 0x71, 0x6f, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, + 0x64, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x71, 0x6f, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, + 0x12, 0x4f, 0x0a, 0x24, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, + 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, + 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x50, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x74, + 0x72, 0x79, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x22, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, + 0x6d, 0x61, 0x63, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x2e, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1d, 0x67, 0x72, 0x69, 0x62, 0x69, 0x4d, 0x61, 0x63, 0x4f, 0x76, 0x65, 0x72, + 0x72, 0x69, 0x64, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, + 0x70, 0x12, 0x4a, 0x0a, 0x22, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x41, + 0x66, 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x56, 0x0a, + 0x28, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x24, 0x67, 0x6e, 0x6f, 0x69, 0x46, 0x61, 0x62, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x6e, 0x74, 0x70, 0x5f, 0x6e, 0x6f, 0x6e, + 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x31, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, + 0x6e, 0x74, 0x70, 0x4e, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x72, 0x66, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x6f, + 0x6d, 0x69, 0x74, 0x5f, 0x6c, 0x32, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x6f, 0x6d, 0x69, 0x74, 0x4c, 0x32, 0x4d, 0x74, 0x75, 0x12, 0x46, 0x0a, 0x20, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, + 0x61, 0x72, 0x64, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, + 0x33, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x41, 0x64, + 0x6d, 0x69, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x64, 0x65, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x12, 0x2e, + 0x0a, 0x13, 0x62, 0x67, 0x70, 0x5f, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x62, 0x67, 0x70, + 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4d, + 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x61, 0x6c, 0x5f, 0x77, 0x61, 0x69, 0x74, + 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x6c, 0x69, + 0x6e, 0x6b, 0x51, 0x75, 0x61, 0x6c, 0x57, 0x61, 0x69, 0x74, 0x41, 0x66, 0x74, 0x65, 0x72, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x43, 0x0a, + 0x1e, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x65, 0x6d, 0x70, + 0x74, 0x79, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, + 0x3f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x12, 0x56, 0x0a, 0x28, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x40, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x62, 0x67, + 0x70, 0x5f, 0x6d, 0x64, 0x35, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x72, + 0x65, 0x73, 0x65, 0x74, 0x18, 0x41, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x62, 0x67, 0x70, 0x4d, + 0x64, 0x35, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, + 0x4b, 0x0a, 0x23, 0x64, 0x65, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x73, + 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x42, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x64, 0x65, + 0x71, 0x75, 0x65, 0x75, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x65, 0x64, 0x41, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, + 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x72, 0x69, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6f, 0x6e, 0x6c, + 0x79, 0x18, 0x43, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x67, 0x72, 0x69, 0x62, 0x69, 0x52, 0x69, + 0x62, 0x61, 0x63, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x61, 0x67, 0x67, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x44, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x45, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x30, 0x0a, + 0x14, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x34, 0x0a, 0x16, 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x47, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x14, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4c, 0x0a, 0x23, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x48, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x56, 0x72, 0x66, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x76, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x49, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x10, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x56, 0x6c, 0x61, 0x6e, 0x49, + 0x64, 0x12, 0x58, 0x0a, 0x2a, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x6f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, + 0x72, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, + 0x4a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x67, 0x72, 0x69, 0x62, 0x69, 0x4d, 0x61, 0x63, 0x4f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, + 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x4b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x6f, 0x73, 0x5f, + 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x71, 0x6f, + 0x73, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x70, 0x75, 0x5f, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x18, + 0x4d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x70, 0x75, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x30, 0x18, 0x4e, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x53, + 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x30, 0x12, 0x5f, 0x0a, 0x2d, + 0x67, 0x6e, 0x6f, 0x69, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x18, 0x4f, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x28, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, + 0x18, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x24, 0x70, 0x34, 0x72, 0x74, 0x5f, + 0x75, 0x6e, 0x73, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x5f, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x18, + 0x51, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x70, 0x34, 0x72, 0x74, 0x55, 0x6e, 0x73, 0x65, 0x74, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x62, 0x6b, 0x75, 0x70, + 0x5f, 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, + 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x52, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, 0x6b, + 0x75, 0x70, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x49, 0x0a, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, + 0x6e, 0x68, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x76, 0x72, 0x66, + 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x18, 0x53, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1d, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4e, 0x68, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x73, 0x56, 0x72, 0x66, 0x57, 0x69, 0x74, 0x68, 0x44, 0x65, 0x63, 0x61, 0x70, + 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x18, 0x55, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x69, 0x73, 0x69, 0x73, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x41, 0x66, 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x23, 0x70, 0x34, 0x72, 0x74, 0x5f, 0x6d, 0x6f, + 0x64, 0x69, 0x66, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x56, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1f, 0x70, 0x34, 0x72, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x5e, 0x0a, 0x2d, 0x6f, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x5f, 0x6f, 0x72, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x63, 0x61, 0x72, 0x64, 0x18, 0x57, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x6f, 0x73, 0x43, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x73, 0x53, + 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x4f, 0x72, 0x4c, 0x69, 0x6e, 0x65, 0x63, + 0x61, 0x72, 0x64, 0x12, 0x42, 0x0a, 0x1e, 0x6f, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x63, 0x68, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x6f, 0x73, 0x43, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x73, + 0x43, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x12, 0x57, 0x0a, 0x2a, 0x69, 0x73, 0x69, 0x73, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6c, 0x31, 0x5f, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6c, 0x32, 0x5f, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x65, 0x4c, 0x31, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x32, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x12, 0x57, 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x64, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x5f, 0x6f, + 0x73, 0x70, 0x66, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5c, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x62, 0x67, 0x70, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x4f, 0x73, 0x70, 0x66, + 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x4e, 0x0a, 0x24, 0x70, 0x34, 0x72, + 0x74, 0x5f, 0x67, 0x64, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x64, + 0x6f, 0x74, 0x31, 0x71, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x34, 0x72, 0x74, 0x47, 0x64, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x44, 0x6f, 0x74, 0x31, 0x71, 0x53, 0x75, 0x62, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x2a, 0x61, 0x74, 0x65, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x5e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x61, + 0x74, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, + 0x65, 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x73, 0x0a, 0x38, + 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x60, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, + 0x69, 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x4c, + 0x73, 0x70, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x12, 0x4f, 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, + 0x75, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x62, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x21, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x71, 0x6f, 0x73, 0x5f, 0x76, 0x6f, 0x71, 0x5f, 0x64, 0x72, - 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x71, 0x6f, - 0x73, 0x56, 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x55, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x61, 0x74, - 0x65, 0x5f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x68, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, 0x36, 0x46, 0x6c, 0x6f, 0x77, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x5f, - 0x63, 0x73, 0x6e, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x21, 0x69, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x43, 0x73, 0x6e, 0x70, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x71, 0x0a, 0x37, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x72, 0x65, 0x61, - 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6a, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x30, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x72, 0x6f, - 0x70, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x72, 0x65, 0x61, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6b, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, - 0x72, 0x50, 0x61, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, - 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6c, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, - 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x65, - 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x67, 0x6e, 0x6d, 0x69, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, - 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x61, 0x77, 0x47, 0x6e, 0x6d, 0x69, 0x12, 0x40, 0x0a, - 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x74, 0x63, 0x70, 0x5f, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x6e, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x6b, 0x69, 0x70, 0x54, 0x63, 0x70, 0x4e, 0x65, 0x67, - 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, - 0x4c, 0x0a, 0x23, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x69, 0x73, - 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, 0x61, - 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, - 0x15, 0x71, 0x6f, 0x73, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x70, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x71, 0x6f, - 0x73, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x49, 0x64, - 0x12, 0x55, 0x0a, 0x28, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x66, 0x69, 0x62, 0x5f, 0x66, 0x61, 0x69, - 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x66, 0x6f, 0x72, 0x77, - 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x71, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x23, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x69, 0x62, 0x46, 0x61, 0x69, 0x6c, 0x65, - 0x64, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x50, 0x0a, 0x25, 0x71, 0x6f, 0x73, 0x5f, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, - 0x18, 0x72, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x71, 0x6f, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x66, 0x0a, 0x31, 0x62, 0x67, 0x70, - 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, - 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, - 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x73, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, 0x62, 0x67, 0x70, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x45, - 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x45, 0x6e, - 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x31, 0x0a, 0x15, 0x62, 0x67, 0x70, 0x5f, 0x6c, 0x6c, 0x67, 0x72, 0x5f, 0x6f, 0x63, - 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x74, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x12, 0x62, 0x67, 0x70, 0x4c, 0x6c, 0x67, 0x72, 0x4f, 0x63, 0x55, 0x6e, 0x64, 0x65, 0x66, - 0x69, 0x6e, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x75, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x74, 0x75, 0x6e, - 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x74, 0x75, 0x6e, 0x6e, 0x65, - 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x76, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1b, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x61, 0x74, - 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x26, - 0x65, 0x63, 0x6e, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x78, - 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x77, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x65, 0x63, - 0x6e, 0x53, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x4d, 0x61, 0x78, 0x54, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x41, 0x0a, 0x1d, 0x71, 0x6f, 0x73, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, - 0x18, 0x78, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, 0x53, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x71, 0x6f, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x77, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x79, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x71, - 0x6f, 0x73, 0x53, 0x65, 0x74, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x42, 0x0a, 0x1e, - 0x71, 0x6f, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x7a, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x7b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, - 0x69, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x48, - 0x0a, 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x5f, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x18, 0x7c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x49, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x47, 0x0a, 0x20, 0x6d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x7d, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, - 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x4d, 0x0a, 0x24, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x6c, 0x71, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x7e, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x6c, 0x71, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x12, 0x4a, 0x0a, 0x22, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, - 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x7f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x62, 0x67, - 0x70, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x29, - 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x63, 0x5f, 0x6d, - 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x80, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x24, 0x62, 0x67, 0x70, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4f, 0x63, 0x4d, 0x61, - 0x78, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x26, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x62, - 0x67, 0x70, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x5f, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x5f, 0x61, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, - 0x18, 0x81, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x67, 0x70, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x57, 0x69, 0x74, 0x68, - 0x6f, 0x75, 0x74, 0x41, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, 0x12, 0x62, 0x0a, 0x2e, 0x6d, 0x69, - 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, - 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x82, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x29, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x48, - 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x49, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x68, - 0x0a, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, - 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x83, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2c, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x42, 0x65, 0x66, 0x6f, - 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5d, 0x0a, 0x2b, 0x67, 0x6e, 0x6f, 0x69, - 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, - 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x84, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, - 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x5f, - 0x6e, 0x6f, 0x6e, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x65, 0x78, - 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x85, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x6e, 0x42, 0x67, 0x70, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x55, 0x0a, - 0x27, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x79, - 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x86, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x23, 0x69, 0x73, 0x69, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x74, 0x79, 0x6c, 0x65, - 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x87, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x48, - 0x6f, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x55, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x19, 0x73, 0x6b, 0x69, - 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x68, 0x6f, 0x70, - 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x88, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x73, - 0x6b, 0x69, 0x70, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4e, 0x65, 0x78, 0x74, 0x68, 0x6f, 0x70, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x5f, 0x0a, 0x2c, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8a, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x69, 0x70, - 0x76, 0x36, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x41, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5d, 0x0a, 0x2b, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x5f, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8b, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x70, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, - 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x61, 0x73, 0x18, 0x8c, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, - 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x41, 0x73, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, - 0x69, 0x70, 0x5f, 0x70, 0x62, 0x66, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x63, 0x61, - 0x70, 0x5f, 0x65, 0x6e, 0x63, 0x61, 0x70, 0x5f, 0x76, 0x72, 0x66, 0x18, 0x8d, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x62, 0x66, 0x57, 0x69, 0x74, 0x68, 0x44, - 0x65, 0x63, 0x61, 0x70, 0x45, 0x6e, 0x63, 0x61, 0x70, 0x56, 0x72, 0x66, 0x12, 0x31, 0x0a, 0x14, - 0x74, 0x74, 0x6c, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x18, 0x8e, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x74, 0x74, 0x6c, - 0x43, 0x6f, 0x70, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x4b, 0x0a, 0x22, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x5f, 0x6d, - 0x69, 0x78, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x65, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8f, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x67, 0x72, - 0x69, 0x62, 0x69, 0x44, 0x65, 0x63, 0x61, 0x70, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6c, 0x65, - 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x65, - 0x76, 0x65, 0x6c, 0x18, 0x90, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70, - 0x49, 0x73, 0x69, 0x73, 0x53, 0x65, 0x74, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x44, 0x0a, 0x1f, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x91, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x49, 0x73, 0x69, 0x73, - 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, - 0x70, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, - 0x53, 0x65, 0x74, 0x52, 0x70, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x65, 0x74, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x27, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x93, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x62, 0x0a, 0x2e, 0x62, - 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, - 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x94, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, - 0x79, 0x53, 0x65, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x41, 0x0a, 0x1d, 0x70, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x75, 0x6c, 0x65, - 0x18, 0x95, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x70, 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x75, - 0x6c, 0x65, 0x12, 0x67, 0x0a, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x96, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x4f, 0x70, 0x74, - 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x73, - 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x70, - 0x18, 0x97, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x70, 0x12, 0x51, 0x0a, 0x25, 0x72, 0x65, 0x6f, 0x72, - 0x64, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x76, 0x65, - 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x74, - 0x79, 0x18, 0x98, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, - 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x46, 0x6f, 0x72, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x43, - 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x1f, 0x61, - 0x64, 0x64, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x69, 0x61, 0x5f, 0x63, 0x6c, 0x69, 0x18, 0x99, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x61, 0x64, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x42, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x69, 0x61, 0x43, 0x6c, - 0x69, 0x12, 0x33, 0x0a, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x9a, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x4d, 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x3d, 0x0a, 0x1b, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x69, - 0x62, 0x5f, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x9b, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, 0x67, - 0x70, 0x52, 0x69, 0x62, 0x4f, 0x63, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x9c, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x65, 0x74, 0x5f, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x18, 0x9d, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x65, 0x74, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x73, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x72, 0x0a, 0x38, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, 0x34, - 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x9e, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x2f, 0x69, 0x70, 0x76, 0x36, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x70, 0x76, 0x34, 0x4e, 0x65, 0x78, - 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x72, 0x70, 0x12, 0x50, 0x0a, 0x25, 0x70, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6f, - 0x72, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x9f, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, - 0x62, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x2e, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, - 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa0, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x58, 0x0a, 0x29, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, - 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x18, 0xa1, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x63, - 0x75, 0x72, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x2c, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x6f, - 0x70, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x74, 0x72, 0x79, 0x18, 0xa2, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x26, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x44, - 0x72, 0x6f, 0x70, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x74, 0x72, 0x79, 0x12, 0x73, 0x0a, 0x37, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x7a, - 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x5f, 0x74, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa3, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5a, 0x72, - 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x75, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x54, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x1f, 0x70, 0x6c, 0x71, 0x5f, - 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa4, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1c, 0x70, 0x6c, 0x71, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x6d, - 0x61, 0x78, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0xa5, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1e, 0x70, - 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x4d, 0x74, 0x75, 0x12, 0x4b, 0x0a, - 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, - 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x5f, - 0x70, 0x70, 0x73, 0x18, 0xa6, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1e, 0x70, 0x6c, 0x71, 0x47, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x50, 0x70, 0x73, 0x12, 0x57, 0x0a, 0x28, 0x62, 0x67, + 0x65, 0x64, 0x12, 0x53, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, + 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x63, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x23, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x2b, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, + 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, + 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, + 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, + 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, + 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, + 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6c, + 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x74, 0x69, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x71, 0x6f, 0x73, 0x5f, 0x76, 0x6f, 0x71, 0x5f, 0x64, + 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x71, + 0x6f, 0x73, 0x56, 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x61, + 0x74, 0x65, 0x5f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x68, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, 0x36, 0x46, 0x6c, 0x6f, + 0x77, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, + 0x5f, 0x63, 0x73, 0x6e, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x43, 0x73, 0x6e, 0x70, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, 0x37, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x72, 0x65, + 0x61, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6a, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x30, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x72, + 0x6f, 0x70, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x72, 0x65, 0x61, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0x6b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x22, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6c, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x67, 0x6e, 0x6d, 0x69, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x62, + 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x61, 0x77, 0x47, 0x6e, 0x6d, 0x69, 0x12, 0x40, + 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x74, 0x63, 0x70, 0x5f, 0x6e, 0x65, 0x67, 0x6f, 0x74, + 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, + 0x6e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x6b, 0x69, 0x70, 0x54, 0x63, 0x70, 0x4e, 0x65, + 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x12, 0x4c, 0x0a, 0x23, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x69, + 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, + 0x61, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x31, + 0x0a, 0x15, 0x71, 0x6f, 0x73, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x70, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x71, + 0x6f, 0x73, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x49, + 0x64, 0x12, 0x55, 0x0a, 0x28, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x66, 0x69, 0x62, 0x5f, 0x66, 0x61, + 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x66, 0x6f, 0x72, + 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x71, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x23, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x69, 0x62, 0x46, 0x61, 0x69, 0x6c, + 0x65, 0x64, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x50, 0x0a, 0x25, 0x71, 0x6f, 0x73, 0x5f, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x18, 0x72, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x71, 0x6f, 0x73, 0x42, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x66, 0x0a, 0x31, 0x62, 0x67, + 0x70, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, + 0x64, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x65, 0x6e, 0x63, 0x6f, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0x73, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2b, 0x62, 0x67, 0x70, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x12, 0x31, 0x0a, 0x15, 0x62, 0x67, 0x70, 0x5f, 0x6c, 0x6c, 0x67, 0x72, 0x5f, 0x6f, + 0x63, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x74, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x12, 0x62, 0x67, 0x70, 0x4c, 0x6c, 0x67, 0x72, 0x4f, 0x63, 0x55, 0x6e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x75, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x74, 0x75, 0x6e, 0x6e, + 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x76, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1b, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x61, + 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, + 0x26, 0x65, 0x63, 0x6e, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x6d, 0x61, + 0x78, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x77, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x65, + 0x63, 0x6e, 0x53, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x4d, 0x61, 0x78, 0x54, 0x68, 0x72, 0x65, + 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x41, 0x0a, 0x1d, 0x71, 0x6f, 0x73, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x18, 0x78, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, 0x53, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x21, 0x71, 0x6f, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x79, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, + 0x71, 0x6f, 0x73, 0x53, 0x65, 0x74, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x42, 0x0a, + 0x1e, 0x71, 0x6f, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0x7a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x71, 0x6f, 0x73, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x7b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, + 0x73, 0x69, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, + 0x48, 0x0a, 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, + 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x18, 0x7c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x49, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x47, 0x0a, 0x20, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, + 0x6b, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x7d, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, + 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x12, 0x4d, 0x0a, 0x24, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x6c, 0x71, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x7e, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x6c, 0x71, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x12, 0x4a, 0x0a, 0x22, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x72, + 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x7f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x62, + 0x67, 0x70, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x58, 0x0a, + 0x29, 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x63, 0x5f, + 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x80, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4f, 0x63, 0x4d, + 0x61, 0x78, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x26, 0x73, 0x6b, 0x69, 0x70, 0x5f, + 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x5f, 0x61, 0x66, 0x69, 0x73, 0x61, 0x66, + 0x69, 0x18, 0x81, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x67, + 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x57, 0x69, 0x74, + 0x68, 0x6f, 0x75, 0x74, 0x41, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, 0x12, 0x62, 0x0a, 0x2e, 0x6d, + 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, + 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x82, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, + 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, + 0x68, 0x0a, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x72, 0x64, 0x77, + 0x61, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x83, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2c, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x42, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5d, 0x0a, 0x2b, 0x67, 0x6e, 0x6f, + 0x69, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x72, + 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x84, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x27, 0x67, 0x6e, 0x6f, 0x69, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x65, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x85, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x6e, 0x42, 0x67, 0x70, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x55, + 0x0a, 0x27, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x86, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x23, 0x69, 0x73, 0x69, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x74, 0x79, 0x6c, + 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x87, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x29, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, + 0x48, 0x6f, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x66, 0x55, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x19, 0x73, 0x6b, + 0x69, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x68, 0x6f, + 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x88, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, + 0x73, 0x6b, 0x69, 0x70, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4e, 0x65, 0x78, 0x74, 0x68, 0x6f, + 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x5f, 0x0a, 0x2c, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8a, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x28, 0x69, + 0x70, 0x76, 0x36, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x41, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5d, 0x0a, 0x2b, 0x70, 0x72, 0x65, 0x66, 0x69, + 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, + 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8b, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, + 0x65, 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6d, 0x75, 0x6c, + 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x61, 0x73, 0x18, 0x8c, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x6c, 0x6f, + 0x77, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x41, 0x73, 0x12, 0x40, 0x0a, 0x1d, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x62, 0x66, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x63, + 0x61, 0x70, 0x5f, 0x65, 0x6e, 0x63, 0x61, 0x70, 0x5f, 0x76, 0x72, 0x66, 0x18, 0x8d, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x62, 0x66, 0x57, 0x69, 0x74, 0x68, + 0x44, 0x65, 0x63, 0x61, 0x70, 0x45, 0x6e, 0x63, 0x61, 0x70, 0x56, 0x72, 0x66, 0x12, 0x31, 0x0a, + 0x14, 0x74, 0x74, 0x6c, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8e, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x74, 0x74, + 0x6c, 0x43, 0x6f, 0x70, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x4b, 0x0a, 0x22, 0x67, 0x72, 0x69, 0x62, 0x69, 0x5f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x5f, + 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x65, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x8f, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x67, + 0x72, 0x69, 0x62, 0x69, 0x44, 0x65, 0x63, 0x61, 0x70, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6c, + 0x65, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, + 0x13, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x90, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, 0x6b, 0x69, + 0x70, 0x49, 0x73, 0x69, 0x73, 0x53, 0x65, 0x74, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x44, 0x0a, + 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x91, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x49, 0x73, 0x69, + 0x73, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, + 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, + 0x70, 0x53, 0x65, 0x74, 0x52, 0x70, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x65, 0x74, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x27, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x93, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x62, 0x0a, 0x2e, + 0x62, 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, + 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x94, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, + 0x74, 0x79, 0x53, 0x65, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x41, 0x0a, 0x1d, 0x70, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x18, 0x95, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x70, 0x66, 0x52, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, + 0x75, 0x6c, 0x65, 0x12, 0x67, 0x0a, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x96, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x2b, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x4f, 0x70, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x11, + 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, + 0x70, 0x18, 0x97, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x70, 0x12, 0x51, 0x0a, 0x25, 0x72, 0x65, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x76, + 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, + 0x74, 0x79, 0x18, 0x98, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x72, 0x65, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x46, 0x6f, 0x72, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, + 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x1f, + 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x69, 0x61, 0x5f, 0x63, 0x6c, 0x69, 0x18, + 0x99, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x61, 0x64, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x42, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x69, 0x61, 0x43, + 0x6c, 0x69, 0x12, 0x33, 0x0a, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x9a, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x13, 0x73, 0x6b, 0x69, 0x70, 0x4d, 0x61, 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x3d, 0x0a, 0x1b, 0x62, 0x67, 0x70, 0x5f, 0x72, + 0x69, 0x62, 0x5f, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x9b, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, + 0x67, 0x70, 0x52, 0x69, 0x62, 0x4f, 0x63, 0x50, 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x9c, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x72, 0x65, 0x66, 0x69, + 0x78, 0x53, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x65, 0x74, 0x5f, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x18, 0x9d, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x65, 0x74, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x73, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x72, 0x0a, 0x38, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, + 0x34, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x9e, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2f, 0x69, 0x70, 0x76, 0x36, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x70, 0x76, 0x34, 0x4e, 0x65, + 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x53, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x41, 0x72, 0x70, 0x12, 0x50, 0x0a, 0x25, 0x70, 0x66, 0x5f, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x62, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x9f, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, + 0x50, 0x62, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x2e, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa0, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x28, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x58, 0x0a, 0x29, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, + 0x5f, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x65, 0x18, 0xa1, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x24, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x52, 0x65, + 0x63, 0x75, 0x72, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x2c, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x64, 0x72, + 0x6f, 0x70, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x5f, 0x74, 0x65, 0x6c, 0x65, + 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xa2, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x26, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x54, 0x65, 0x6c, 0x65, 0x6d, + 0x65, 0x74, 0x72, 0x79, 0x12, 0x73, 0x0a, 0x37, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, + 0x7a, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x5f, 0x74, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, + 0xa3, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5a, + 0x72, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x54, + 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x1f, 0x70, 0x6c, 0x71, + 0x5f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa4, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x1c, 0x70, 0x6c, 0x71, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x5f, + 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x74, 0x75, 0x18, 0xa5, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1e, + 0x70, 0x6c, 0x71, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x4d, 0x74, 0x75, 0x12, 0x4b, + 0x0a, 0x22, 0x70, 0x6c, 0x71, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x78, + 0x5f, 0x70, 0x70, 0x73, 0x18, 0xa6, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1e, 0x70, 0x6c, 0x71, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x4d, 0x61, 0x78, 0x50, 0x70, 0x73, 0x12, 0x57, 0x0a, 0x28, 0x62, + 0x67, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, + 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, + 0x62, 0x67, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, + 0x6e, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x62, 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, + 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa8, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1e, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, + 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x69, 0x62, 0x5f, 0x77, 0x65, 0x63, 0x6d, 0x70, 0x18, 0xa9, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x69, 0x62, 0x57, 0x65, 0x63, 0x6d, 0x70, 0x12, + 0x43, 0x0a, 0x1d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x18, 0xaa, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x5f, 0x76, 0x65, 0x6e, 0x64, + 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x73, 0x65, + 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0xab, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1b, 0x75, 0x73, 0x65, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x1c, + 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6f, + 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0xac, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x67, 0x70, 0x53, 0x65, 0x6e, 0x64, + 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x5e, 0x0a, + 0x2c, 0x62, 0x67, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x74, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xae, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x62, 0x67, 0x70, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2a, 0x0a, + 0x11, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x18, 0xaf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x65, 0x74, 0x4e, 0x6f, + 0x50, 0x65, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x46, 0x0a, 0x20, 0x62, 0x67, 0x70, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x5f, 0x69, 0x73, 0x5f, 0x61, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0xb0, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, + 0x74, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x73, 0x41, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x12, 0x59, 0x0a, 0x2a, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, 0x36, + 0x5f, 0x6e, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0xb1, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x69, 0x70, 0x76, 0x34, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x70, 0x76, 0x36, 0x4e, + 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x59, 0x0a, 0x2a, + 0x69, 0x70, 0x76, 0x36, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6e, 0x68, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xb2, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x24, 0x69, 0x70, 0x76, 0x36, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x70, 0x76, 0x34, 0x4e, 0x68, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x19, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x72, 0x6f, + 0x70, 0x5f, 0x6e, 0x68, 0x18, 0xb3, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x44, 0x72, 0x6f, 0x70, + 0x4e, 0x68, 0x12, 0x49, 0x0a, 0x21, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, + 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0xb4, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x45, + 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x44, 0x0a, + 0x1e, 0x62, 0x67, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0xb5, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x62, 0x67, 0x70, 0x44, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x4a, 0x0a, 0x22, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x6f, 0x6e, 0x5f, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x18, 0xb6, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1d, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x42, 0x67, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x72, 0x66, 0x12, + 0x45, 0x0a, 0x1f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, + 0x65, 0x64, 0x18, 0xb7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x72, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x45, 0x6d, + 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x26, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x61, + 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x66, 0x6f, 0x72, + 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x61, 0x73, + 0x18, 0xb8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x66, 0x69, + 0x53, 0x61, 0x66, 0x69, 0x50, 0x61, 0x74, 0x68, 0x46, 0x6f, 0x72, 0x42, 0x67, 0x70, 0x4d, 0x75, + 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x41, 0x73, 0x12, 0x4c, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x6d, + 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, + 0x65, 0x78, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xb9, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x67, 0x65, 0x78, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x74, + 0x6f, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x66, 0x69, 0x73, 0x18, 0xba, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1b, 0x73, 0x61, 0x6d, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x74, 0x74, + 0x61, 0x63, 0x68, 0x65, 0x64, 0x54, 0x6f, 0x41, 0x6c, 0x6c, 0x41, 0x66, 0x69, 0x73, 0x12, 0x49, + 0x0a, 0x21, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x18, 0xbb, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, 0x6b, 0x69, 0x70, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x42, 0x0a, 0x1d, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xbc, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x55, 0x0a, + 0x27, 0x66, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0xbd, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x23, 0x66, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x57, 0x69, + 0x74, 0x68, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xbe, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x1d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x35, + 0x0a, 0x16, 0x73, 0x6c, 0x61, 0x61, 0x63, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x31, 0x32, 0x38, 0x18, 0xbf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x14, 0x73, 0x6c, 0x61, 0x61, 0x63, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x31, 0x32, 0x38, 0x12, 0x4d, 0x0a, 0x23, 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x61, 0x78, + 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc0, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x1f, 0x62, 0x67, 0x70, 0x4d, 0x61, 0x78, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x70, 0x61, 0x74, 0x68, 0x50, 0x61, 0x74, 0x68, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x59, 0x0a, 0x29, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x74, + 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x65, + 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x5f, 0x6f, 0x72, 0x5f, 0x61, 0x66, 0x69, 0x73, 0x61, 0x66, + 0x69, 0x18, 0xc1, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, + 0x61, 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4e, 0x65, + 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x4f, 0x72, 0x41, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, 0x12, + 0x35, 0x0a, 0x16, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc2, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x14, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x65, 0x0a, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, + 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, + 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc3, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x2b, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x6a, 0x0a, + 0x32, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x18, 0xc4, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2d, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x57, 0x0a, 0x29, 0x65, 0x6e, 0x63, + 0x61, 0x70, 0x5f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x75, 0x74, 0x5f, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x6e, 0x68, 0x67, 0x5f, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x74, + 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x18, 0xc5, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x65, + 0x6e, 0x63, 0x61, 0x70, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x68, 0x75, 0x74, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x4e, 0x68, 0x67, 0x5a, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x66, 0x66, + 0x69, 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x63, 0x6d, 0x70, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x73, 0x18, 0xc6, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x78, + 0x45, 0x63, 0x6d, 0x70, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x35, 0x0a, 0x16, 0x77, 0x65, 0x63, + 0x6d, 0x70, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x18, 0xc7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x77, 0x65, 0x63, 0x6d, + 0x70, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x4e, 0x0a, 0x23, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, + 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x35, 0x0a, 0x16, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, + 0x6b, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x65, 0x64, 0x5f, 0x65, 0x63, 0x6d, 0x70, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x70, + 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x65, 0x64, 0x45, 0x63, 0x6d, 0x70, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, + 0x0a, 0x19, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x5f, 0x6e, 0x68, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0xcb, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x16, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x4e, 0x68, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x53, 0x0a, 0x26, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, - 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, - 0x67, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, - 0x69, 0x74, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x22, 0x62, 0x67, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, - 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xa8, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1e, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, - 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x69, 0x62, 0x5f, 0x77, 0x65, 0x63, 0x6d, 0x70, 0x18, 0xa9, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x69, 0x62, 0x57, 0x65, 0x63, 0x6d, 0x70, 0x12, 0x43, - 0x0a, 0x1d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, - 0xaa, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, - 0x72, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x74, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0xab, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, - 0x75, 0x73, 0x65, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, - 0x61, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x73, - 0x6b, 0x69, 0x70, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6d, - 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0xac, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x67, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x43, - 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x5e, 0x0a, 0x2c, - 0x62, 0x67, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x5f, - 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xae, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x27, 0x62, 0x67, 0x70, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, - 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x11, - 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x18, 0xaf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x65, 0x74, 0x4e, 0x6f, 0x50, - 0x65, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x46, 0x0a, 0x20, 0x62, 0x67, 0x70, 0x5f, - 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x5f, 0x69, 0x73, 0x5f, 0x61, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0xb0, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x1b, 0x62, 0x67, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, - 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x73, 0x41, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x12, 0x59, 0x0a, 0x2a, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, 0x36, 0x5f, - 0x6e, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xb1, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x69, 0x70, 0x76, 0x34, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x70, 0x76, 0x36, 0x4e, 0x68, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x59, 0x0a, 0x2a, 0x69, - 0x70, 0x76, 0x36, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6e, 0x68, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xb2, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x24, 0x69, 0x70, 0x76, 0x36, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x70, 0x76, 0x34, 0x4e, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x19, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x72, 0x6f, 0x70, - 0x5f, 0x6e, 0x68, 0x18, 0xb3, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x44, 0x72, 0x6f, 0x70, 0x4e, - 0x68, 0x12, 0x49, 0x0a, 0x21, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0xb4, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x45, 0x78, - 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x44, 0x0a, 0x1e, - 0x62, 0x67, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xb5, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x62, 0x67, 0x70, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x4a, 0x0a, 0x22, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x67, 0x70, 0x5f, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x72, 0x66, 0x18, 0xb6, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1d, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x42, - 0x67, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x72, 0x66, 0x12, 0x45, - 0x0a, 0x1f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, - 0x64, 0x18, 0xb7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x45, 0x6d, 0x62, - 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x26, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x61, 0x66, - 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x66, 0x6f, 0x72, 0x5f, - 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x61, 0x73, 0x18, - 0xb8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x66, 0x69, 0x53, - 0x61, 0x66, 0x69, 0x50, 0x61, 0x74, 0x68, 0x46, 0x6f, 0x72, 0x42, 0x67, 0x70, 0x4d, 0x75, 0x6c, - 0x74, 0x69, 0x70, 0x6c, 0x65, 0x41, 0x73, 0x12, 0x4c, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x75, - 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x65, - 0x78, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xb9, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x67, 0x65, 0x78, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x74, 0x6f, - 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x66, 0x69, 0x73, 0x18, 0xba, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1b, 0x73, 0x61, 0x6d, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x74, 0x74, 0x61, - 0x63, 0x68, 0x65, 0x64, 0x54, 0x6f, 0x41, 0x6c, 0x6c, 0x41, 0x66, 0x69, 0x73, 0x12, 0x49, 0x0a, - 0x21, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x18, 0xbb, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x46, - 0x6f, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x42, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, - 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xbc, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1a, 0x73, 0x6b, 0x69, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x55, 0x0a, 0x27, - 0x66, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x77, - 0x69, 0x74, 0x68, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0xbd, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, - 0x66, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x57, 0x69, 0x74, - 0x68, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xbe, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x35, 0x0a, - 0x16, 0x73, 0x6c, 0x61, 0x61, 0x63, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x31, 0x32, 0x38, 0x18, 0xbf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, - 0x73, 0x6c, 0x61, 0x61, 0x63, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x31, 0x32, 0x38, 0x12, 0x4d, 0x0a, 0x23, 0x62, 0x67, 0x70, 0x5f, 0x6d, 0x61, 0x78, 0x5f, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc0, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1f, 0x62, 0x67, 0x70, 0x4d, 0x61, 0x78, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, - 0x61, 0x74, 0x68, 0x50, 0x61, 0x74, 0x68, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x12, 0x59, 0x0a, 0x29, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x74, 0x68, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x69, - 0x67, 0x68, 0x62, 0x6f, 0x72, 0x5f, 0x6f, 0x72, 0x5f, 0x61, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, - 0x18, 0xc1, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, - 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x69, - 0x67, 0x68, 0x62, 0x6f, 0x72, 0x4f, 0x72, 0x41, 0x66, 0x69, 0x73, 0x61, 0x66, 0x69, 0x12, 0x35, - 0x0a, 0x16, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc2, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x14, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x65, 0x0a, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, - 0x74, 0x79, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x65, - 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc3, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x2b, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x57, - 0x69, 0x74, 0x68, 0x52, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x6a, 0x0a, 0x32, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0xc4, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2d, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x57, 0x0a, 0x29, 0x65, 0x6e, 0x63, 0x61, - 0x70, 0x5f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x75, 0x74, 0x5f, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x6e, 0x68, 0x67, 0x5f, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x74, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 0x18, 0xc5, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x65, 0x6e, - 0x63, 0x61, 0x70, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x68, 0x75, 0x74, 0x42, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x4e, 0x68, 0x67, 0x5a, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, - 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x63, 0x6d, 0x70, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x73, 0x18, 0xc6, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x45, - 0x63, 0x6d, 0x70, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x35, 0x0a, 0x16, 0x77, 0x65, 0x63, 0x6d, - 0x70, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0xc7, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x77, 0x65, 0x63, 0x6d, 0x70, - 0x41, 0x75, 0x74, 0x6f, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x4e, 0x0a, 0x23, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xc8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x72, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x68, 0x61, 0x69, - 0x6e, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x35, 0x0a, 0x16, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, - 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x14, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x65, 0x64, 0x5f, 0x65, 0x63, 0x6d, 0x70, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x70, 0x61, - 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x65, 0x64, 0x45, 0x63, 0x6d, 0x70, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, - 0x19, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x5f, 0x6e, 0x68, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0xcb, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x16, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x4e, 0x68, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x53, 0x0a, 0x26, 0x62, 0x67, 0x70, - 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, - 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0xcc, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x62, 0x67, 0x70, 0x45, - 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, - 0x53, 0x65, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x59, - 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x63, 0x6f, - 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xcd, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x53, 0x65, 0x74, 0x45, 0x78, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x25, 0x62, 0x67, 0x70, - 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x62, 0x61, 0x6e, - 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0xce, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x62, 0x67, 0x70, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4f, 0x0a, 0x24, - 0x71, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, 0x72, 0x6f, 0x70, - 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x18, 0xcf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x71, 0x6f, 0x73, - 0x49, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x53, 0x0a, - 0x26, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x65, 0x78, - 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, - 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, 0xd0, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, - 0x62, 0x67, 0x70, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x12, 0x4d, 0x0a, 0x23, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x61, 0x67, 0x5f, - 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd1, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x4c, 0x0a, 0x23, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, - 0x64, 0x65, 0x66, 0x5f, 0x65, 0x62, 0x67, 0x70, 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd2, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1e, 0x70, 0x65, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x66, 0x45, 0x62, 0x67, - 0x70, 0x56, 0x72, 0x66, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x5a, 0x0a, 0x2a, 0x72, 0x65, 0x64, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x65, 0x62, 0x67, 0x70, 0x5f, 0x76, 0x72, - 0x66, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd3, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x72, 0x65, 0x64, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x45, 0x62, 0x67, 0x70, 0x56, 0x72, 0x66, - 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x57, 0x0a, 0x2a, 0x62, - 0x67, 0x70, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x69, 0x6e, 0x5f, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6e, 0x69, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, - 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x6e, 0x69, 0x18, 0xd4, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x22, 0x62, 0x67, 0x70, 0x41, 0x66, 0x69, 0x53, 0x61, 0x66, 0x69, 0x49, 0x6e, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4e, 0x69, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x4f, 0x74, 0x68, - 0x65, 0x72, 0x4e, 0x69, 0x12, 0x57, 0x0a, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, - 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x18, 0xd5, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x63, 0x0a, - 0x2e, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x76, - 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, - 0xd6, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2a, 0x69, 0x70, 0x76, 0x36, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x41, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x24, 0x64, 0x65, 0x63, 0x61, 0x70, 0x5f, 0x6e, 0x68, 0x5f, 0x77, - 0x69, 0x74, 0x68, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x68, 0x6f, 0x70, 0x5f, 0x6e, 0x69, 0x5f, 0x75, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd7, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x4e, 0x68, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, - 0x78, 0x74, 0x68, 0x6f, 0x70, 0x4e, 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x48, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, - 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x5f, 0x61, 0x6e, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x63, - 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x41, 0x6e, - 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, - 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd9, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, - 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0xda, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x10, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4d, 0x61, 0x73, 0x6b, - 0x4c, 0x65, 0x6e, 0x12, 0x62, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, - 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xdb, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x75, 0x73, - 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x46, 0x6f, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x44, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x66, 0x67, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xdc, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4d, 0x66, 0x67, 0x44, 0x61, - 0x74, 0x65, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x40, 0x0a, - 0x1c, 0x6f, 0x74, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x74, 0x72, 0x69, - 0x62, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xdd, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x6f, 0x74, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x54, 0x72, 0x69, 0x62, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x5b, 0x0a, 0x2a, 0x65, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, - 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xde, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x26, 0x65, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x53, 0x0a, 0x26, - 0x65, 0x74, 0x68, 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, 0xdf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x65, - 0x74, 0x68, 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, 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, + 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x18, 0xcc, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x62, 0x67, 0x70, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, + 0x79, 0x53, 0x65, 0x74, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, + 0x59, 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x63, + 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, + 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xcd, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x62, 0x67, 0x70, 0x53, 0x65, 0x74, 0x45, 0x78, 0x74, 0x43, + 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x52, 0x65, 0x66, 0x73, 0x55, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x25, 0x62, 0x67, + 0x70, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x62, 0x61, + 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x18, 0xce, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x62, 0x67, 0x70, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4f, 0x0a, + 0x24, 0x71, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, 0x72, 0x6f, + 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xcf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x71, 0x6f, + 0x73, 0x49, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x53, + 0x0a, 0x26, 0x62, 0x67, 0x70, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, + 0x79, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, 0xd0, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x22, 0x62, 0x67, 0x70, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x4d, 0x0a, 0x23, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x61, 0x67, + 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd1, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x61, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x23, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x64, 0x65, 0x66, 0x5f, 0x65, 0x62, 0x67, 0x70, 0x5f, 0x76, 0x72, 0x66, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd2, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1e, 0x70, 0x65, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x66, 0x45, 0x62, + 0x67, 0x70, 0x56, 0x72, 0x66, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x5a, 0x0a, 0x2a, 0x72, 0x65, 0x64, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x65, 0x62, 0x67, 0x70, 0x5f, 0x76, + 0x72, 0x66, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd3, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x72, 0x65, 0x64, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x45, 0x62, 0x67, 0x70, 0x56, 0x72, + 0x66, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x57, 0x0a, 0x2a, + 0x62, 0x67, 0x70, 0x5f, 0x61, 0x66, 0x69, 0x5f, 0x73, 0x61, 0x66, 0x69, 0x5f, 0x69, 0x6e, 0x5f, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6e, 0x69, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x6e, 0x69, 0x18, 0xd4, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x22, 0x62, 0x67, 0x70, 0x41, 0x66, 0x69, 0x53, 0x61, 0x66, 0x69, 0x49, 0x6e, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4e, 0x69, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x4f, 0x74, + 0x68, 0x65, 0x72, 0x4e, 0x69, 0x12, 0x57, 0x0a, 0x28, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0xd5, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x63, + 0x0a, 0x2e, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, + 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x18, 0xd6, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x2a, 0x69, 0x70, 0x76, 0x36, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x41, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x24, 0x64, 0x65, 0x63, 0x61, 0x70, 0x5f, 0x6e, 0x68, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x68, 0x6f, 0x70, 0x5f, 0x6e, 0x69, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd7, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1f, 0x64, 0x65, 0x63, 0x61, 0x70, 0x4e, 0x68, 0x57, 0x69, 0x74, 0x68, 0x4e, + 0x65, 0x78, 0x74, 0x68, 0x6f, 0x70, 0x4e, 0x69, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, + 0x5f, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x5f, 0x61, 0x6e, 0x79, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, + 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x41, + 0x6e, 0x79, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, 0x0a, + 0x27, 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xd9, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x23, 0x73, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0xda, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4d, 0x61, 0x73, + 0x6b, 0x4c, 0x65, 0x6e, 0x12, 0x62, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x6f, 0x72, + 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0xdb, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x29, 0x75, + 0x73, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x46, 0x6f, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x44, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x66, 0x67, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xdc, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4d, 0x66, 0x67, 0x44, + 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x40, + 0x0a, 0x1c, 0x6f, 0x74, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x74, 0x72, + 0x69, 0x62, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xdd, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x6f, 0x74, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x54, 0x72, 0x69, 0x62, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x5b, 0x0a, 0x2a, 0x65, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, + 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xde, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x26, 0x65, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x53, 0x0a, + 0x26, 0x65, 0x74, 0x68, 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, 0xdf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, + 0x65, 0x74, 0x68, 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, 0x4a, 0x0a, 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x18, 0xe0, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x12, 0x3e, + 0x0a, 0x1b, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x70, + 0x63, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xe1, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x47, 0x65, 0x74, + 0x52, 0x70, 0x63, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x56, + 0x0a, 0x28, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x72, 0x65, 0x66, 0x5f, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe2, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x23, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x65, 0x66, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x1f, 0x73, 0x73, 0x68, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0xe3, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1c, 0x73, 0x73, 0x68, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x65, 0x72, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, + 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, + 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, + 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, + 0x08, 0x13, 0x10, 0x14, 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 ( @@ -3438,7 +3493,7 @@ func file_metadata_proto_rawDescGZIP() []byte { var file_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_metadata_proto_goTypes = []any{ +var file_metadata_proto_goTypes = []interface{}{ (Metadata_Testbed)(0), // 0: openconfig.testing.Metadata.Testbed (Metadata_Tags)(0), // 1: openconfig.testing.Metadata.Tags (*Metadata)(nil), // 2: openconfig.testing.Metadata @@ -3467,7 +3522,7 @@ func file_metadata_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_metadata_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_metadata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Metadata); i { case 0: return &v.state @@ -3479,7 +3534,7 @@ func file_metadata_proto_init() { return nil } } - file_metadata_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_metadata_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Metadata_Platform); i { case 0: return &v.state @@ -3491,7 +3546,7 @@ func file_metadata_proto_init() { return nil } } - file_metadata_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_metadata_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Metadata_Deviations); i { case 0: return &v.state @@ -3503,7 +3558,7 @@ func file_metadata_proto_init() { return nil } } - file_metadata_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_metadata_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Metadata_PlatformExceptions); i { case 0: return &v.state diff --git a/proto/ocpaths.proto b/proto/ocpaths.proto index 46f3bd41717..ea7d21e6d57 100644 --- a/proto/ocpaths.proto +++ b/proto/ocpaths.proto @@ -58,6 +58,10 @@ message OCPath { // A set of opaque tags that are used for this path. These tags can be used // to group paths according to use-case specific criteria. repeated string tags = 4; + + // GNMIRpc describes expected (or supported) behavior for a particular + // Openconfig path. + GNMIRpc gnmi_rpc = 5; } // OCPathConstraint enumerates platform_types that are required to be supported @@ -76,3 +80,39 @@ message OCPathConstraint { string platform_type = 1; } } + +// GNMIRpc describes expected (or supported) behavior for a particular +// Openconfig path. +message GNMIRpc { + bool get = 1; + bool set = 2; + bool subscribe = 3; + + // SubscribeMode, describes how updates are triggered for the request. + enum SubscribeMode { + UNSPECIFIED_SUBSCRIBE_MODE = 0; + NO_READ_SUPPORT = 1; // No requirement / support for path. + STREAM = 2; // Values streamed by the target (Sec. 3.5.1.5.2). + ONCE = 3; // Values sent once-off by the target (Sec. 3.5.1.5.1). + POLL = 4; // Values sent in response to a poll request (Sec. 3.5.1.5.3). + } + repeated SubscribeMode sub_mode = 4; + + // StreamMode is the mode of a streamed subscription, specifying how the + // target must return values for that subscription. + // Reference: gNMI Specification Section 3.5.1.3 + enum StreamMode { + UNSPECIFIED_STREAM_MODE = 0; + NO_STREAMING_SUPPORT = 1; // No requirement / support for streaming path. + TARGET_DEFINED = 2; // The target selects for each element. + ON_CHANGE = 3; // The target sends an update on element value change. + SAMPLE = 4; // The target samples values according to the interval. + } + repeated StreamMode stream_mode = 5; + + // If listed as part of a requirement, sample_interval_nanoseconds is the + // maximum allowable interval between updates. + // If listed as part of the description of level of support, it should be the + // smallest, recommended value. + uint64 sample_interval_nanoseconds = 6; +} diff --git a/testregistry.textproto b/testregistry.textproto index 533758476f2..dff6a14c3bd 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -229,6 +229,12 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/qos/otg_tests/ingress_traffic_classification_and_rewrite_test/README.md" exec: " " } +test: { + id: "DP-1.17" + description: "ARP Policer" + readme: "" + exec: " " +} test: { id: "DP-1.2" description: "QoS policy feature config" @@ -269,6 +275,10 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/qos/ate_tests/wrr_traffic_test/README.md" exec: " " } +test: { + id: "DP-2.4" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/qos/otg_tests/ingress_police_nhg/README.md" +} test: { id: "FP-1.1" description: "Power admin DOWN/UP Test" @@ -277,7 +287,7 @@ test: { test: { id: "Health-1.1" description: "Generic Health Check" - readme: "https://github.com/openconfig/featureprofiles/blob/d26ac7fac5406af29c9a582b8d8ee73d56953e3b/feature/experimental/system/health/tests/system_generic_health_check/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/system/health/tests/system_generic_health_check/README.md" exec: " " } test: { @@ -336,7 +346,7 @@ test: { } test: { id: "P4RT-1.1" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/base_p4rt/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/base_p4rt/README.md" } test: { id: "P4RT-1.2" @@ -344,39 +354,39 @@ test: { } test: { id: "P4RT-2.1" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/tests/p4rt_election/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/tests/p4rt_election/README.md" } test: { id: "P4RT-2.2" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/tests/metadata_validation_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/tests/metadata_validation_test/README.md" } test: { id: "P4RT-3.1" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/google_discovery_protocol_packetin_test/README.md" } test: { id: "P4RT-3.2" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/google_discovery_protocol_packetout_test/README.md" } test: { id: "P4RT-5.1" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/traceroute_packetin_test/README.md" } test: { id: "P4RT-5.2" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/traceroute_packetout_test/README.md" } test: { id: "P4RT-6.1" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/performance_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/performance_test/README.md" } test: { id: "P4RT-7.1" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/lldp_packetin_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/lldp_packetin_test/README.md" } test: { id: "P4RT-7.2" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/p4rt/otg_tests/lldp_packetout_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/p4rt/otg_tests/lldp_packetout_test/README.md" } test: { id: "PF-1.1" @@ -408,10 +418,16 @@ test: { readme: " " exec: " " } +test: { + id: "PF-1.6" + description: "IPv4 & IPV6 based traffic steering from Non-default VRF to Default VRF using Policy based VRF selection" + readme: "" + exec: " " +} test: { id: "PLT-1.1" description: "Interface breakout Test" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/platform/tests/breakout_configuration/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/platform/tests/breakout_configuration/README.md" exec: " " } test: { @@ -466,13 +482,13 @@ test: { test: { id: "RT-1.11" description: "RT-1.11: BGP remove private AS" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/bgp/ate_tests/bgp_remove_private_as/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/otg_tests/bgp_remove_private_as/README.md" exec: " " } test: { id: "RT-1.12" description: "RT-1.12: BGP always compare MED" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/bgp/ate_tests/bgp_always_compare_med/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/otg_tests/bgp_always_compare_med/README.md" exec: " " } test: { @@ -514,7 +530,7 @@ test: { test: { id: "RT-1.19" description: "BGP 2-Byte and 4-Byte ASN support" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/otg_tests/bgp_2byte_4byte_asn/README.md" exec: " " } test: { @@ -538,7 +554,7 @@ test: { test: { id: "RT-1.24" description: "BGP 2-byte and 4-byte ASN support with policy" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/otg_tests/bgp_2byte_4byte_asn_policy_test/README.md" exec: " " } test: { @@ -620,7 +636,7 @@ test: { test: { id: "RT-1.53" description: "Prefix-set test" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/policy/prefix_set/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/policy_forwarding/otg_tests/prefix_set_test/README.md" exec: " " } test: { @@ -697,13 +713,25 @@ test: { test: { id: "RT-2.14" description: "ISIS Drain Test" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/isis/otg_tests/isis_drain_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/isis/otg_tests/isis_drain_test/README.md" + exec: " " +} +test: { + id: "RT-2.15" + description: "IS-IS Extensions for Segment Routing" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/isis/otg_tests/isis_extensions_segment_routing_test/README.md" + exec: " " +} +test: { + id: "RT-2.15" + description: "IS-IS Graceful Restart Helper" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/isis/otg_tests/graceful_restart_helper/README.md" exec: " " } test: { id: "RT-2.2" description: "IS-IS LSP Updates" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/isis/otg_tests/lsp_updates_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/isis/otg_tests/lsp_updates_test/README.md" } test: { id: "RT-2.6" @@ -732,13 +760,31 @@ test: { test: { id: "RT-3.1" description: "Policy based VRF selection base" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/policy/policy_vrf_selection/ate_tests/base_vrf_selection/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/policy_forwarding/policy_vrf_selection/otg_tests/base_vrf_selection/README.md" exec: " " } test: { id: "RT-3.2" description: "Policy based VRF selection with multiple protocol and DSCP values" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/policy/policy_vrf_selection/ate_tests/protocol_dscp_rules_for_vrf_selection_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/policy_forwarding/policy_vrf_selection/otg_tests/protocol_dscp_rules_for_vrf_selection_test/README.md" + exec: " " +} +test: { + id: "RT-3.3" + description: "Multiple VRFs and GUE DECAP in Default VRF" + readme: "" + exec: " " +} +test: { + id: "RT-3.31" + description: "DSCP based traffic steering from default VRF to non-Default VRF using Policy based VRF selection plus GUE DECAP" + readme: "" + exec: " " +} +test: { + id: "RT-3.32" + description: "DSCP based traffic steering from Non-default VRF to Default VRF using Policy based VRF selection plus GUE DECAP and ENCAP" + readme: "" exec: " " } test: { @@ -804,7 +850,7 @@ test: { test: { id: "RT-5.6" description: "Interface Loopback mode" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/README.md" } test: { id: "RT-5.7" @@ -867,7 +913,7 @@ test: { test: { id: "RT-7.5" description: "BGP Policy - Set Link Bandwidth Community" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/bgp/otg_tests/link_bandwidth_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/bgp/otg_tests/link_bandwidth_test/README.md" } test: { id: "RT-7.6" @@ -918,7 +964,7 @@ test: { } test: { id: "Replay-1.2" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/replay/tests/p4rt_replay/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/replay/tests/p4rt_replay/README.md" } test: { id: "SFLOW-1" @@ -985,22 +1031,32 @@ test: { } test: { id: "TE-16.1" + description: "gRIBI Traffic Engineering - Basic encapsulation tests" readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/basic_encap_test/README.md" } test: { id: "TE-16.2" - description: "gRIBI encapsulation FRR scenarios" + description: "gRIBI Traffic Engineering encapsulation FRR scenarios" readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/encap_frr/README.md" } +test: { + id: "TE-16.3" + description: "gRIBI Traffic Engineering Encapsulation with Re-encap NI FRR scenarios" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/encap_frr_with_reencap_vrf_test/README.md" +} test: { id: "TE-17.1" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/gribi/otg_tests/vrf_policy_driven_te/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/vrf_policy_driven_te/README.md" } test { id: "TE-18.1" description: "MPLS in UDP Encapsulation with QoS scheduler" readme: "" } +test: { + id: "TE-18.3" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/gribi/otg_tests/mpls_in_udp_scale/README.md" +} test: { id: "TE-2.1" description: "gRIBI IPv4 Entry" @@ -1544,7 +1600,7 @@ test: { test: { id: "gNMI-1.20" description: "Telemetry: Optics Thresholds" - readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/platform/tests/optics_thresholds_test/README.md" + readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/platform/tests/optics_thresholds_test/README.md" exec: " " } test: {