From 1942363fa62b6a079ae5552d20c90eb55f0033d9 Mon Sep 17 00:00:00 2001 From: Zdeno Olsovsky Date: Thu, 28 Jul 2016 15:04:54 +0200 Subject: [PATCH] CSIT-237: VPN routed forwarding (VRF) - baseline for IPv6 Change-Id: I5c3053c692df29255a1da22a66f7ac282e3d5624 Signed-off-by: Zdeno Olsovsky --- resources/libraries/python/InterfaceUtil.py | 9 +- resources/libraries/python/Routing.py | 9 +- resources/templates/vat/add_route.vat | 2 +- resources/templates/vat/set_fib_to_interface.vat | 2 +- .../traffic_scripts/send_icmp_wait_for_reply.py | 94 ++++- tests/func/vrf/vrf_tests.robot | 2 +- tests/func/vrf/vrf_tests_v6.robot | 409 +++++++++++++++++++++ 7 files changed, 506 insertions(+), 21 deletions(-) create mode 100644 tests/func/vrf/vrf_tests_v6.robot diff --git a/resources/libraries/python/InterfaceUtil.py b/resources/libraries/python/InterfaceUtil.py index 9ecdb7503a..f5f1ce314e 100644 --- a/resources/libraries/python/InterfaceUtil.py +++ b/resources/libraries/python/InterfaceUtil.py @@ -847,25 +847,30 @@ class InterfaceUtil(object): interface_name=interface) @staticmethod - def assign_interface_to_fib_table(node, interface, table_id): + def assign_interface_to_fib_table(node, interface, table_id, ipv6=False): """Assign VPP interface to specific VRF/FIB table. :param node: VPP node where the FIB and interface are located. :param interface: Interface to be assigned to FIB. :param table_id: VRF table ID. + :param ipv6: Assign to IPv6 table. Default False. :type node: dict :type interface: str or int :type table_id: int + :type ipv6: bool """ if isinstance(interface, basestring): sw_if_index = Topology.get_interface_sw_index(node, interface) else: sw_if_index = interface + ipv6 = 'ipv6' if ipv6 else '' + with VatTerminal(node) as vat: vat.vat_terminal_exec_cmd_from_template("set_fib_to_interface.vat", sw_index=sw_if_index, - vrf=table_id) + vrf=table_id, + ipv6=ipv6) @staticmethod def set_linux_interface_mac(node, interface, mac, namespace=None): diff --git a/resources/libraries/python/Routing.py b/resources/libraries/python/Routing.py index 767fb3aff0..fbe7b60183 100644 --- a/resources/libraries/python/Routing.py +++ b/resources/libraries/python/Routing.py @@ -24,7 +24,7 @@ class Routing(object): @staticmethod def vpp_route_add(node, network, prefix_len, gateway=None, interface=None, use_sw_index=True, resolve_attempts=10, - count=1, vrf=None): + count=1, vrf=None, lookup_vrf=None): """Add route to the VPP node. :param node: Node to add route on. @@ -37,6 +37,7 @@ class Routing(object): :param resolve_attempts: Resolve attempts IP route add parameter. :param count: number of IP addresses to add starting from network IP with same prefix (increment is 1). If None, then is not used. + :param lookup_vrf: VRF table ID for lookup. :type node: dict :type network: str :type prefix_len: int @@ -46,6 +47,7 @@ class Routing(object): :type resolve_attempts: int :type count: int :type vrf: int + :type lookup_vrf: int """ if use_sw_index: int_cmd = ('sw_if_index {}'. @@ -63,6 +65,8 @@ class Routing(object): vrf = 'vrf {}'.format(vrf) if vrf else '' + lookup_vrf = 'lookup-in-vrf {}'.format(lookup_vrf) if lookup_vrf else '' + with VatTerminal(node, json_param=False) as vat: vat.vat_terminal_exec_cmd_from_template('add_route.vat', network=network, @@ -71,7 +75,8 @@ class Routing(object): vrf=vrf, interface=int_cmd, resolve_attempts=rap, - count=cnt) + count=cnt, + lookup_vrf=lookup_vrf) @staticmethod def add_fib_table(node, network, prefix_len, fib_id, place): diff --git a/resources/templates/vat/add_route.vat b/resources/templates/vat/add_route.vat index 6c7dfb09f0..9fe89526e6 100644 --- a/resources/templates/vat/add_route.vat +++ b/resources/templates/vat/add_route.vat @@ -1 +1 @@ -ip_add_del_route {network}/{prefix_length} {via} {vrf} {interface} {resolve_attempts} {count} +ip_add_del_route {network}/{prefix_length} {via} {vrf} {interface} {resolve_attempts} {count} {lookup_vrf} diff --git a/resources/templates/vat/set_fib_to_interface.vat b/resources/templates/vat/set_fib_to_interface.vat index f0850c900b..09a97faf17 100644 --- a/resources/templates/vat/set_fib_to_interface.vat +++ b/resources/templates/vat/set_fib_to_interface.vat @@ -1 +1 @@ -sw_interface_set_table sw_if_index {sw_index} vrf {vrf} \ No newline at end of file +sw_interface_set_table sw_if_index {sw_index} vrf {vrf} {ipv6} \ No newline at end of file diff --git a/resources/traffic_scripts/send_icmp_wait_for_reply.py b/resources/traffic_scripts/send_icmp_wait_for_reply.py index 3c8b71abc8..a77f15efc2 100755 --- a/resources/traffic_scripts/send_icmp_wait_for_reply.py +++ b/resources/traffic_scripts/send_icmp_wait_for_reply.py @@ -12,22 +12,33 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Traffic script that sends an IP ICMPv4.""" +"""Traffic script that sends an IP ICMPv4 or ICMPv6.""" import sys +import ipaddress from scapy.layers.inet import ICMP, IP +from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest from scapy.all import Ether from resources.libraries.python.PacketVerifier import RxQueue, TxQueue from resources.libraries.python.TrafficScriptArg import TrafficScriptArg -def is_icmp_reply(pkt): +def is_icmp_reply(pkt, ipformat): """Return True if pkt is echo reply, else return False. If exception occurs - return False.""" + return False. + + :param pkt: Packet. + :param ipformat: Dictionary of names to distinguish IPv4 and IPv6. + :type pkt: dict + :type ipformat: dict + :rtype: bool + """ + #pylint: disable=bare-except try: - if pkt['IP']['ICMP'].type == 0: # 0 - echo-reply + if pkt[ipformat['IPType']][ipformat['ICMP_rep']].type == \ + ipformat['Type']: return True else: return False @@ -35,16 +46,59 @@ def is_icmp_reply(pkt): return False -def address_check(request, reply): +def address_check(request, reply, ipformat): """Compare request packet source address with reply destination address - and vice versa. If exception occurs return False.""" + and vice versa. If exception occurs return False. + + :param request: Sent packet containing request. + :param reply: Received packet containing reply. + :param ipformat: Dictionary of names to distinguish IPv4 and IPv6. + :type request: dict + :type reply: dict + :type ipformat: dict + :rtype: bool + """ + #pylint: disable=bare-except try: - return reply['IP'].src == request['IP'].dst \ - and reply['IP'].dst == request['IP'].src + r_src = reply[ipformat['IPType']].src == request[ipformat['IPType']].dst + r_dst = reply[ipformat['IPType']].dst == request[ipformat['IPType']].src + return r_src and r_dst except: return False +def valid_ipv4(ip): + """Check if IP address has the correct IPv4 address format. + + :param ip: IP address. + :type ip: str + :return: True in case of correct IPv4 address format, + otherwise return False. + :rtype: bool + """ + try: + ipaddress.IPv4Address(unicode(ip)) + return True + except (AttributeError, ipaddress.AddressValueError): + return False + + +def valid_ipv6(ip): + """Check if IP address has the correct IPv6 address format. + + :param ip: IP address. + :type ip: str + :return: True in case of correct IPv6 address format, + otherwise return False. + :rtype: bool + """ + try: + ipaddress.IPv6Address(unicode(ip)) + return True + except (AttributeError, ipaddress.AddressValueError): + return False + + def main(): """Send ICMP echo request and wait for ICMP echo reply. It ignores all other packets.""" @@ -65,21 +119,33 @@ def main(): sent_packets = [] # Create empty ip ICMP packet - icmp_request = (Ether(src=src_mac, dst=dst_mac) / - IP(src=src_ip, dst=dst_ip) / - ICMP()) + if valid_ipv4(src_ip) and valid_ipv4(dst_ip): + icmp_request = (Ether(src=src_mac, dst=dst_mac) / + IP(src=src_ip, dst=dst_ip) / + ICMP()) + ip_format = {'IPType': 'IP', 'ICMP_req': 'ICMP', + 'ICMP_rep': 'ICMP', 'Type': 0} + elif valid_ipv6(src_ip) and valid_ipv6(dst_ip): + icmp_request = (Ether(src=src_mac, dst=dst_mac) / + IPv6(src=src_ip, dst=dst_ip) / + ICMPv6EchoRequest()) + ip_format = {'IPType': 'IPv6', 'ICMP_req': 'ICMPv6 Echo Request', + 'ICMP_rep': 'ICMPv6 Echo Reply', 'Type': 129} + else: + raise ValueError("IP not in correct format") + # Send created packet on the interface sent_packets.append(icmp_request) txq.send(icmp_request) for _ in range(1000): - icmp_reply = rxq.recv(wait_step) + icmp_reply = rxq.recv(wait_step, ignore=sent_packets) if icmp_reply is None: timeout -= wait_step if timeout < 0: raise RuntimeError("ICMP echo Rx timeout") - elif is_icmp_reply(icmp_reply): - if address_check(icmp_request, icmp_reply): + elif is_icmp_reply(icmp_reply, ip_format): + if address_check(icmp_request, icmp_reply, ip_format): break else: raise RuntimeError("Max packet count limit reached") diff --git a/tests/func/vrf/vrf_tests.robot b/tests/func/vrf/vrf_tests.robot index 239900c1eb..74696135b1 100644 --- a/tests/func/vrf/vrf_tests.robot +++ b/tests/func/vrf/vrf_tests.robot @@ -25,7 +25,7 @@ | Test Setup | Run Keywords | Setup all DUTs before test | ... | AND | Setup all TGs before traffic script | Test Teardown | Show Packet Trace on All DUTs | ${nodes} -| Documentation | *Vpn routed forwarding - baseline* +| Documentation | *Vpn routed forwarding - baseline IPv4* | ... | *[Top] Network Topologies:* TG=DUT1=DUT2=TG 3-node topology with two | ... | links in between nodes. | ... | *[Enc] Packet Encapsulations:* Eth-IPv4-ICMPv4 for L2 switching of diff --git a/tests/func/vrf/vrf_tests_v6.robot b/tests/func/vrf/vrf_tests_v6.robot new file mode 100644 index 0000000000..b5dd18d50d --- /dev/null +++ b/tests/func/vrf/vrf_tests_v6.robot @@ -0,0 +1,409 @@ +# Copyright (c) 2016 Cisco and/or its affiliates. +# 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. + +*** Settings *** +| Resource | resources/libraries/robot/default.robot +| Resource | resources/libraries/robot/ipv4.robot +| Resource | resources/libraries/robot/ipv6.robot +| Resource | resources/libraries/robot/interfaces.robot +| Resource | resources/libraries/robot/testing_path.robot +| Resource | resources/libraries/robot/traffic.robot +| Resource | resources/libraries/robot/l2_traffic.robot +| Library | resources.libraries.python.Trace +| Library | resources.libraries.python.IPUtil +| Force Tags | HW_ENV | VM_ENV | 3_NODE_DOUBLE_LINK_TOPO +| Test Setup | Run Keywords | Setup all DUTs before test +| ... | AND | Setup all TGs before traffic script +| Test Teardown | Run Keywords | Show Packet Trace on All DUTs | ${nodes} +| ... | AND | Show vpp trace dump on all DUTs +| Documentation | *Vpn routed forwarding - baseline IPv6* +| ... | *[Top] Network Topologies:* TG=DUT1=DUT2=TG 3-node topology with two +| ... | links in between nodes. +| ... | *[Enc] Packet Encapsulations:* Eth-IPv6-ICMPv6 +| ... | *[Cfg] DUT configuration:* Each DUT is configured with two VRF tables; +| ... | Separation of traffic is tested by IP packets; Neighbors and Routes are +| ... | set on DUT nodes; IP addresses are set on DUT interfaces. +| ... | *[Ver] TG verification:* Test ICMPv6 Echo Request packets +| ... | are sent by TG on link to DUT1, DUT2 or back to TG; On receipt TG +| ... | verifies packets for correctness and their IPv6 src-addr, dst-addr, +| ... | and MAC addresses. +| ... | *[Ref] Applicable standard specifications:* + +*** Variables *** +| ${fib_table_1}= | 9 +| ${fib_table_2}= | 99 + +| ${dut1_to_tg_ip1}= | 2001:62::3 +| ${dut1_to_tg_ip2}= | 2001:62::4 +| ${dut2_to_tg_ip1}= | 2003:62::3 +| ${dut2_to_tg_ip2}= | 2003:62::4 + +| ${dut1_to_dut2_ip1}= | 2002:62::1 +| ${dut1_to_dut2_ip2}= | 2002:62::2 +| ${dut2_to_dut1_ip1}= | 2002:62::3 +| ${dut2_to_dut1_ip2}= | 2002:62::4 + +| ${tg_dut1_ip1}= | 2001:62::1 +| ${tg_dut1_ip2}= | 2001:62::2 +| ${tg_dut2_ip1}= | 2003:62::1 +| ${tg_dut2_ip2}= | 2003:62::2 + +| ${ip_prefix}= | 64 +| ${timeout}= | 5 + +*** Test Cases *** +| TC01: TG packets routed to DUT ingress interface, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT1->TG-if1 and from +| | ... | TG->DUT1-if2 to DUT1->TG-if2 and checked if arrived. +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Node replies to ICMP echo request | ${tg_node} +| | ... | ${tg_to_dut1_if1} | ${dut1_to_tg_if1_mac} +| | ... | ${tg_to_dut1_if1_mac} | ${dut1_to_tg_ip1} +| | ... | ${tg_dut1_ip1} | ${timeout} +| | And Node replies to ICMP echo request | ${tg_node} +| | ... | ${tg_to_dut1_if2} | ${dut1_to_tg_if2_mac} +| | ... | ${tg_to_dut1_if2_mac} | ${dut1_to_tg_ip2} +| | ... | ${tg_dut1_ip2} | ${timeout} + +| TC02: TG packets routed to DUT egress interface, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT1->DUT2-if1 and from +| | ... | TG->DUT1-if2 to DUT1->DUT2-if2 and checked if arrived. +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Node replies to ICMP echo request | ${tg_node} | ${tg_to_dut1_if1} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut1_if1_mac} +| | ... | ${dut1_to_dut2_ip1} | ${tg_dut1_ip1} | ${timeout} +| | And Node replies to ICMP echo request | ${tg_node} | ${tg_to_dut1_if2} +| | ... | ${dut1_to_tg_if2_mac} | ${tg_to_dut1_if2_mac} +| | ... | ${dut1_to_dut2_ip2} | ${tg_dut1_ip2} | ${timeout} + +| TC03: TG packets routed to DUT2 ingress interface through DUT1, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT2->DUT1-if1 and from +| | ... | TG->DUT1-if2 to DUT2->DUT1-if2 and checked if arrived. +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Node replies to ICMP echo request | ${tg_node} | ${tg_to_dut1_if1} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut1_if1_mac} +| | ... | ${dut2_to_dut1_ip1} | ${tg_dut1_ip1} | ${timeout} +| | And Node replies to ICMP echo request | ${tg_node} | ${tg_to_dut1_if2} +| | ... | ${dut1_to_tg_if2_mac} | ${tg_to_dut1_if2_mac} +| | ... | ${dut2_to_dut1_ip2} | ${tg_dut1_ip2} | ${timeout} + +| TC04: TG packets routed to DUT2 egress interface through DUT1, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT2->TG-if1 and from +| | ... | TG->DUT1-if2 to DUT2->TG-if2 and checked if arrived. +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Node replies to ICMP echo request | ${tg_node} | ${tg_to_dut1_if1} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut1_if1_mac} +| | ... | ${dut2_to_tg_ip1} | ${tg_dut1_ip1} | ${timeout} +| | And Node replies to ICMP echo request | ${tg_node} | ${tg_to_dut1_if2} +| | ... | ${dut1_to_tg_if2_mac} | ${tg_to_dut1_if2_mac} +| | ... | ${dut2_to_tg_ip2} | ${tg_dut1_ip2} | ${timeout} + +| TC05: TG packets routed to TG through DUT1 and DUT2, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to TG->DUT2-if1 and from +| | ... | TG->DUT1-if2 to TG->DUT2-if2 and checked if arrived. +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Send Packet And Check Headers | ${tg_node} | ${tg_dut1_ip1} +| | ... | ${tg_dut2_ip1} | ${tg_to_dut1_if1} | ${tg_to_dut1_if1_mac} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut2_if1} | ${dut2_to_tg_if1_mac} +| | ... | ${tg_to_dut2_if1_mac} +| | And Send Packet And Check Headers | ${tg_node} +| | ... | ${tg_dut1_ip2} | ${tg_dut2_ip2} | ${tg_to_dut1_if2} +| | ... | ${tg_to_dut1_if2_mac} | ${dut1_to_tg_if2_mac} | ${tg_to_dut2_if2} +| | ... | ${dut2_to_tg_if2_mac} | ${tg_to_dut2_if2_mac} + +| TC06: TG packets not routed to DUT ingress interface in different VRF, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT1->TG-if2 where it +| | ... | should not arrive. +| | [Tags] | SKIP_PATCH +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if1} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut1_if1_mac} +| | ... | ${dut1_to_tg_ip2} | ${tg_dut1_ip1} | ${timeout} +| | And Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if2} +| | ... | ${dut1_to_tg_if2_mac} | ${tg_to_dut1_if2_mac} +| | ... | ${dut1_to_tg_ip1} | ${tg_dut1_ip2} | ${timeout} + +| TC07: TG packets not routed to DUT egress interface in different VRF, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT1->DUT2-if2 where it +| | ... | should not arrive. +| | [Tags] | SKIP_PATCH +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if1} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut1_if1_mac} +| | ... | ${dut1_to_dut2_ip2} | ${tg_dut1_ip1} | ${timeout} +| | And Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if2} +| | ... | ${dut1_to_tg_if2_mac} | ${tg_to_dut1_if2_mac} +| | ... | ${dut1_to_dut2_ip1} | ${tg_dut1_ip2} | ${timeout} + + +| TC08: TG packets not routed to DUT2 ingress interface in different VRF through DUT1, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT2->DUT1-if2 where it +| | ... | should not arrive. +| | [Tags] | SKIP_PATCH +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if1} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut1_if1_mac} +| | ... | ${dut2_to_dut1_ip2} | ${tg_dut1_ip1} | ${timeout} +| | And Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if2} +| | ... | ${dut1_to_tg_if2_mac} | ${tg_to_dut1_if2_mac} +| | ... | ${dut2_to_dut1_ip1} | ${tg_dut1_ip2} | ${timeout} + +| TC09: TG packets not routed to DUT2 egress interface in different VRF through DUT1, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to DUT2->TG-if2 where it +| | ... | should not arrive. +| | [Tags] | SKIP_PATCH +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if1} +| | ... | ${dut1_to_tg_if1_mac} | ${tg_to_dut1_if1_mac} +| | ... | ${dut2_to_tg_ip2} | ${tg_dut1_ip1} | ${timeout} +| | And Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Node replies to ICMP echo request +| | ... | ${tg_node} | ${tg_to_dut1_if2} +| | ... | ${dut1_to_tg_if2_mac} | ${tg_to_dut1_if2_mac} +| | ... | ${dut2_to_tg_ip1} | ${tg_dut1_ip2} | ${timeout} + +| TC10: TG packets not routed to TG in different VRF through DUT1 and DUT2, VPP configured with two VRFs +| | [Documentation] +| | ... | [Top] TG=DUT1=DUT2=TG. +| | ... | [Enc] Eth-IPv6-ICMPv6. +| | ... | [Cfg] DUT1 and DUT2 are both configured with two fib tables. Each +| | ... | table is assigned to 2 interfaces to separate the traffic. Interfaces +| | ... | are configured with IP addresses from *Variables*. Neighbors are +| | ... | configured for each DUTs ingress/egress ports, and each VRF is +| | ... | configured with just one route. +| | ... | [Ver] Packet is sent from TG->DUT1-if1 to TG->DUT2-if2 where it +| | ... | should not arrive. +| | [Tags] | SKIP_PATCH +| | Given Path for Double-Link 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} +| | ... | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in Double-Link 3-node path are UP +| | When Setup Env - 2xVRF Each Node +| | Then Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Send Packet And Check Headers | ${tg_node} | ${tg_dut1_ip1} +| | ... | ${tg_dut2_ip2} | ${tg_to_dut1_if1} +| | ... | ${tg_to_dut1_if1_mac} | ${dut1_to_tg_if1_mac} | ${tg_to_dut2_if2} +| | ... | ${dut2_to_tg_if2_mac} | ${tg_to_dut2_if2_mac} +| | And Run Keyword And Expect Error | ICMP echo Rx timeout +| | ... | Send Packet And Check Headers | ${tg_node} | ${tg_dut1_ip2} +| | ... | ${tg_dut2_ip1} | ${tg_to_dut1_if2} +| | ... | ${tg_to_dut1_if2_mac} | ${dut1_to_tg_if2_mac} | ${tg_to_dut2_if1} +| | ... | ${dut2_to_tg_if1_mac} | ${tg_to_dut2_if1_mac} + +*** Keywords *** +| Setup Env - 2xVRF Each Node +| | [Documentation] +| | ... | Environment is set up with 2 fib tables on each DUT. DUT1-TG-IF1 and \ +| | ... | DUT1-DUT2-IF1 are assigned to FIB1, and DUT1-TG-IF2 and DUT1-DUT2-IF2 +| | ... | are assigned to FIB2 (the same done on DUT2, just opposite). +| | ... | IP addresses and IP Neighbors are subsequently set for interfaces. +| | ... | The last setting is route for each fib table. +| | ... +| | ${dut1_if1_idx}= | Get Interface SW Index +| | ... | ${dut1_node} | ${dut1_to_dut2_if1} +| | ${dut1_if2_idx}= | Get Interface SW Index +| | ... | ${dut1_node} | ${dut1_to_dut2_if2} +| | ${dut2_if1_idx}= | Get Interface SW Index +| | ... | ${dut2_node} | ${dut2_to_dut1_if1} +| | ${dut2_if2_idx}= | Get Interface SW Index +| | ... | ${dut2_node} | ${dut2_to_dut1_if2} + +| | Assign Interface To Fib Table +| | ... | ${dut1_node} | ${dut1_to_dut2_if1} | ${fib_table_1} | ipv6=${TRUE} +| | Assign Interface To Fib Table +| | ... | ${dut1_node} | ${dut1_to_dut2_if2} | ${fib_table_2} | ipv6=${TRUE} +| | Assign Interface To Fib Table +| | ... | ${dut1_node} | ${dut1_to_tg_if1} | ${fib_table_1} | ipv6=${TRUE} +| | Assign Interface To Fib Table +| | ... | ${dut1_node} | ${dut1_to_tg_if2} | ${fib_table_2} | ipv6=${TRUE} + +| | Assign Interface To Fib Table +| | ... | ${dut2_node} | ${dut2_to_dut1_if1} | ${fib_table_1} | ipv6=${TRUE} +| | Assign Interface To Fib Table +| | ... | ${dut2_node} | ${dut2_to_dut1_if2} | ${fib_table_2} | ipv6=${TRUE} +| | Assign Interface To Fib Table +| | ... | ${dut2_node} | ${dut2_to_tg_if1} | ${fib_table_1} | ipv6=${TRUE} +| | Assign Interface To Fib Table +| | ... | ${dut2_node} | ${dut2_to_tg_if2} | ${fib_table_2} | ipv6=${TRUE} + +| | And Set Interface Address +| | ... | ${dut1_node} | ${dut1_to_tg_if1} | ${dut1_to_tg_ip1} | ${ip_prefix} +| | And Set Interface Address +| | ... | ${dut1_node} | ${dut1_to_tg_if2} | ${dut1_to_tg_ip2} | ${ip_prefix} +| | And Set Interface Address +| | ... | ${dut1_node} | ${dut1_to_dut2_if1} +| | ... | ${dut1_to_dut2_ip1} | ${ip_prefix} +| | And Set Interface Address +| | ... | ${dut1_node} | ${dut1_to_dut2_if2} +| | ... | ${dut1_to_dut2_ip2} | ${ip_prefix} + +| | And Set Interface Address +| | ... | ${dut2_node} | ${dut2_to_tg_if1} | ${dut2_to_tg_ip1} | ${ip_prefix} +| | And Set Interface Address +| | ... | ${dut2_node} | ${dut2_to_tg_if2} | ${dut2_to_tg_ip2} | ${ip_prefix} +| | And Set Interface Address +| | ... | ${dut2_node} | ${dut2_to_dut1_if1} +| | ... | ${dut2_to_dut1_ip1} | ${ip_prefix} +| | And Set Interface Address +| | ... | ${dut2_node} | ${dut2_to_dut1_if2} +| | ... | ${dut2_to_dut1_ip2} | ${ip_prefix} + +| | And Add IP Neighbor | ${dut1_node} | ${dut1_to_tg_if1} +| | ... | ${tg_dut1_ip1} | ${tg_to_dut1_if1_mac} | vrf=${fib_table_1} +| | And Add IP Neighbor | ${dut1_node} | ${dut1_to_dut2_if1} +| | ... | ${dut2_to_dut1_ip1} | ${dut2_to_dut1_if1_mac} | vrf=${fib_table_1} +| | And Add IP Neighbor | ${dut2_node} | ${dut2_to_tg_if1} +| | ... | ${tg_dut2_ip1} | ${tg_to_dut2_if1_mac} | vrf=${fib_table_1} +| | And Add IP Neighbor | ${dut2_node} | ${dut2_to_dut1_if1} +| | ... | ${dut1_to_dut2_ip1} | ${dut1_to_dut2_if1_mac} | vrf=${fib_table_1} + +| | And Add IP Neighbor | ${dut1_node} | ${dut1_to_tg_if2} +| | ... | ${tg_dut1_ip2} | ${tg_to_dut1_if2_mac} | vrf=${fib_table_2} +| | And Add IP Neighbor | ${dut1_node} | ${dut1_to_dut2_if2} +| | ... | ${dut2_to_dut1_ip2} | ${dut2_to_dut1_if2_mac} | vrf=${fib_table_2} +| | And Add IP Neighbor | ${dut2_node} | ${dut2_to_tg_if2} +| | ... | ${tg_dut2_ip2} | ${tg_to_dut2_if2_mac} | vrf=${fib_table_2} +| | And Add IP Neighbor | ${dut2_node} | ${dut2_to_dut1_if2} +| | ... | ${dut1_to_dut2_ip2} | ${dut1_to_dut2_if2_mac} | vrf=${fib_table_2} + +| | And Vpp Route Add | ${dut1_node} | ${tg_dut2_ip1} | ${ip_prefix} +| | ... | ${dut2_to_dut1_ip1} | ${dut1_to_dut2_if1} | vrf=${fib_table_1} +| | And Vpp Route Add | ${dut2_node} | ${tg_dut1_ip1} | ${ip_prefix} +| | ... | ${dut1_to_dut2_ip1} | ${dut2_to_dut1_if1} | vrf=${fib_table_1} + +| | And Vpp Route Add | ${dut1_node} | ${tg_dut2_ip2} | ${ip_prefix} +| | ... | ${dut2_to_dut1_ip2} | ${dut1_to_dut2_if2} | vrf=${fib_table_2} +| | And Vpp Route Add | ${dut2_node} | ${tg_dut1_ip2} | ${ip_prefix} +| | ... | ${dut1_to_dut2_ip2} | ${dut2_to_dut1_if2} | vrf=${fib_table_2} -- 2.16.6