diff --git a/doc/sai-ptf/img/Component_topology.jpg b/doc/sai-ptf/img/Component_topology.jpg new file mode 100644 index 000000000..a51295929 Binary files /dev/null and b/doc/sai-ptf/img/Component_topology.jpg differ diff --git a/doc/sai-ptf/img/Device_topology.jpg b/doc/sai-ptf/img/Device_topology.jpg new file mode 100644 index 000000000..77a1d7761 Binary files /dev/null and b/doc/sai-ptf/img/Device_topology.jpg differ diff --git a/doc/sai-ptf/img/SAI_PTF_Topology.jpg b/doc/sai-ptf/img/SAI_PTF_Topology.jpg new file mode 100644 index 000000000..19babb71d Binary files /dev/null and b/doc/sai-ptf/img/SAI_PTF_Topology.jpg differ diff --git a/doc/sai-ptf/lag_test_plan.md b/doc/sai-ptf/lag_test_plan.md new file mode 100644 index 000000000..007b84e0c --- /dev/null +++ b/doc/sai-ptf/lag_test_plan.md @@ -0,0 +1,140 @@ +# SAI Lag Test plan +- [SAI Lag Test plan](#sai-lag-test-plan) + - [Overriew](#overriew) + - [Test Topology](#test-topology) + - [Testbed](#testbed) + - [Scope](#scope) +- [Basic SAI APIs and sample packets](#basic-sai-apis-and-sample-packets) + - [APIs](#apis) + - [Packets](#packets) +- [Test suites](#test-suites) + - [Test suite #1: PortChannel Loadbalanceing](#test-suite-1-portchannel-loadbalanceing) + - [Test suite #2: Ingress/Egreee disable](#test-suite-2-ingressegreee-disable) +## Overriew +The purpose of this test plan is to test the LAG/PortChannel function from SAI. + +### Test Topology +For SAI-PTF, it will use a non-topology network structure for the sai testing. + +### Testbed +Those tests will be run on the testbed structure, the components are: +* PTF - running in a server that can connect to the target DUT +* SAI server - running on a dut + +*p.s. cause the SAI testing will not depend on any sonic components, then there will be no specific topology(T0 T1 T2) for testing.* + +## Scope +The test will include two parts +1. Lag functionalities + - Load balancing +2. Lag SAI APIs + - create/check/remove lag and lag member + + +# Basic SAI APIs and sample packets + +## APIs + +Create and lag member +```Python +sai_thrift_create_lag(self.client) +sai_thrift_create_lag_member( + self.client, lag_id=lag3, port_id=self.port24) +``` + +Get lag members +```Python +sai_thrift_get_lag_attribute( + self.client, lag3, port_list=portlist) +count = attr_list["SAI_LAG_ATTR_PORT_LIST"].count +``` + +Get port counter +```Python +counter_results = sai_thrift_get_port_stats(client, port) + +counter_results["SAI_PORT_STAT_IF_IN_DISCARDS"], +counter_results["SAI_PORT_STAT_IF_IN_DISCARDS"], +counter_results["SAI_PORT_STAT_IF_IN_UCAST_PKTS"], +counter_results["SAI_PORT_STAT_IF_OUT_UCAST_PKTS"])) +``` + +Add fdb entry +**P.s.For fordwarding packet with vlan tag, fdb entry should enable the bv_id** +```python +sai_thrift_fdb_entry_t(switch_id=self.switch_id, mac_address=mac1, bv_id=self.vlan_oid) +sai_thrift_create_fdb_entry( + self.client, + fdb_entry, + type=SAI_FDB_ENTRY_TYPE_STATIC, + bridge_port_id=port_bp, + packet_action=SAI_PACKET_ACTION_FORWARD) +``` + +Remove lag member +```Python +sai_thrift_remove_lag_member(self.client, self.lag1_member6) +``` + +## Packets +Vlan tagged packet +```Python +simple_udp_packet(eth_dst=dst_mac, + eth_src=src_mac, + dl_vlan_enable=True, + vlan_vid=vlan_id, + pktlen=104) +``` + +# Test suites +## Test suite #1: PortChannel Loadbalanceing +For load balancing, expecting the ports in a lag should receive the packet equally. + +Even after removing and disabling the port in a lag. + +Sample APIS +Disbale egress +```Python +sai_thrift_set_lag_member_attribute( + self.client, + self.lag1_member4, + ingress_disable=True, + egress_disable=True) +``` + +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create lag, add lag members, port1 - 4. Add FDB entry for lag, map with a MAC. | Create lag and member| lag, and member created| +| Send packet with.| Prepare to send from lag to VLAN.| Vlan and members have been created.| +| Send packet on port0 to the lag by specifying lag mac as dest mac. 4 times .| Packet forwards on port equally.| Loadbalance on lag members.| +| Every time, disable egress/ingress on one lag member, then send packet | Packet forwards on available ports equally.| Loadbalance on lag members.| +| Every time, enable egress/ingress on one lag member, then send packet | Packet forwards on available ports equally.| Loadbalance on lag members.| +| Every time, remove one lag member, then send packet | Packet forwards on available ports equally.| Loadbalance on lag members.| + +## Test suite #2: Ingress/Egreee disable +Sample APIs + +Ingress/Egreee disable +```python + status = sai_thrift_set_lag_member_attribute( + self.client, + self.lag1_member4, + ingress_disable=True, + egress_disable=True) + +``` + +lag port list +```Python +sai_thrift_get_lag_attribute( + self.client, self.lag1, port_list=portlist) +``` + +| Steps/Cases | Goal | Expect | +|-|-|-| +| Add FDB entry for port4 map to a MAC. Create lag and add port4 as a member. | Create lag and member| lag, and member created| +| Create VLAN and add VLAN member with port0 and port1.| Prepare to send from lag to VLAN.| Vlan and members have been created.| +| Send packet on port1 with target mac on port4. | Forwarding from port1 to port4.| Receive packet on port4.| +| Disable egress and ingress on lag member4. send packet | Packet dropped on port4| Packet drop.| +| Enable lag egress and ingress. Send packet with VLAN tag on lag port4 with a new dest mac.|Packet flooding on VLAN members, port0 and port1.|Packet received.| + diff --git a/doc/sai-ptf/vlan_test_plan.md b/doc/sai-ptf/vlan_test_plan.md new file mode 100644 index 000000000..d1174c761 --- /dev/null +++ b/doc/sai-ptf/vlan_test_plan.md @@ -0,0 +1,403 @@ +# SAI Vlan Test plan +- [SAI Vlan Test plan](#sai-vlan-test-plan) + - [Overriew](#overriew) + - [Test Topology](#test-topology) + - [Testbed](#testbed) + - [Scope](#scope) + - [Basic Test data and SAI APIs](#basic-test-data-and-sai-apis) + - [Create VLAN and VLAN member](#create-vlan-and-vlan-member) + - [Packet example](#packet-example) + - [Test Suites](#test-suites) + - [Test suite #1 : Test Flooding and learn](#test-suite-1--test-flooding-and-learn) + - [Testing Objective](#testing-objective) + - [Trunk VLAN](#trunk-vlan) + - [Access VLAN](#access-vlan) + - [Test suite #2: Test Frame Filtering](#test-suite-2-test-frame-filtering) + - [Testing Objective](#testing-objective-1) + - [Test suite #3: Test ARP Flooding and learn](#test-suite-3-test-arp-flooding-and-learn) + - [Testing Objective](#testing-objective-2) + - [Test sutie #4: Test tagging and trunk/access](#test-sutie-4-test-tagging-and-trunkaccess) + - [Testing Objective](#testing-objective-3) + - [Test sutie #5: Test native vlan](#test-sutie-5-test-native-vlan) + - [Testing Objective](#testing-objective-4) + - [Test sutie #6: VLAN interface (RIF/SVI)](#test-sutie-6-vlan-interface-rifsvi) + - [Testing Objective](#testing-objective-5) + - [SAI APIs operations](#sai-apis-operations) + - [Test suite #7: Test VLAN related counters.](#test-suite-7-test-vlan-related-counters) + - [Testing Objective](#testing-objective-6) + - [Test suite #8: Test VLAN related counters.](#test-suite-8-test-vlan-related-counters) + - [Testing Objective](#testing-objective-7) +## Overriew +The purpose of this test plan is to test the VLAN function from SAI. + +### Test Topology +For SAI-PTF, it will use a non-topology network structure for the sai testing. + +![Device_topology](img/SAI_PTF_Topology.jpg) +### Testbed +Those tests will be run on the testbed structure as below, the components are: +* PTF - running in a server that can connect to the target DUT +* SAI server - running on a dut + +![Device_topology](img/Device_topology.jpg) + +*p.s. cause the SAI testing will not depend on any sonic components, then there will be no specific topology(T0 T1 T2) for testing.* +## Scope +The test will include three parts +1. Vlan functionalities + - Flooding + - Forwarding + - Trunk/Access + - Tagging/Untagging(802.1Q) + - VLAN interface (RIF/SVI) +2. SAI APIs operations + - Vlan Counters + - Vlan and member list operations + +## Basic Test data and SAI APIs +During testing, we need to use SAI APIs for testing. By using SAI-PTF structure, we can invoke the SAI with RPC APIs remotely, the sample code is below. +### Create VLAN and VLAN member +- Create Vlan 10 + ```Python + sai_thrift_create_vlan(self.client, vlan_id=10) + ``` +- Create Native vlan + ```python + sai_thrift_set_port_attribute(self.client, port_id, port_vlan_id=10) + ``` +- Create Vlan member and VLAN member with different mode + Untag mode and access port + ```python + sai_thrift_create_vlan_member( + self.client, + vlan_id=10, + bridge_port_id=port_bridge_port, + vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) + ``` + Tag mode and trunk port + ```python + sai_thrift_create_vlan_member( + self.client, + vlan_id=10, + bridge_port_id=port_bridge_port, + vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_TAGGED) + ``` +- Add static FDB entry in the FDB table + + In the code below, we can create fdb entry, and bind the SMAC with a port with a static dfb entry. + ```python + sai_thrift_fdb_entry_t(switch_id=self.switch_id, mac_address=mac1, bv_id=self.vlan_oid) + sai_thrift_create_fdb_entry( + self.client, + fdb_entry, + type=SAI_FDB_ENTRY_TYPE_STATIC, + bridge_port_id=port_bp, + packet_action=SAI_PACKET_ACTION_FORWARD) + ``` +- Fdb operations + Get Fdb entries + ```python + sai_thrift_get_switch_attribute( + self.client, + available_fdb_entry=True) + ``` +- Clear fdb entries + Clear the learned fdb entries with the VLAN id object id + ```python + sai_thrift_flush_fdb_entries( + self.client, + bv_id=self.vlan_oid, + entry_type=SAI_FDB_ENTRY_TYPE_DYNAMIC) + ``` + +### Packet example +- Tagged packet with VLAN id + + When a packet sent to a access port or send out from a access port, we will get a packet with the VLAN id. + ```python + tagged_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:22:22:22:22:22', + vlan_vid=10, + ip_dst='172.16.0.1', + ip_ttl=64) + ``` +- ARP request + ```Python + simple_arp_packet( + eth_dst='FF:FF:FF:FF:FF:FF', # boardcast + eth_src='00:11:11:11:11:11', + arp_op=1, # ARP request + ip_tgt='10.10.10.2', + ip_snd='10.10.10.1', + hw_snd='00:11:11:11:11:11', + hw_tgt="00:00:00:00:00:00") + ``` +- ARP response + ```Python + simple_arp_packet( + eth_dst='00:11:11:11:11:11', + eth_src='00:22:22:22:22:22', + arp_op=2, # ARP response + ip_tgt='10.10.10.1', + ip_snd='10.10.10.2', + hw_snd='00:22:22:22:22:22', + hw_tgt="00:11:11:11:11:11") + ``` +- Untagged packet + ```Python + simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:22:22:22:22:22', + ip_dst='172.16.0.1', + ip_ttl=64) + ``` + +## Test Suites +*p.s. We can extend this test to each port with a loop, just take smaple amount of ports as example.* + + +### Test suite #1 : Test Flooding and learn + +#### Testing Objective +Those tests will verifies flooding and learning for vlan. + +VLANs divide broadcast domains in a LAN environment. When flooding on a trunk port with match vlan, the boadcast should only happened within vlan. + +After save the mac address to forwarding table, only unicast will happen with target mac. + +ARP request and response will also be covered in this set. + +##### Trunk VLAN +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create Vlan and add ports(port1, port2, port3) as VLAN members to the new created vlan. All VLAN members are set as ``Trunk`` | Create VLAN and its members| Vlan and members created| +| Send packet to VLAN port1 with ``tagged`` packet. Packet's src mac:mac1, target mac:mac2.| Flooding to VLAN port2 and port3. | flooding happen| +| Add a fdb entry which binding the mac2 and port2 together.|stimulate the mac learning.| fdb created.| +| Sent the packet again with packet's src mac:mac1, target mac:mac2, VLAN id, to port1.| Packet forwards to the target ``Trunk`` port with mac2.| Received ``tagged`` packet on port2.| +| Check the fdb entries | two new fdb entries added, with mac1 and mac2.| Learnt entries added.| +|Flush the fdb table for next port testing| FDB table cleared.|FDB entries added.| + +##### Access VLAN +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create Vlan and add ports(port1:``Trunk``, port2:``Access``, port3:``Trunk``) as VLAN members to the new created vlan.| Create VLAN and its members| Vlan and members created| +| Send packet to VLAN port1 with ``tagged`` packet. Packet's src mac:mac1, target mac:mac2.| Flooding to vlan, port2 with untagged packet and port3 with tagged packet. | multicast happen with differnt mode| +| Add a fdb entry which binding the mac2 and port2 together.|stimulate the mac learning.| fdb created.| +| Sent the packet again with packet's src mac:mac1, target mac:mac2, VLAN id, to port1.| Packet forwards to the target ``Access`` port with mac2.| Received ``untagged`` packet on port2.| +| Check the fdb entries | ``Two`` new fdb entries added, with mac1 and mac2.| FDB entries added.| + +### Test suite #2: Test Frame Filtering +#### Testing Objective +Switch will not forward packet when send packet to port, on which it have the same dest mac with the packet. + +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create VLAN, add port1, port2, port3 as VLAN members to new created vlan. All VLAN members are set as ``Trunk`` | Create VLAN and its members| Vlan and members created| +| Add a fdb entry which binding the mac2 and port2 together.|stimulate the mac learning.| fdb created.| +|Add a new fdb with mac3 one port1, send packet with mac3 as target mac to port1.| Filtering frame | Drop the packet.| + +### Test suite #3: Test ARP Flooding and learn + +#### Testing Objective +Test ARP Flooding and learn + +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create two VLANs, add port1 and port2 as to vlan1, port3, port4 to vlan2, all set as ports' native VLAN with tag mode(Testing purpose).| create VLAN and its members| Vlan and members created| +| Send ARP request packet to a port.| Flooding to all the other ports with mapped VLAN id. | flooding happen with vlan| +| Send a ``tagged`` ARP response packet with src:mac2, dest:mac1 to port2 and check the fdb entries.|Mac learnt.|Unicast happened.| +| Call API to check the FDB entries.|Check the mac entries in CAM.| fdb entry added.| + + +### Test sutie #4: Test tagging and trunk/access + +*p.s. Do not take native VLAN in this scarinro(Will be in other test suite). Please make sure the native VLAN will not impact the result.* +#### Testing Objective +With Tagged packet or untagged packet, on trunk and access port, when ingress and egress happen, the behivor as below +| Port mode | packet tag mode | Direction | Action | +| :---------|--------------- | :-------- | :--------------------------------------- | +| Access|Untag| Ingress | Accept the packet. | +| |Untag | Egress | Untag the packet. | +| |Tag| Ingress | Drop, if native id not match.| +| |Tag | Egress | Untag the packet. | +| Trunk |Untag| Ingress | Drop, if native VLAN id not match. | +| |Untag| Egress | Tag the packet. | +| |Tag| Ingress | Drop, if VLAN and native VLAN id not match. | +| |Tag| Egress | Tag the packet. | + + +Below is the test for checking this. + +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create VLAN 10, add port1 and port3 as ``trunk``, add port2, port4 as ``access``| create VLAN and its members| Vlan and members created| +| Add FDB entries, each port with its own mac.|Simulate the mac learning.| Set up forwarding table| +| Send ``tagged`` packet with dest mac3 on port1. | Forwarding from trunk to trunk port.| ``tagged`` packet received on port3.| +| Send ``untagged`` packet with dest mac4 on port2. | Forwarding from access to access port.| ``Untagged`` packet received on port4.| +| Send ``tagged`` packet with dest mac4 on port1. | Forwarding from trunk to access port.| ``Untagged`` packet received on port4.| +| Send ``Untagged`` packet with dest mac3 on port2. | Forwarding from access to Trunk port.| ``tagged`` packet received on port3.| +|Create VLAN 20, add port5 as ``trunk``, add FDB entry for this new port with mac5.|Vlan member with differnt VLAN id added.|Vlan member and fdb created.| +| Sent the ``Untagged`` packet from port1 with target mac5.|Forwarding on native vlan.|Packet received on port5 with VLAN 20.| +| Sent the ``Tagged`` packet for VLAN 10 from port1 with target mac5.|Forwarding on vlan.|Packet received on port5 with VLAN 20.| +| Sent the ``Untagged`` packet from port2 with target mac5.|Forwarding to trunk.|Packet received on port5 with VLAN 20.| + +### Test sutie #5: Test native vlan + +#### Testing Objective +For Native vlan, only consider the ingress direction, the entry condition for VLAN and the behivor as below +| Port mode | packet tag mode | Action | +| :---------|--------------- | :--------------------------------------- | +| Access|Tag| Drop, if native id not match. | +| Trunk |Untag| Drop, if native VLAN id not match.. | +| |Tag| Drop, if VLAN id not match and not meet native VLAN case. | + +Below is the test for checking this. +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create VLAN 10, add port1 and port3 as ``trunk``, add port2, port4 as ``access``. Set VLAN 10 as ports' native vlan| create native VLAN and its members| Vlan and members created| +| Add FDB entries for each port with its own mac.|Simulate the mac learning.| Set up forwarding table| +| Send ``tagged`` packet with dest mac3 on port1. | Forwarding from trunk to trunk port on native vlan.| ``tagged`` packet received on port3.| +| Send ``tagged`` packet with dest mac4 on port1. | Forwarding from trunk to access port.| ``Untagged`` packet received on port4.| +| Send ``Untagged`` packet with dest mac3 on port1. | Forwarding from trunk to Trunk port.| ``tagged`` packet received on port3.| +| Send ``Untagged`` packet with dest mac4 on port1. | Forwarding from trunk to access port.| ``Untagged`` packet received on port3.| +| Send ``tagged`` packet with a not-exiting dest mac on port1. | Dropping incorrect VLAN packet on ``trunk``.| Drop packet.| + +### Test sutie #6: VLAN interface (RIF/SVI) +#### Testing Objective +Test the configuration as below + +```xml + + + + + +``` +Convert to config_db.json +```json + "VLAN": { + "Vlan608": { + "members": [ + "Ethernet6/1", + "Ethernet7/1", + "Ethernet8/1", + ], + "vlanid": "608" + } + }, + "VLAN_INTERFACE": { + "Vlan608": {}, + "Vlan608|10.95.88.209/28": {}, + "Vlan608|2603:10a0:31c:8144::1/64": {} + }, + "VLAN_MEMBER": { + "Vlan608|Ethernet6/1": { + "tagging_mode": "untagged" + }, + "Vlan608|Ethernet7/1": { + "tagging_mode": "untagged" + }, + + "Vlan608|Ethernet8/1": { + "tagging_mode": "untagged" + }, + } +``` + +Need the APIs as below + +- Create Router Interface for a vlan interface + ```Python + sai_thrift_create_router_interface( + self.client, + type=SAI_ROUTER_INTERFACE_TYPE_VLAN, + virtual_router_id=self.default_vrf, + vlan_id=self.vlan10) + ``` +- Create next hop to a IP address '10.10.0.1' and mac + ```python + sai_thrift_create_next_hop( + self.client, + ip=sai_ipaddress('10.10.0.1'), + router_interface_id=self.vlan100_rif, + type=SAI_NEXT_HOP_TYPE_IP) + sai_thrift_create_neighbor_entry( + self.client, self.neighbor_entry1, dst_mac_address=self.dmac1) + sai_thrift_route_entry_t( + vr_id=self.default_vrf, destination=sai_ipprefix('10.10.10.1/32')) + ``` + +Below is the test for checking this. +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create VLAN 10, add port1 and port3 as ``trunk``, add port2, port4 as ``access``. Set VLAN 10 as ports' native vlan| create native VLAN and its members| Vlan and members created| +| Create route entry and next hop for vlan 10, with [IP1] and [mac5].| Create vlan interface. | Vlan interface created.| +| Add FDB entries for RIF. MAC is [mac5], and map it to Port5 in fdb entry. |Simulate the mac learning.| Set up forwarding table| +| Send ``tagged`` packet with dest mac3 on port1. | Forwarding from trunk to trunk port on native vlan.| ``tagged`` packet received on ``port5``.| +| Send ``tagged`` packet with dest mac4 on port1. | Forwarding from trunk to access port.| ``Untagged`` packet received on ``port5``.| +| Send ``Untagged`` packet with dest mac3 on port1. | Forwarding from trunk to Trunk port.| ``tagged`` packet received on ``port5``.| +| Send ``Untagged`` packet with dest mac4 on port1. | Forwarding from trunk to access port.| ``Untagged`` packet received on ``port5``.| +| Send ``tagged`` packet with a not-exiting dest mac on port1. | Dropping incorrect VLAN packet on ``trunk``.| Drop packet.| + +## SAI APIs operations + +### Test suite #7: Test VLAN related counters. +#### Testing Objective +For VLAN related counters, SAI should be able to get the counter and clear them. + +Below are the sample API to operate those data + +Check counters +```Python + stats = sai_thrift_get_vlan_stats(self.client, self.vlan10) + in_bytes = stats["SAI_VLAN_STAT_IN_OCTETS"] + out_bytes = stats["SAI_VLAN_STAT_OUT_OCTETS"] + in_packets = stats["SAI_VLAN_STAT_IN_PACKETS"] + in_ucast_packets = stats["SAI_VLAN_STAT_IN_UCAST_PKTS"] + out_packets = stats["SAI_VLAN_STAT_OUT_PACKETS"] + out_ucast_packets = stats["SAI_VLAN_STAT_OUT_UCAST_PKTS"] + +``` +Clear counters +```Python +sai_thrift_clear_vlan_stats(self.client, self.vlan10) +``` + +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create VLAN 10, add port1 and port3 as ``trunk``| create VLAN and its members| Vlan and members created| +| Add FDB entries, each port with its own mac.|Simulate the mac learning.| Set up forwarding table| +| Use the SAI API to check the counters | Related counter should be changed | Counter changed.| +| Use the SAI API to clear the counters.| Related counter is reset to zero. | Counter reset.| + + +### Test suite #8: Test VLAN related counters. +#### Testing Objective +Test Vlan and member list operations + +Sample APIs + +Get VLAN member list +```Python + vlan_member_list = sai_thrift_object_list_t(count=100) + mbr_list = sai_thrift_get_vlan_attribute( + self.client, self.vlan10, member_list=vlan_member_list) +``` + +nagtive test +```python + vlan_attr = sai_thrift_get_vlan_attribute( + self.client, vlan_oid=11, learn_disable=True) + + incorrect_member = sai_thrift_create_vlan_member( + self.client, + vlan_id=11, + bridge_port_id=self.port27_bp, + vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_TAGGED) +``` +| Steps/Cases | Goal | Expect | +|-|-|-| +| Create VLAN 10, add port1 and port3 as ``trunk``| create VLAN and its members| Vlan and members created| +| Use the SAI API to check VLAN member | VLAN member list and member count is right. | Vlan member list.| +| Remove the VLAN member from VLAN 10 and remove vlan. | VLAN and its member removed.| VLAN and its member removed.| +| Use the SAI API to check VLAN member | return 0. | Vlan member is 0.| +| Use the SAI API to create a VLAN member on VLAN 10 | return 0. | Vlan attribute is 0.|