diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering/README.md b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering/README.md new file mode 100644 index 00000000000..5b47195e477 --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering/README.md @@ -0,0 +1,644 @@ +# AFT-6.1: AFT Prefix Filtering + +## Summary + +This test validates the core AFT global filter mechanism, which restricts gNMI +streaming AFT updates to only the prefixes matching a specified routing policy. +Tests cover initial synchronization, dynamic updates, error handling for +non-existent policies, and policy deletion behavior. + +See also: +[AFT-6.2](../afts_prefix_filtering_dualstack/README.md) (Dual-Stack), +[AFT-6.3](../afts_prefix_filtering_resilience/README.md) (Resilience), +[AFT-6.4](../afts_prefix_filtering_dynamic/README.md) (Dynamic Updates). + +## Testbed type + +[atedut_2.testbed](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed) + +## Test Setup + +### Test environment setup + +- The `DUT` and `ATE` are connected via two links (`port1` and `port2`). + +- Basic interface configuration is applied to the `DUT` and `ATE`. + +- The DUT is pre-configured with static routes to populate the AFT. Routes + include a mix of IPv4 and IPv6 prefixes drawn from RFC 5737 test address + space (see IP address conventions in `CONTRIBUTING.md`). At minimum the + following prefixes are installed in the `DEFAULT` network instance: + `198.51.100.0/24`, `203.0.113.0/28`, `100.64.0.0/24`, `2001:DB8:1::/64`, and + `2001:DB8:3::/64`. + +- The DUT is pre-configured with the following routing policies under + `/routing-policy/policy-definitions/`: + + - `POLICY-MATCH-ALL`: Matches all routes (unconditional accept). + + - `POLICY-PREFIX-SET-A`: Matches a specific set of IPv4 prefixes: + `198.51.100.0/24`, `203.0.113.0/28`, and `198.51.100.1/32`. + + - `POLICY-PREFIX-SET-B`: Matches a specific set of IPv6 prefixes: + `2001:DB8:2::/64` and `2001:DB8:2::1/128`. + + - `POLICY-PREFIX-SET-VRF-A`: Matches any IPv4 prefix within + `100.64.1.0/24` with a masklength range of `/24` to `/32`. + + - `POLICY-SUBNET`: Matches any IPv4 prefix within `203.0.113.0/24` with a + masklength range of `/25` to `/32` (i.e., any subnet of that block). + + - `POLICY-SUBNET-V6`: Matches any IPv6 prefix within `2001:DB8:3::/64` + with a masklength range of `/65` to `/128` (i.e., any subnet of that + block). + +### Test Case Iteration + +**AFT-6.1.1** is a parameterized test. Its subscribe and validate steps must be +repeated for each address family, substituting the appropriate policy: +`POLICY-PREFIX-SET-A` (IPv4) and `POLICY-PREFIX-SET-B` (IPv6), `POLICY-SUBNET` +(IPv4), and `POLICY-SUBNET-V6` (IPv6). For each iteration, only policy should be +configured (e.g., when testing IPv4, only `ipv4-policy` is set). Ensure the AFT +contains both matching and non-matching entries appropriate for the policy and +address family under test before subscribing. (Note: Simultaneous application of +both policies is covered in +[AFT-6.2.1](../afts_prefix_filtering_dualstack/README.md#aft-621---simultaneous-independent-ipv4-and-ipv6-policy-application)). + +## AFT-6.1.1 - Validation of Subscription with Prefix-Set Policy + +### Configure Routing Policy and Prefixes + +- Ensure `DUT` has `POLICY-PREFIX-SET-A` configured to match prefixes + `198.51.100.0/24`, `203.0.113.0/28`, and `198.51.100.1/32`. + +- Ensure the DUT's AFT contains entries for `198.51.100.0/24`, + `203.0.113.0/28`, and at least one non-matching prefix (`100.64.0.0/24`). + +- Configure the global-filter leaf for the address family under test to the + selected policy. For example, when testing `POLICY-PREFIX-SET-A`: + + - Set + `/network-instances/network-instance/afts/global-filter/config/ipv4-policy` + to `POLICY-PREFIX-SET-A`. + - Ensure + `/network-instances/network-instance/afts/global-filter/config/ipv6-policy` + is NOT set (or set to an empty/matching-none policy). + +### Subscribe + +Establish a gNMI STREAM subscription (ON_CHANGE) to the DUT targeting the +following paths within the `DEFAULT` network instance AFT: + +```protobuf +subscribe: { + prefix: { + target: "target-device" + origin: "openconfig" + path: { + elem: { name: "network-instances" } + elem: { name: "network-instance" key: { key: "name" value: "DEFAULT" } } + elem: { name: "afts" } + } + } + subscription: { + path: { + elem: { name: "global-filter" } + elem: { name: "state" } + } + mode: ON_CHANGE + } + subscription: { + path: { + elem: { name: "ipv4-unicast" } + elem: { name: "ipv4-entry" } + } + mode: ON_CHANGE + } + subscription: { + path: { + elem: { name: "ipv6-unicast" } + elem: { name: "ipv6-entry" } + } + mode: ON_CHANGE + } + subscription: { + path: { + elem: { name: "next-hop-groups" } + elem: { name: "next-hop-group" } + } + mode: ON_CHANGE + } + subscription: { + path: { + elem: { name: "next-hops" } + elem: { name: "next-hop" } + } + mode: ON_CHANGE + } + mode: STREAM + encoding: PROTO +} +``` + +### Validate Initial Synced Data + +- Wait for the initial set of gNMI Notifications and verify `SYNC` is + received. + +- Verify that Notifications are received **only** for prefixes matching + `POLICY-PREFIX-SET-A` (`198.51.100.0/24`, `203.0.113.0/28`, + `198.51.100.1/32`), plus any necessary recursive resolution prefixes. + +- Verify that the non-matching prefix (`100.64.0.0/24`) is **not** received. + +- Verify that all next-hop-groups and next-hops referenced by matching + prefixes are received. + +- Verify that every received next-hop-group is referenced by at least one + received prefix. + +- Verify that every received next-hop is referenced by at least one received + next-hop-group. + +- Verify that the `atomic` flag is set to `true` on all initial update + notifications. (See AFT-3.1 for complete atomic-flag behavior coverage.) + +### Validate Dynamic Updates + +- Add a new prefix (`198.51.100.1/32`) to the DUT that matches + `POLICY-PREFIX-SET-A`. Verify receipt of an update notification for this + prefix and its associated next-hop-groups and next-hops. + +- Remove `198.51.100.1/32` from the DUT. Verify receipt of a delete + notification for the prefix. Verify that the next-hop-group and next-hop + shared with `198.51.100.0/24` are **not** deleted, since they are still + referenced by the remaining prefix. + +- Add a new prefix (`100.64.1.0/24`) to the DUT that does **not** match the + routing policy. Verify that **no** gNMI update is received for this prefix. + +### Remove the Filtered View + +- Delete the `global-filter` configuration from the DUT. + +- Verify receipt of a delete notification for + `/network-instances/network-instance/afts/global-filter/state/ipv4-policy` + and + `/network-instances/network-instance/afts/global-filter/state/ipv6-policy`. + +- Verify that the previously excluded prefix `100.64.0.0/24` is now received, + confirming the filter has been lifted. + +## AFT-6.1.2 - Validation with Non-Existent Policy + +- Attempt to configure the AFT global filter `ipv4-policy` and `ipv6-policy` + with `POLICY-DOES-NOT-YET-EXIST`. + + - Verify a `FAILED_PRECONDITION` error is returned. + +- Apply a configuration to the DUT defining `POLICY-DOES-NOT-YET-EXIST` to + match prefix `198.51.100.128/25`. + +- Again configure the AFT global filter `ipv4-policy` and `ipv6-policy` to + `POLICY-DOES-NOT-YET-EXIST`. Verify no error is returned. + +- Subscribe to the AFT as in **AFT-6.1.1** and verify: + + - `SYNC` is received. + - Notifications are received only for `198.51.100.128/25` and its + associated next-hops/groups. + - Prefixes that do not match `POLICY-DOES-NOT-YET-EXIST` are **not** + received. + +## AFT-6.1.3 - Validation of Policy Deletion + +- Configure the device to filter AFT using `POLICY-PREFIX-SET-A`. + +- Establish a gNMI Subscribe session and wait for `SYNC`. + +- Attempt to delete `POLICY-PREFIX-SET-A` from the DUT while the global filter + still references it. + + - Verify a `FAILED_PRECONDITION` error is returned, indicating the + global-filter reference must be removed first. + +- Delete both the global filter and `POLICY-PREFIX-SET-A` in a single atomic + gNMI.Set request. + + - Verify no errors are returned. + +- Verify that the previously excluded prefix `100.64.0.0/24` is now received, + confirming the filter has been lifted. + +- Re-configure `POLICY-PREFIX-SET-A` and set the global filter to reference + it. + +- Verify notifications match the expected filtered set as in **AFT-6.1.1**. + +### Multi-Step Policy Deletion + +- Delete the global filter reference in a first gNMI.Set request. Verify no + error is returned. + +- Delete `POLICY-PREFIX-SET-A` in a separate, second gNMI.Set request. Verify + no error is returned. + +- Verify that the previously excluded prefix `100.64.0.0/24` is now received, + confirming the filter has been lifted. + +## OpenConfig Path and RPC Coverage + +> **TODO:** The `global-filter` container and its `config/ipv4-policy`, +> `config/ipv6-policy`, `state/ipv4-policy` and `state/ipv6-policy` leaves are +> proposed extensions to the OpenConfig AFT model and are not yet present in the +> master branch of [openconfig/public](https://github.com/openconfig/public). +> This README may be merged before the TODO is resolved. +> +> The OpenConfig pull request is +> [#1441](https://github.com/openconfig/public/pull/1441). + +```yaml +paths: + # Proposed paths for the new filter mechanism (not yet in openconfig/public) + # /network-instances/network-instance/afts/global-filter/config/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/config/ipv6-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv6-policy: + + # Standard AFT state paths + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group: + /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-hop-groups/next-hop-group/next-hops/next-hop/state/weight: + /network-instances/network-instance/afts/next-hops/next-hop/state/index: + /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address: + /network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/interface: + + # Paths for configuring policies and prefix-sets (used in setup) + /routing-policy/defined-sets/prefix-sets/prefix-set/config/name: + /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/ip-prefix: + /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/masklength-range: + /routing-policy/policy-definitions/policy-definition/config/name: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result: + /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/index: + /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/next-hop: + +rpcs: + gnmi: + gNMI.Subscribe: + STREAM: true + ON_CHANGE: true + gNMI.Set: + REPLACE: true + UPDATE: true + DELETE: true +``` + +## Canonical OC + +The following JSON shows the expected OpenConfig configuration for the routing +policies and static routes used in the test setup. The `global-filter` +configuration uses proposed OC paths and is excluded from this JSON (see TODO +above). + +```json +{ + "routing-policy": { + "defined-sets": { + "prefix-sets": { + "prefix-set": [ + { + "name": "PREFIX-SET-A", + "config": { + "name": "PREFIX-SET-A" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "198.51.100.0/24", + "masklength-range": "exact", + "config": { + "ip-prefix": "198.51.100.0/24", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "203.0.113.0/28", + "masklength-range": "exact", + "config": { + "ip-prefix": "203.0.113.0/28", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "198.51.100.1/32", + "masklength-range": "exact", + "config": { + "ip-prefix": "198.51.100.1/32", + "masklength-range": "exact" + } + } + ] + } + }, + { + "name": "PREFIX-SET-B", + "config": { + "name": "PREFIX-SET-B" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "2001:DB8:2::/64", + "masklength-range": "exact", + "config": { + "ip-prefix": "2001:DB8:2::/64", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "2001:DB8:2::1/128", + "masklength-range": "exact", + "config": { + "ip-prefix": "2001:DB8:2::1/128", + "masklength-range": "exact" + } + } + ] + } + }, + { + "name": "PREFIX-SET-VRF-A", + "config": { + "name": "PREFIX-SET-VRF-A" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "100.64.1.0/24", + "masklength-range": "24..32", + "config": { + "ip-prefix": "100.64.1.0/24", + "masklength-range": "24..32" + } + } + ] + } + }, + { + "name": "PREFIX-SET-SUBNET", + "config": { + "name": "PREFIX-SET-SUBNET" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "203.0.113.0/24", + "masklength-range": "25..32", + "config": { + "ip-prefix": "203.0.113.0/24", + "masklength-range": "25..32" + } + } + ] + } + }, + { + "name": "PREFIX-SET-SUBNET-V6", + "config": { + "name": "PREFIX-SET-SUBNET-V6" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "2001:DB8:3::/64", + "masklength-range": "65..128", + "config": { + "ip-prefix": "2001:DB8:3::/64", + "masklength-range": "65..128" + } + } + ] + } + } + ] + } + }, + "policy-definitions": { + "policy-definition": [ + { + "name": "POLICY-MATCH-ALL", + "config": { + "name": "POLICY-MATCH-ALL" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-PREFIX-SET-A", + "config": { + "name": "POLICY-PREFIX-SET-A" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-A", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-PREFIX-SET-B", + "config": { + "name": "POLICY-PREFIX-SET-B" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-B", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-PREFIX-SET-VRF-A", + "config": { + "name": "POLICY-PREFIX-SET-VRF-A" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-VRF-A", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-SUBNET", + "config": { + "name": "POLICY-SUBNET" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-SUBNET", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-SUBNET-V6", + "config": { + "name": "POLICY-SUBNET-V6" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-SUBNET-V6", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + } + ] + } + }, + "network-instances": { + "network-instance": [ + { + "name": "DEFAULT", + "protocols": { + "protocol": [ + { + "identifier": "STATIC", + "name": "STATIC", + "config": { + "identifier": "STATIC", + "name": "STATIC" + }, + "static-routes": { + "static": [ + { + "prefix": "198.51.100.0/24", + "config": { "prefix": "198.51.100.0/24" }, + "next-hops": { + "next-hop": [ + { + "index": "0", + "config": { "index": "0", "next-hop": "192.0.2.2" } + } + ] + } + }, + { + "prefix": "203.0.113.0/28", + "config": { "prefix": "203.0.113.0/28" }, + "next-hops": { + "next-hop": [ + { + "index": "0", + "config": { "index": "0", "next-hop": "192.0.2.2" } + } + ] + } + }, + { + "prefix": "100.64.0.0/24", + "config": { "prefix": "100.64.0.0/24" }, + "next-hops": { + "next-hop": [ + { + "index": "0", + "config": { "index": "0", "next-hop": "192.0.2.2" } + } + ] + } + } + ] + } + } + ] + } + } + ] + } +} +``` + +## Required DUT platform + +FFF (Fixed Form Factor) or MFF (Modular Form Factor). diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering/metadata.textproto b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering/metadata.textproto new file mode 100644 index 00000000000..18f5d983a36 --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "3cf4e073-148a-4b92-b12c-1bfb4d5dce61" +plan_id: "AFT-6.1" +description: "AFT Prefix Filtering" +testbed: TESTBED_DUT_ATE_2LINKS diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dualstack/README.md b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dualstack/README.md new file mode 100644 index 00000000000..e1f9e59b3af --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dualstack/README.md @@ -0,0 +1,242 @@ +# AFT-6.2: AFT Prefix Filtering Dual-Stack + +## Summary + +This test validates that IPv4 and IPv6 AFT filters can be applied independently +and concurrently using different routing policies on the same network instance. + +See [AFT-6.1](../afts_prefix_filtering/README.md) for common test setup and +policy definitions. + +## Testbed type + +[atedut_2.testbed](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed) + +## Test Setup + +Use the test environment and routing policies described in +[AFT-6.1](../afts_prefix_filtering/README.md#test-setup). In particular, ensure +the following policies and prefixes are configured: + +- `POLICY-PREFIX-SET-A`: Matches IPv4 prefixes `198.51.100.0/24`, + `203.0.113.0/28`, and `198.51.100.1/32`. + +- `POLICY-PREFIX-SET-B`: Matches IPv6 prefixes `2001:DB8:2::/64` and + `2001:DB8:2::1/128`. + +- The DUT's AFT contains entries for both matching and non-matching prefixes in + each address family (e.g., `100.64.0.0/24` for IPv4, `2001:DB8:1::/64` for + IPv6). + +## AFT-6.2.1 - Simultaneous Independent IPv4 and IPv6 Policy Application + +### Setup + +- Configure the global filter such that different address families use + different policies: + + - `/network-instances/network-instance[name=DEFAULT]/afts/global-filter/config/ipv4-policy` = + `POLICY-PREFIX-SET-A` + - `/network-instances/network-instance[name=DEFAULT]/afts/global-filter/config/ipv6-policy` = + `POLICY-PREFIX-SET-B` + +### Validation + +- Establish a gNMI STREAM subscription (ON_CHANGE) to the AFT of the `DEFAULT` + network instance as described in + [AFT-6.1.1](../afts_prefix_filtering/README.md#aft-611---validation-of-subscription-with-prefix-set-policy). + +- Wait for `SYNC`. + +- Verify that the received IPv4 entries match `POLICY-PREFIX-SET-A` + (`198.51.100.0/24`, `203.0.113.0/28`, `198.51.100.1/32`). + +- Verify that the received IPv6 entries match `POLICY-PREFIX-SET-B` + (`2001:DB8:2::/64`, `2001:DB8:2::1/128`). + +- Verify that prefixes NOT covered by their respective policies are barred + from the stream (e.g., IPv4 prefix `100.64.0.0/24`). + +- Update the configuration to swap the policies: + + - `ipv4-policy` = `POLICY-PREFIX-SET-B` (Matches nothing for IPv4) + - `ipv6-policy` = `POLICY-PREFIX-SET-A` (Matches nothing for IPv6) + +- Verify that deletes are received, deleting all prefixes, as the cross-family + matching results in an empty set. + +## OpenConfig Path and RPC Coverage + +> **TODO:** The `global-filter` container and its `config/ipv4-policy`, +> `config/ipv6-policy`, `state/ipv4-policy` and `state/ipv6-policy` leaves are +> proposed extensions to the OpenConfig AFT model and are not yet present in the +> master branch of [openconfig/public](https://github.com/openconfig/public). +> This README may be merged before the TODO is resolved. +> +> The OpenConfig pull request is +> [#1441](https://github.com/openconfig/public/pull/1441). + +```yaml +paths: + # Proposed paths for the new filter mechanism (not yet in openconfig/public) + # /network-instances/network-instance/afts/global-filter/config/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/config/ipv6-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv6-policy: + + # Standard AFT state paths + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group: + /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/state/index: + /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address: + +rpcs: + gnmi: + gNMI.Subscribe: + STREAM: true + ON_CHANGE: true + gNMI.Set: + REPLACE: true + UPDATE: true +``` + +## Canonical OC + +See [AFT-6.1](../afts_prefix_filtering/README.md#canonical-oc) for the full +canonical OpenConfig configuration. This test uses `POLICY-PREFIX-SET-A` and +`POLICY-PREFIX-SET-B` as defined there. + +```json +{ + "routing-policy": { + "defined-sets": { + "prefix-sets": { + "prefix-set": [ + { + "name": "PREFIX-SET-A", + "config": { + "name": "PREFIX-SET-A" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "198.51.100.0/24", + "masklength-range": "exact", + "config": { + "ip-prefix": "198.51.100.0/24", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "203.0.113.0/28", + "masklength-range": "exact", + "config": { + "ip-prefix": "203.0.113.0/28", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "198.51.100.1/32", + "masklength-range": "exact", + "config": { + "ip-prefix": "198.51.100.1/32", + "masklength-range": "exact" + } + } + ] + } + }, + { + "name": "PREFIX-SET-B", + "config": { + "name": "PREFIX-SET-B" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "2001:DB8:2::/64", + "masklength-range": "exact", + "config": { + "ip-prefix": "2001:DB8:2::/64", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "2001:DB8:2::1/128", + "masklength-range": "exact", + "config": { + "ip-prefix": "2001:DB8:2::1/128", + "masklength-range": "exact" + } + } + ] + } + } + ] + } + }, + "policy-definitions": { + "policy-definition": [ + { + "name": "POLICY-PREFIX-SET-A", + "config": { + "name": "POLICY-PREFIX-SET-A" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-A", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-PREFIX-SET-B", + "config": { + "name": "POLICY-PREFIX-SET-B" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-B", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + } + ] + } + } +} +``` + +## Required DUT platform + +FFF (Fixed Form Factor) or MFF (Modular Form Factor). diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dualstack/metadata.textproto b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dualstack/metadata.textproto new file mode 100644 index 00000000000..3267859d6e5 --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dualstack/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "8a04d024-82b3-4bff-9c7c-27f4cccdf452" +plan_id: "AFT-6.2" +description: "AFT Prefix Filtering Dual-Stack" +testbed: TESTBED_DUT_ATE_2LINKS diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dynamic/README.md b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dynamic/README.md new file mode 100644 index 00000000000..4bea0e97ab1 --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dynamic/README.md @@ -0,0 +1,260 @@ +# AFT-6.4: AFT Prefix Filtering Dynamic Updates + +## Summary + +This test validates that the AFT filter dynamically responds to changes in the +underlying prefix sets without requiring a re-binding of the policy itself. Both +IPv4 and IPv6 prefix-set modifications are covered. + +See [AFT-6.1](../afts_prefix_filtering/README.md) for common test setup and +policy definitions. + +## Testbed type + +[atedut_2.testbed](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed) + +## Test Setup + +Use the test environment and routing policies described in +[AFT-6.1](../afts_prefix_filtering/README.md#test-setup). + +### IPv4 Setup + +- Configure `POLICY-PREFIX-SET-A` which references `PREFIX-SET-A`. +- Set the global filter `ipv4-policy` to `POLICY-PREFIX-SET-A`. +- Ensure the DUT has static routes for `198.51.100.0/24` and `203.0.113.0/28`. +- Establish a gNMI subscription and wait for `SYNC`. + +### IPv6 Setup + +- Configure `POLICY-PREFIX-SET-B` which references `PREFIX-SET-B`. +- Set the global filter `ipv6-policy` to `POLICY-PREFIX-SET-B`. +- Ensure the DUT has static routes for `2001:DB8:2::/64` and + `2001:DB8:2::1/128`. +- Establish a gNMI subscription and wait for `SYNC`. + +## AFT-6.4.1 - Dynamic Prefix-Set Updates (IPv4) + +### 6.4.1.1 - Addition of Prefix to Active Set + +- Add a new prefix `192.0.2.0/24` to `PREFIX-SET-A` on the DUT. +- Ensure the DUT has a RIB/AFT entry for `192.0.2.0/24`. +- Verify receipt of a gNMI update notification for `192.0.2.0/24`. + +### 6.4.1.2 - Deletion of Prefix from Active Set + +- Remove prefix `198.51.100.0/24` from `PREFIX-SET-A` on the DUT. +- Verify receipt of a gNMI delete notification for `198.51.100.0/24`, even + though the route still exists in the DUT's RIB/AFT. + +### 6.4.1.3 - Simultaneous Addition and Deletion + +- Perform an atomic gNMI update to `PREFIX-SET-A`: + - Add `198.51.100.0/24` back to the set. + - Remove `203.0.113.0/28` from the set. +- Verify receipt of an update for `198.51.100.0/24` and a delete for + `203.0.113.0/28`. + +## AFT-6.4.2 - Dynamic Prefix-Set Updates (IPv6) + +### 6.4.2.1 - Addition of IPv6 Prefix to Active Set + +- Add a new prefix `2001:DB8:2::2/128` to `PREFIX-SET-B` on the DUT. +- Ensure the DUT has a RIB/AFT entry for `2001:DB8:2::2/128`. +- Verify receipt of a gNMI update notification for `2001:DB8:2::2/128`. + +### 6.4.2.2 - Deletion of IPv6 Prefix from Active Set + +- Remove prefix `2001:DB8:2::/64` from `PREFIX-SET-B` on the DUT. +- Verify receipt of a gNMI delete notification for `2001:DB8:2::/64`, even + though the route still exists in the DUT's RIB/AFT. + +### 6.4.2.3 - Simultaneous IPv6 Addition and Deletion + +- Perform an atomic gNMI update to `PREFIX-SET-B`: + - Add `2001:DB8:2::/64` back to the set. + - Remove `2001:DB8:2::1/128` from the set. +- Verify receipt of an update for `2001:DB8:2::/64` and a delete for + `2001:DB8:2::1/128`. + +## OpenConfig Path and RPC Coverage + +> **TODO:** The `global-filter` container and its `config/ipv4-policy`, +> `config/ipv6-policy`, `state/ipv4-policy` and `state/ipv6-policy` leaves are +> proposed extensions to the OpenConfig AFT model and are not yet present in the +> master branch of [openconfig/public](https://github.com/openconfig/public). +> This README may be merged before the TODO is resolved. +> +> The OpenConfig pull request is +> [#1441](https://github.com/openconfig/public/pull/1441). + +```yaml +paths: + # Proposed paths for the new filter mechanism (not yet in openconfig/public) + # /network-instances/network-instance/afts/global-filter/config/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/config/ipv6-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv6-policy: + + # Standard AFT state paths + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group: + /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/state/index: + /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address: + + # Paths for configuring prefix-sets + /routing-policy/defined-sets/prefix-sets/prefix-set/config/name: + /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/ip-prefix: + /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/masklength-range: + +rpcs: + gnmi: + gNMI.Subscribe: + STREAM: true + ON_CHANGE: true + gNMI.Set: + REPLACE: true + UPDATE: true + DELETE: true +``` + +## Canonical OC + +See [AFT-6.1](../afts_prefix_filtering/README.md#canonical-oc) for the full +canonical OpenConfig configuration. This test uses `PREFIX-SET-A`, +`PREFIX-SET-B`, and their associated policies as defined there. + +```json +{ + "routing-policy": { + "defined-sets": { + "prefix-sets": { + "prefix-set": [ + { + "name": "PREFIX-SET-A", + "config": { + "name": "PREFIX-SET-A" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "198.51.100.0/24", + "masklength-range": "exact", + "config": { + "ip-prefix": "198.51.100.0/24", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "203.0.113.0/28", + "masklength-range": "exact", + "config": { + "ip-prefix": "203.0.113.0/28", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "198.51.100.1/32", + "masklength-range": "exact", + "config": { + "ip-prefix": "198.51.100.1/32", + "masklength-range": "exact" + } + } + ] + } + }, + { + "name": "PREFIX-SET-B", + "config": { + "name": "PREFIX-SET-B" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "2001:DB8:2::/64", + "masklength-range": "exact", + "config": { + "ip-prefix": "2001:DB8:2::/64", + "masklength-range": "exact" + } + }, + { + "ip-prefix": "2001:DB8:2::1/128", + "masklength-range": "exact", + "config": { + "ip-prefix": "2001:DB8:2::1/128", + "masklength-range": "exact" + } + } + ] + } + } + ] + } + }, + "policy-definitions": { + "policy-definition": [ + { + "name": "POLICY-PREFIX-SET-A", + "config": { + "name": "POLICY-PREFIX-SET-A" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-A", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-PREFIX-SET-B", + "config": { + "name": "POLICY-PREFIX-SET-B" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-B", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + } + ] + } + } +} +``` + +## Required DUT platform + +FFF (Fixed Form Factor) or MFF (Modular Form Factor). diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dynamic/metadata.textproto b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dynamic/metadata.textproto new file mode 100644 index 00000000000..68f88e31a50 --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_dynamic/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "82a0e32f-4f79-43dc-a2f3-da48275c539e" +plan_id: "AFT-6.4" +description: "AFT Prefix Filtering Dynamic Updates" +testbed: TESTBED_DUT_ATE_2LINKS diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_resilience/README.md b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_resilience/README.md new file mode 100644 index 00000000000..2f161c09ca1 --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_resilience/README.md @@ -0,0 +1,313 @@ +# AFT-6.3: AFT Prefix Filtering Resilience + +## Summary + +This test validates AFT prefix filtering behavior under stress and recovery +conditions, including device reboot persistence, scale behavior with multiple +simultaneous subscriptions, and per-network-instance filter isolation with +multiple collectors. + +See [AFT-6.1](../afts_prefix_filtering/README.md) for common test setup and +policy definitions. + +## Testbed type + +[atedut_2.testbed](https://github.com/openconfig/featureprofiles/blob/main/topologies/atedut_2.testbed) + +## Test Setup + +Use the test environment and routing policies described in +[AFT-6.1](../afts_prefix_filtering/README.md#test-setup). + +## AFT-6.3.1 - Validation After Device Reboot + +### Establish Subscription + +- Configure `POLICY-PREFIX-SET-A` and set the global filter `ipv4-policy` and + `ipv6-policy` to it. + +- Establish a successful gNMI subscription and verify the initial filtered set + of AFT entries is received. + +### Reboot DUT + +- Issue a reboot command to the DUT via `gNOI.System/Reboot` while the + subscription is active. + +- Verify the gNMI stream terminates. + +### Await DUT Readiness + +- Wait for the DUT to become reachable and for gNMI to be available after + reboot. + +### Re-establish Subscription + +- Re-establish the same gNMI subscription. + +- Verify the subscription is successfully established. Only + endpoint-unreachable errors during the reboot window are acceptable; no + internal errors should be returned. + +- Verify that `global-filter/config/ipv4-policy` and + `global-filter/config/ipv6-policy` still hold `POLICY-PREFIX-SET-A`, + confirming the configuration persisted across reboot. + +- Verify that the DUT streams the correct filtered set of AFT entries matching + `POLICY-PREFIX-SET-A`. + +## AFT-6.3.2 - Scale Test + +- Let `X` be the number of IPv4 routes to advertise from the ATE. **(User + Adjustable Value, default: 5000)** + +- Let `Y` be the number of IPv6 routes to advertise from the ATE. **(User + Adjustable Value, default: 2000)** + +- Let `K` be the maximum allowed synchronization time in seconds. **(User + Adjustable Value, default: 120)** + +- Populate the AFT with `X` IPv4 routes and `Y` IPv6 routes by advertising + them from the connected ATE. + +- Configure three routing policies matching approximately 1%, 5%, and 20% of + the total route set for the address family under test, respectively. + +- Establish two simultaneous gNMI STREAM subscriptions (ON_CHANGE) to the AFT. + For each policy scenario and address family, wait until both subscriptions + receive `SYNC` and all expected leaves. + +- Measure the time taken for initial synchronization for each scenario. + +- Verify that in all cases, synchronization completes within `K` seconds. + +- Verify correct filtering is applied in all scenarios (only matching prefixes + for the active address family are streamed). + +## AFT-6.3.3 - Per Network-Instance Filtering with Multiple Collectors + +To validate that AFT filters are applied independently per network instance and +that multiple collectors can subscribe to different network instances with their +respective filters. + +### Setup + +- Configure two network instances on the DUT: `DEFAULT` and `VRF-A`. + +- Populate both instances with distinct static routes. The prefix + `198.51.100.0/24` appears in both instances to verify filter independence. + + - `DEFAULT`: `198.51.100.0/24`, `203.0.113.0/28`, `100.64.0.0/24` + - `VRF-A`: `198.51.100.0/24`, `100.64.1.0/24`, `203.0.113.128/28` + +- Configure the following routing policies: + + - `POLICY-PREFIX-SET-A`: Matches `198.51.100.0/24`, `203.0.113.0/28`, and + `198.51.100.1/32`. + - `POLICY-PREFIX-SET-VRF-A`: Matches `100.64.1.0/24` and subnets up to + `/32`. + - `POLICY-MATCH-ALL`: Matches all routes. + +- Configure AFT filters: + + - `DEFAULT`: + `/network-instances/network-instance[name=DEFAULT]/afts/global-filter/config/ipv4-policy` = + `POLICY-PREFIX-SET-A` + `/network-instances/network-instance[name=DEFAULT]/afts/global-filter/config/ipv6-policy` = + `POLICY-PREFIX-SET-A` + - `VRF-A`: + `/network-instances/network-instance[name=VRF-A]/afts/global-filter/config/ipv4-policy` = + `POLICY-PREFIX-SET-VRF-A` + `/network-instances/network-instance[name=VRF-A]/afts/global-filter/config/ipv6-policy` = + `POLICY-PREFIX-SET-VRF-A` + +### Validation + +- **Collector 1**: Establishes a gNMI subscription to AFT paths within the + `DEFAULT` network instance. + +- **Collector 2**: Establishes a gNMI subscription to AFT paths within the + `VRF-A` network instance. + +- Collector 1: Verify `SYNC` and receipt of only `198.51.100.0/24` and + `203.0.113.0/28` from `DEFAULT`, with associated next-hops/groups. Verify + `100.64.0.0/24` is **not** received. + +- Collector 2: Verify `SYNC` and receipt of only `100.64.1.0/24` from `VRF-A`, + with associated next-hops/groups. Verify `198.51.100.0/24` and + `203.0.113.128/28` are **not** received. + +- Add `100.64.2.0/24` to `DEFAULT`. Verify **neither** collector receives an + update. + +- Add `203.0.113.64/28` to `DEFAULT`. Verify **neither** collector receives an + update (not matched by either collector's active policy). + +- Add `198.51.100.1/32` (matched by `POLICY-PREFIX-SET-A` via exact match) to + `DEFAULT`. Verify **Collector 1** receives an update and **Collector 2** + does not. + +- Add `100.64.1.128/25` (matched by `POLICY-PREFIX-SET-VRF-A` via prefix + range) to `VRF-A`. Verify **Collector 2** receives an update and **Collector + 1** does not. + +- Change the filter for `VRF-A`: + `/network-instances/network-instance[name=VRF-A]/afts/global-filter/config/ipv4-policy` = + `POLICY-MATCH-ALL` + `/network-instances/network-instance[name=VRF-A]/afts/global-filter/config/ipv6-policy` = + `POLICY-MATCH-ALL`. + +- **Collector 1**: Verify its received AFT set for `DEFAULT` remains unchanged + and the connection remains stable throughout. + +- **Collector 2**: After the policy change to `POLICY-MATCH-ALL`, verify + within 60 seconds that Collector 2 receives update notifications for the + previously filtered-out prefixes (`198.51.100.0/24` and + `203.0.113.128/28`) that are now included under the new policy. If the DUT + terminates Collector 2's stream due to the policy change, re-establish the + subscription and verify the full set of `VRF-A` prefixes + (`198.51.100.0/24`, `100.64.1.0/24`, `203.0.113.128/28`, and the + dynamically added `100.64.1.128/25`) is received after `SYNC`. + +## OpenConfig Path and RPC Coverage + +> **TODO:** The `global-filter` container and its `config/ipv4-policy`, +> `config/ipv6-policy`, `state/ipv4-policy` and `state/ipv6-policy` leaves are +> proposed extensions to the OpenConfig AFT model and are not yet present in the +> master branch of [openconfig/public](https://github.com/openconfig/public). +> This README may be merged before the TODO is resolved. +> +> The OpenConfig pull request is +> [#1441](https://github.com/openconfig/public/pull/1441). + +```yaml +paths: + # Proposed paths for the new filter mechanism (not yet in openconfig/public) + # /network-instances/network-instance/afts/global-filter/config/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/config/ipv6-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv4-policy: + # /network-instances/network-instance/afts/global-filter/state/ipv6-policy: + + # Standard AFT state paths + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix: + /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/prefix: + /network-instances/network-instance/afts/ipv6-unicast/ipv6-entry/state/next-hop-group: + /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-hop-groups/next-hop-group/next-hops/next-hop/state/weight: + /network-instances/network-instance/afts/next-hops/next-hop/state/index: + /network-instances/network-instance/afts/next-hops/next-hop/state/ip-address: + /network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/interface: + + # Paths for configuring policies and prefix-sets (used in setup) + /routing-policy/defined-sets/prefix-sets/prefix-set/config/name: + /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/ip-prefix: + /routing-policy/defined-sets/prefix-sets/prefix-set/prefixes/prefix/config/masklength-range: + /routing-policy/policy-definitions/policy-definition/config/name: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/prefix-set: + /routing-policy/policy-definitions/policy-definition/statements/statement/conditions/match-prefix-set/config/match-set-options: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/config/policy-result: + /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/index: + /network-instances/network-instance/protocols/protocol/static-routes/static/next-hops/next-hop/config/next-hop: + +rpcs: + gnmi: + gNMI.Subscribe: + STREAM: true + ON_CHANGE: true + gNMI.Set: + REPLACE: true + UPDATE: true + DELETE: true + gnoi: + system.System.Reboot: true +``` + +## Canonical OC + +See [AFT-6.1](../afts_prefix_filtering/README.md#canonical-oc) for the full +canonical OpenConfig configuration. This test uses `POLICY-PREFIX-SET-A`, +`POLICY-PREFIX-SET-VRF-A`, and `POLICY-MATCH-ALL` as defined there. + +```json +{ + "routing-policy": { + "defined-sets": { + "prefix-sets": { + "prefix-set": [ + { + "name": "PREFIX-SET-VRF-A", + "config": { + "name": "PREFIX-SET-VRF-A" + }, + "prefixes": { + "prefix": [ + { + "ip-prefix": "100.64.1.0/24", + "masklength-range": "24..32", + "config": { + "ip-prefix": "100.64.1.0/24", + "masklength-range": "24..32" + } + } + ] + } + } + ] + } + }, + "policy-definitions": { + "policy-definition": [ + { + "name": "POLICY-MATCH-ALL", + "config": { + "name": "POLICY-MATCH-ALL" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + }, + { + "name": "POLICY-PREFIX-SET-VRF-A", + "config": { + "name": "POLICY-PREFIX-SET-VRF-A" + }, + "statements": { + "statement": [ + { + "name": "10", + "config": { "name": "10" }, + "conditions": { + "match-prefix-set": { + "config": { + "prefix-set": "PREFIX-SET-VRF-A", + "match-set-options": "ANY" + } + } + }, + "actions": { + "config": { "policy-result": "ACCEPT_ROUTE" } + } + } + ] + } + } + ] + } + } +} +``` + +## Required DUT platform + +FFF (Fixed Form Factor) or MFF (Modular Form Factor). diff --git a/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_resilience/metadata.textproto b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_resilience/metadata.textproto new file mode 100644 index 00000000000..2507221adaf --- /dev/null +++ b/feature/afts/filtered_streaming/otg_tests/afts_prefix_filtering_resilience/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "0475e688-c645-43ef-a50c-6ed1f3606ed8" +plan_id: "AFT-6.3" +description: "AFT Prefix Filtering Resilience" +testbed: TESTBED_DUT_ATE_2LINKS