From c3bf9f6ad20223998c1103ba3061a5e338979e2b Mon Sep 17 00:00:00 2001 From: Tibor Frank Date: Wed, 24 Aug 2016 16:09:20 +0200 Subject: [PATCH] CSIT-229: ip4-lispgpe-ip4 - main fib, - vrf, - phy2lisp Change-Id: Ic9bacef4574dc07b25041c4cd0653825a65c94fb Signed-off-by: Tibor Frank --- resources/libraries/python/IPUtil.py | 68 +++++++- resources/libraries/python/IPv4Util.py | 26 --- resources/libraries/python/InterfaceUtil.py | 22 +++ resources/libraries/python/L2Util.py | 29 ---- resources/libraries/python/LispSetup.py | 44 ++++- resources/libraries/python/LispUtil.py | 17 +- resources/libraries/robot/lisp/lisp_api.robot | 35 +++- resources/libraries/robot/lisp/lispgpe.robot | 118 ++++++++++++++ resources/templates/vat/lisp/lisp_gpe_status.vat | 1 + .../templates/vat/lisp/show_lisp_gpe_tunnel.vat | 1 + .../templates/vat/lisp/show_lisp_locator_set.vat | 2 +- .../lisp/ipv4_lispgpe_ipv4/ipv4_lispgpe_ipv4.py | 54 +++++++ tests/func/lisp/lisp_ipv4_lispgpe_ipv4.robot | 179 +++++++++++++++++++++ 13 files changed, 530 insertions(+), 66 deletions(-) create mode 100644 resources/libraries/robot/lisp/lispgpe.robot create mode 100644 resources/templates/vat/lisp/lisp_gpe_status.vat create mode 100644 resources/templates/vat/lisp/show_lisp_gpe_tunnel.vat create mode 100644 resources/test_data/lisp/ipv4_lispgpe_ipv4/ipv4_lispgpe_ipv4.py create mode 100644 tests/func/lisp/lisp_ipv4_lispgpe_ipv4.robot diff --git a/resources/libraries/python/IPUtil.py b/resources/libraries/python/IPUtil.py index 5011708c39..ed38272645 100644 --- a/resources/libraries/python/IPUtil.py +++ b/resources/libraries/python/IPUtil.py @@ -17,7 +17,7 @@ from ipaddress import IPv4Network, ip_address from resources.libraries.python.ssh import SSH from resources.libraries.python.constants import Constants - +from resources.libraries.python.ssh import exec_cmd_no_error, exec_cmd from resources.libraries.python.topology import Topology @@ -73,6 +73,72 @@ class IPUtil(object): raise AssertionError('IP addresses are not equal: {0} != {1}'. format(ip1, ip2)) + @staticmethod + def setup_network_namespace(node, namespace_name, interface_name, + ip_address, prefix): + """Setup namespace on given node and attach interface and IP to + this namespace. Applicable also on TG node. + + :param node: Node to set namespace on. + :param namespace_name: Namespace name. + :param interface_name: Interface name. + :param ip_address: IP address of namespace's interface. + :param prefix: IP address prefix length. + :type node: dict + :type namespace_name: str + :type vhost_if: str + :type ip_address: str + :type prefix: int + """ + cmd = ('ip netns add {0}'.format(namespace_name)) + exec_cmd_no_error(node, cmd, sudo=True) + + cmd = ('ip link set dev {0} up netns {1}'.format(interface_name, + namespace_name)) + exec_cmd_no_error(node, cmd, sudo=True) + + cmd = ('ip netns exec {0} ip addr add {1}/{2} dev {3}'.format( + namespace_name, ip_address, prefix, interface_name)) + exec_cmd_no_error(node, cmd, sudo=True) + + @staticmethod + def linux_enable_forwarding(node, ip_ver='ipv4'): + """Enable forwarding on a Linux node, e.g. VM. + + :param node: Node to enable forwarding on. + :param ip_ver: IP version, 'ipv4' or 'ipv6'. + :type node: dict + :type ip_ver: str + """ + cmd = 'sysctl -w net.{0}.ip_forward=1'.format(ip_ver) + exec_cmd_no_error(node, cmd, sudo=True) + + @staticmethod + def set_linux_interface_ip(node, interface, ip, prefix, namespace=None): + """Set IP address to interface in linux. + + :param node: Node where to execute command. + :param interface: Interface in namespace. + :param ip: IP to be set on interface. + :param prefix: IP prefix. + :param namespace: Execute command in namespace. Optional + :type node: dict + :type interface: str + :type ip: str + :type prefix: int + :type namespace: str + :raises RuntimeError: IP could not be set. + """ + if namespace is not None: + cmd = 'ip netns exec {} ip addr add {}/{} dev {}'.format( + namespace, ip, prefix, interface) + else: + cmd = 'ip addr add {}/{} dev {}'.format(ip, prefix, interface) + (rc, _, stderr) = exec_cmd(node, cmd, timeout=5, sudo=True) + if rc != 0: + raise RuntimeError( + 'Could not set IP for interface, reason:{}'.format(stderr)) + def convert_ipv4_netmask_prefix(network): """Convert network mask to equivalent network prefix length or vice versa. diff --git a/resources/libraries/python/IPv4Util.py b/resources/libraries/python/IPv4Util.py index 3043f230c2..ca5a1b571f 100644 --- a/resources/libraries/python/IPv4Util.py +++ b/resources/libraries/python/IPv4Util.py @@ -218,29 +218,3 @@ class IPv4Util(object): if rc != 0: raise RuntimeError("Arp set not successful, reason:{}". format(stderr)) - - @staticmethod - def set_linux_interface_ip(node, interface, ip, prefix, namespace=None): - """Set IP address to interface in linux. - - :param node: Node where to execute command. - :param interface: Interface in namespace. - :param ip: IP to be set on interface. - :param prefix: IP prefix. - :param namespace: Execute command in namespace. Optional - :type node: dict - :type interface: str - :type ip: str - :type prefix: int - :type namespace: str - :raises RuntimeError: IP could not be set. - """ - if namespace is not None: - cmd = 'ip netns exec {} ip addr add {}/{} dev {}'.format( - namespace, ip, prefix, interface) - else: - cmd = 'ip addr add {}/{} dev {}'.format(ip, prefix, interface) - (rc, _, stderr) = exec_cmd(node, cmd, timeout=5, sudo=True) - if rc != 0: - raise RuntimeError( - 'Could not set IP for interface, reason:{}'.format(stderr)) diff --git a/resources/libraries/python/InterfaceUtil.py b/resources/libraries/python/InterfaceUtil.py index f5f1ce314e..11600a1d47 100644 --- a/resources/libraries/python/InterfaceUtil.py +++ b/resources/libraries/python/InterfaceUtil.py @@ -212,6 +212,28 @@ class InterfaceUtil(object): return dict() return data + @staticmethod + def vpp_get_interface_mac(node, interface=None): + """Get MAC address for the given interface from actual interface dump. + + :param node: VPP node to get interface data from. + :param interface: Numeric index or name string of a specific interface. + :type node: dict + :type interface: int or str + :return: MAC address. + :rtype: str + """ + + if_data = InterfaceUtil.vpp_get_interface_data(node, interface) + mac_data = [str(hex(item))[2:] for item in if_data['l2_address'][:6]] + mac_data_nice = [] + for item in mac_data: + if len(item) == 1: + item = '0' + item + mac_data_nice.append(item) + mac = ":".join(mac_data_nice) + return mac + @staticmethod def vpp_get_interface_ip_addresses(node, interface, ip_version): """Get list of IP addresses from an interface on a VPP node. diff --git a/resources/libraries/python/L2Util.py b/resources/libraries/python/L2Util.py index 566b69bf1c..a909e8611b 100644 --- a/resources/libraries/python/L2Util.py +++ b/resources/libraries/python/L2Util.py @@ -217,35 +217,6 @@ class L2Util(object): cmd = 'ip link set dev {0} up'.format(br_name) exec_cmd_no_error(node, cmd, sudo=True) - @staticmethod - def setup_network_namespace(node, namespace_name, interface_name, - ip_address, prefix): - """Setup namespace on given node and attach interface and IP to - this namespace. Applicable also on TG node. - - :param node: Node to set namespace on. - :param namespace_name: Namespace name. - :param interface_name: Interface name. - :param ip_address: IP address of namespace's interface. - :param prefix: IP address prefix length. - :type node: dict - :type namespace_name: str - :type vhost_if: str - :type ip_address: str - :type prefix: int - - """ - cmd = ('ip netns add {0}'.format(namespace_name)) - exec_cmd_no_error(node, cmd, sudo=True) - - cmd = ('ip link set dev {0} up netns {1}'.format(interface_name, - namespace_name)) - exec_cmd_no_error(node, cmd, sudo=True) - - cmd = ('ip netns exec {0} ip addr add {1}/{2} dev {3}'.format( - namespace_name, ip_address, prefix, interface_name)) - exec_cmd_no_error(node, cmd, sudo=True) - @staticmethod def linux_del_bridge(node, br_name, set_down=True): """Delete bridge from linux node. diff --git a/resources/libraries/python/LispSetup.py b/resources/libraries/python/LispSetup.py index 531510198c..ee2ae5d8a3 100644 --- a/resources/libraries/python/LispSetup.py +++ b/resources/libraries/python/LispSetup.py @@ -164,6 +164,26 @@ class LispAdjacency(object): seid_prefix=seid_prefix) +class LispGpeStatus(object): + """Clas for LISP GPE status manipulation.""" + + def __init__(self): + pass + + @staticmethod + def vpp_lisp_gpe_enable_disable(node, state): + """Change the state of LISP GPE - enable or disable. + + :param node: VPP node. + :param state: Requested state - enable or disable. + :type node: dict + :type state: str + """ + + VatExecutor.cmd_from_template(node, 'lisp/lisp_gpe_status.vat', + state=state) + + class LispGpeIface(object): """Class for Lisp gpe interface API.""" @@ -180,11 +200,31 @@ class LispGpeIface(object): :type state: str """ - VatExecutor.cmd_from_template(node, - 'lisp/lisp_gpe_iface.vat', + VatExecutor.cmd_from_template(node, 'lisp/lisp_gpe_iface.vat', state=state) +class LispGpeForwardEntry(object): + """The functionality needed for these methods is not implemented in VPP + (VAT). Bug https://jira.fd.io/browse/VPP-334 was open to cover this issue. + + TODO: Implement when VPP-334 is fixed. + """ + + def __init__(self): + pass + + @staticmethod + def add_lisp_gpe_forward_entry(node, *args): + # TODO: Implement when VPP-334 is fixed. + pass + + @staticmethod + def del_lisp_gpe_forward_entry(node, *args): + # TODO: Implement when VPP-334 is fixed. + pass + + class LispMapResolver(object): """Class for Lisp map resolver API.""" diff --git a/resources/libraries/python/LispUtil.py b/resources/libraries/python/LispUtil.py index 8a83dc4d30..c50e626b80 100644 --- a/resources/libraries/python/LispUtil.py +++ b/resources/libraries/python/LispUtil.py @@ -15,7 +15,7 @@ from resources.libraries.python.parsers.JsonParser import JsonParser from resources.libraries.python.topology import Topology -from resources.libraries.python.VatExecutor import VatExecutor +from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal class LispUtil(object): @@ -40,18 +40,25 @@ class LispUtil(object): return JsonParser().parse_data(vat.get_script_stdout()) @staticmethod - def vpp_show_lisp_locator_set(node): + def vpp_show_lisp_locator_set(node, items_filter): """Get lisp locator_set from VPP node. :param node: VPP node. + :param items_filter: Filter which specifies which items should be + retrieved - local, remote, empty string = both. :type node: dict + :type items_filter: str :return: Lisp locator_set data as python list. :rtype: list """ - vat = VatExecutor() - vat.execute_script_json_out('lisp/show_lisp_locator_set.vat', node) - return JsonParser().parse_data(vat.get_script_stdout()) + try: + with VatTerminal(node) as vat: + response = vat.vat_terminal_exec_cmd_from_template( + 'lisp/show_lisp_locator_set.vat', filter=items_filter) + return response[0] + except ValueError: + return [] @staticmethod def vpp_show_lisp_eid_table(node): diff --git a/resources/libraries/robot/lisp/lisp_api.robot b/resources/libraries/robot/lisp/lisp_api.robot index 8094d08b84..4bd22bc036 100644 --- a/resources/libraries/robot/lisp/lisp_api.robot +++ b/resources/libraries/robot/lisp/lisp_api.robot @@ -16,6 +16,7 @@ | Library | resources.libraries.python.NodePath | Library | resources.libraries.python.LispSetup.LispStatus | Library | resources.libraries.python.LispSetup.LispSetup +| Library | resources.libraries.python.LispSetup.LispGpeStatus | Library | resources.libraries.python.LispUtil *** Keywords *** @@ -82,7 +83,7 @@ | | ... | \| Then Lisp locator_set is set correctly \| ${nodes['DUT1']} \| | | ... | | [Arguments] | ${dut_node} -| | ${show_locator_set}= | Vpp Show Lisp Locator Set | ${dut_node} +| | ${show_locator_set}= | Vpp Show Lisp Locator Set | ${dut_node} | local | | Lisp Locator S Should Be Equal | | ... | ${locator_set_values} | ${show_locator_set} @@ -120,7 +121,7 @@ | | ... | \| Then Lisp locator_set should be unset \| ${nodes['DUT1']} \| | | ... | | [Arguments] | ${dut_node} -| | ${show_locator_set}= | Vpp Show Lisp Locator Set | ${dut_node} +| | ${show_locator_set}= | Vpp Show Lisp Locator Set | ${dut_node} | ${EMPTY} | | Lisp Is Empty | ${show_locator_set} | Lisp locator_set data use for test reset locator_set are prepared @@ -359,3 +360,33 @@ | | [Arguments] | ${dut_node} | ${lisp_status_data} | | ${show_lisp_stat}= | Vpp Show Lisp State | ${dut_node} | | Lisp Should Be Equal | ${show_lisp_stat} | ${lisp_status_data[0]} + +| Enable Lisp Gpe +| | [Documentation] | Enable Lisp Gpe on VPP node. +| | ... +| | ... | *Arguments:* +| | ... | - dut_node - DUT node. Type: dictionary +| | ... +| | ... | *Return:* +| | ... | - No value returned +| | ... +| | ... | *Example:* +| | ... | \| Enable Lisp Gpe \| ${nodes['DUT1']} \| +| | ... +| | [Arguments] | ${dut_node} +| | Vpp Lisp Gpe Enable Disable | ${dut_node} | enable + +| Disable Lisp Gpe +| | [Documentation] | Disable Lisp Gpe on VPP node. +| | ... +| | ... | *Arguments:* +| | ... | - dut_node - DUT node. Type: dictionary +| | ... +| | ... | *Return:* +| | ... | - No value returned +| | ... +| | ... | *Example:* +| | ... | \| Disable Lisp Gpe \| ${nodes['DUT1']} \| +| | ... +| | [Arguments] | ${dut_node} +| | Vpp Lisp Gpe Enable Disable | ${dut_node} | disable diff --git a/resources/libraries/robot/lisp/lispgpe.robot b/resources/libraries/robot/lisp/lispgpe.robot new file mode 100644 index 0000000000..a5ab102652 --- /dev/null +++ b/resources/libraries/robot/lisp/lispgpe.robot @@ -0,0 +1,118 @@ +# 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 *** +| Documentation | LISP-gpe encapsulation suite keywords +| Library | resources.libraries.python.topology.Topology +| Resource | resources/libraries/robot/lisp/lisp_api.robot +| Library | resources.libraries.python.LispSetup.LispLocatorSet +| Library | resources.libraries.python.LispSetup.LispLocator +| Library | resources.libraries.python.LispSetup.LispLocalEid +| Library | resources.libraries.python.LispSetup.LispAdjacency +| Library | resources.libraries.python.LispSetup.LispRemoteMapping + +*** Keywords *** +| Set up LISP GPE topology +| | [Documentation] | Set up LISP GPE topology. +| | ... +| | ... | *Arguments:* +| | ... | - dut1_node - DUT1 node. Type: dictionary +| | ... | - dut1_if - DUT1 node interface. Type: string +| | ... | - dut1_int_index - DUT1 node interface index. Type: integer +| | ... | - dut2_node - DUT2 node. Type: dictionary +| | ... | - dut2_if - DUT2 node interface. Type: string +| | ... | - dut2_int_index - DUT2 node interface index. Type: integer +| | ... | - locator_set - Locator set values. Type: dictionary +| | ... | - dut1_eid - DUT1 node eid address. Type: dictionary +| | ... | - dut2_eid - DUT2 node eid address. Type: dictionary +| | ... | - dut1_static_adjacency - DUT1 static adjacency. Type: dictionary +| | ... | - dut2_static_adjacency - DUT2 static adjacency. Type: dictionary +| | ... +| | ... | *Return:* +| | ... | - No value returned +| | ... +| | ... | *Example:* +| | ... | \| Set up LISP GPE topology \| ${dut1_node} \| ${interface_name} \ +| | ... | \| None \| ${dut2_node} \| ${interface_name} \| None \ +| | ... | \| ${locator_set} \| ${dut1_eid} \| ${dut2_eid} \ +| | ... | \| ${dut1_static_adjacency} \| ${dut2_static_adjacency} \| +| | ... +| | [Arguments] +| | ... | ${dut1_node} | ${dut1_if} | ${dut1_int_index} +| | ... | ${dut2_node} | ${dut2_if} | ${dut2_int_index} +| | ... | ${locator_set} | ${dut1_eid} | ${dut2_eid} +| | ... | ${dut1_static_adjacency} | ${dut2_static_adjacency} +| | ... +# DUT1 settings: +| | ${dut1_int_index}= | Run Keyword If | ${dut1_int_index} is None +| | | ... | Get Interface Sw Index | ${dut1_node} | ${dut1_if} +| | | ... | ELSE | Set Variable | ${dut1_int_index} +| | Enable Lisp | ${dut1_node} +| | Enable Lisp GPE | ${dut1_node} +| | Vpp Add Lisp Locator Set | ${dut1_node} +| | ... | ${locator_set['locator_name']} +| | Vpp Add Lisp Locator | ${dut1_node} +| | ... | ${locator_set['locator_name']} +| | ... | ${dut1_int_index} +| | ... | ${locator_set['priority']} +| | ... | ${locator_set['weight']} +| | Vpp Add Lisp Local Eid | ${dut1_node} +| | ... | ${dut1_eid['locator_name']} +| | ... | ${dut1_eid['vni']} +| | ... | ${dut1_eid['eid']} +| | ... | ${dut1_eid['prefix']} +| | Vpp Add Lisp Remote Mapping | ${dut1_node} +| | ... | ${dut1_static_adjacency['vni']} +| | ... | ${dut1_static_adjacency['deid']} +| | ... | ${dut1_static_adjacency['prefix']} +| | ... | ${dut1_static_adjacency['seid']} +| | ... | ${dut1_static_adjacency['prefix']} +| | ... | ${dut1_static_adjacency['rloc']} +| | Vpp Add Lisp Adjacency | ${dut1_node} +| | ... | ${dut1_static_adjacency['vni']} +| | ... | ${dut1_static_adjacency['deid']} +| | ... | ${dut1_static_adjacency['prefix']} +| | ... | ${dut1_static_adjacency['seid']} +| | ... | ${dut1_static_adjacency['prefix']} +| | ... +# DUT2 settings: +| | ${dut2_int_index}= | Run Keyword If | ${dut2_int_index} is None +| | | ... | Get Interface Sw Index | ${dut2_node} | ${dut2_if} +| | | ... | ELSE | Set Variable | ${dut2_int_index} +| | Enable Lisp | ${dut2_node} +| | Enable Lisp GPE | ${dut2_node} +| | Vpp Add Lisp Locator Set | ${dut2_node} +| | ... | ${locator_set['locator_name']} +| | Vpp Add Lisp Locator | ${dut2_node} +| | ... | ${locator_set['locator_name']} +| | ... | ${dut2_int_index} +| | ... | ${locator_set['priority']} +| | ... | ${locator_set['weight']} +| | Vpp Add Lisp Local Eid | ${dut2_node} +| | ... | ${dut2_eid['locator_name']} +| | ... | ${dut2_eid['vni']} +| | ... | ${dut2_eid['eid']} +| | ... | ${dut2_eid['prefix']} +| | Vpp Add Lisp Remote Mapping | ${dut2_node} +| | ... | ${dut2_static_adjacency['vni']} +| | ... | ${dut2_static_adjacency['deid']} +| | ... | ${dut2_static_adjacency['prefix']} +| | ... | ${dut2_static_adjacency['seid']} +| | ... | ${dut2_static_adjacency['prefix']} +| | ... | ${dut2_static_adjacency['rloc']} +| | Vpp Add Lisp Adjacency | ${dut2_node} +| | ... | ${dut2_static_adjacency['vni']} +| | ... | ${dut2_static_adjacency['deid']} +| | ... | ${dut2_static_adjacency['prefix']} +| | ... | ${dut2_static_adjacency['seid']} +| | ... | ${dut2_static_adjacency['prefix']} diff --git a/resources/templates/vat/lisp/lisp_gpe_status.vat b/resources/templates/vat/lisp/lisp_gpe_status.vat new file mode 100644 index 0000000000..5c4080afc5 --- /dev/null +++ b/resources/templates/vat/lisp/lisp_gpe_status.vat @@ -0,0 +1 @@ +lisp_gpe_enable_disable {state} diff --git a/resources/templates/vat/lisp/show_lisp_gpe_tunnel.vat b/resources/templates/vat/lisp/show_lisp_gpe_tunnel.vat new file mode 100644 index 0000000000..802cfbb6a0 --- /dev/null +++ b/resources/templates/vat/lisp/show_lisp_gpe_tunnel.vat @@ -0,0 +1 @@ +# TODO: Implement when VPP-334 is fixed. \ No newline at end of file diff --git a/resources/templates/vat/lisp/show_lisp_locator_set.vat b/resources/templates/vat/lisp/show_lisp_locator_set.vat index 43768ec421..4f775ff47a 100644 --- a/resources/templates/vat/lisp/show_lisp_locator_set.vat +++ b/resources/templates/vat/lisp/show_lisp_locator_set.vat @@ -1 +1 @@ -lisp_locator_set_dump \ No newline at end of file +lisp_locator_set_dump {filter} \ No newline at end of file diff --git a/resources/test_data/lisp/ipv4_lispgpe_ipv4/ipv4_lispgpe_ipv4.py b/resources/test_data/lisp/ipv4_lispgpe_ipv4/ipv4_lispgpe_ipv4.py new file mode 100644 index 0000000000..cd1b6383e6 --- /dev/null +++ b/resources/test_data/lisp/ipv4_lispgpe_ipv4/ipv4_lispgpe_ipv4.py @@ -0,0 +1,54 @@ +# 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. + +"""Test variables for ip4-lispgpe-ip4 encapsulation test suite.""" + +# Lisp default global value +locator_name = 'tst_locator' + +# Lisp default locator_set value +duts_locator_set = {'locator_name': locator_name, + 'priority': 1, + 'weight': 1} + +# IPv4 Lisp static mapping configuration +dut1_to_dut2_ip4 = '6.0.3.1' +dut2_to_dut1_ip4 = '6.0.3.2' +dut1_to_tg_ip4 = '6.0.1.1' +dut2_to_tg_ip4 = '6.0.2.1' +tg1_ip4 = '6.0.1.2' +tg2_ip4 = '6.0.2.2' +prefix4 = 24 + +dut1_to_dut2_ip4_static_adjacency = {'vni': 0, + 'deid': '6.0.2.0', + 'seid': '6.0.1.0', + 'rloc': '6.0.3.2', + 'prefix': 24} +dut2_to_dut1_ip4_static_adjacency = {'vni': 0, + 'deid': '6.0.1.0', + 'seid': '6.0.2.0', + 'rloc': '6.0.3.1', + 'prefix': 24} + +dut1_ip4_eid = {'locator_name': locator_name, + 'vni': 0, + 'eid': '6.0.1.0', + 'prefix': 24} +dut2_ip4_eid = {'locator_name': locator_name, + 'vni': 0, + 'eid': '6.0.2.0', + 'prefix': 24} + +dut1_fib_table = '1' +dut2_fib_table = '2' diff --git a/tests/func/lisp/lisp_ipv4_lispgpe_ipv4.robot b/tests/func/lisp/lisp_ipv4_lispgpe_ipv4.robot new file mode 100644 index 0000000000..8a18962e35 --- /dev/null +++ b/tests/func/lisp/lisp_ipv4_lispgpe_ipv4.robot @@ -0,0 +1,179 @@ +# 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 *** +| Library | resources.libraries.python.topology.Topology +| Library | resources.libraries.python.NodePath +| Library | resources.libraries.python.Trace +| Library | resources.libraries.python.IPUtil +| Library | resources.libraries.python.LispUtil +| Resource | resources/libraries/robot/traffic.robot +| Resource | resources/libraries/robot/default.robot +| Resource | resources/libraries/robot/interfaces.robot +| Resource | resources/libraries/robot/testing_path.robot +| Resource | resources/libraries/robot/ipv4.robot +| Resource | resources/libraries/robot/lisp/lispgpe.robot +# Import configuration and test data: +| Variables | resources/test_data/lisp/ipv4_lispgpe_ipv4/ipv4_lispgpe_ipv4.py +| ... +| Force Tags | 3_NODE_SINGLE_LINK_TOPO | VM_ENV | EXPECTED_FAILING +| ... +| Test Setup | Run Keywords | Setup all DUTs before test +| ... | AND | Setup all TGs before traffic script +| ... | AND | Update All Interface Data On All Nodes | ${nodes} +| Test Teardown | Run Keywords | Show Packet Trace on All DUTs | ${nodes} +| ... | AND | Show vpp trace dump on all DUTs +| ... | AND | VPP Show Errors | ${nodes['DUT1']} +| ... | AND | VPP Show Errors | ${nodes['DUT2']} +| ... +| Documentation | *ip4-lispgpe-ip4 encapsulation test cases* +| ... +| ... | *[Top] Network Topologies:* TG-DUT1-DUT2-TG 3-node circular topology +| ... | with single links between nodes. +| ... | *[Enc] Packet Encapsulations:* Eth-IPv4-LISP-IPv4-ICMPv4 on DUT1-DUT2, +| ... | Eth-IPv4-ICMPv4 on TG-DUTn for IPv4 routing over LISPoIPv4 tunnel. +| ... | *[Cfg] DUT configuration:* DUT1 and DUT2 are configured with IPv4 +| ... | routing and static routes. LISPoIPv4 tunnel is configured between +| ... | DUT1 and DUT2. +| ... | *[Ver] TG verification:* Test ICMPv4 Echo Request packets are sent in +| ... | both directions by TG on links to DUT1 and DUT2; on receive +| ... | TG verifies packets for correctness and their IPv4 src-addr, dst-addr +| ... | and MAC addresses. +| ... | *[Ref] Applicable standard specifications:* RFC6830. + +*** Test Cases *** +| TC01: DUT1 and DUT2 route IPv4 bidirectionally over LISP GPE tunnel using physical interfaces +| | [Documentation] +| | ... | Case: ip4-lispgpe-ip4 - phy2lisp \ +| | ... | [Top] TG-DUT1-DUT2-TG. +| | ... | [Enc] Eth-IPv4-LISPGPE-IPv4-ICMPv4 on DUT1-DUT2, Eth-IPv4-ICMPv4 on +| | ... | TG-DUTn. +| | ... | [Cfg] Configure IPv4 LISP static adjacencies on DUT1 and DUT2. +| | ... | [Ver] Make TG send ICMPv4 Echo Req between its interfaces across both +| | ... | DUTs and LISP GPE tunnel between them; verify IPv4 headers on received +| | ... | packets are correct. +| | ... | [Ref] RFC6830. +| | ... +| | Given Path for 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in 3-node path are up +| | And IP addresses are set on interfaces +| | ... | ${dut1_node} | ${dut1_to_dut2} | ${dut1_to_dut2_ip4} | ${prefix4} +| | ... | ${dut1_node} | ${dut1_to_tg} | ${dut1_to_tg_ip4} | ${prefix4} +| | ... | ${dut2_node} | ${dut2_to_dut1} | ${dut2_to_dut1_ip4} | ${prefix4} +| | ... | ${dut2_node} | ${dut2_to_tg} | ${dut2_to_tg_ip4} | ${prefix4} +| | And VPP IP Probe | ${dut1_node} | ${dut1_to_dut2} | ${dut2_to_dut1_ip4} +| | And VPP IP Probe | ${dut2_node} | ${dut2_to_dut1} | ${dut1_to_dut2_ip4} +| | And Add Arp On Dut | ${dut2_node} | ${dut2_to_tg} | ${tg2_ip4} +| | ... | ${tg_to_dut2_mac} +| | And Add Arp On Dut | ${dut1_node} | ${dut1_to_tg} | ${tg1_ip4} +| | ... | ${tg_to_dut1_mac} +| | When Set up LISP GPE topology +| | ... | ${dut1_node} | ${dut1_to_dut2} | ${NONE} +| | ... | ${dut2_node} | ${dut2_to_dut1} | ${NONE} +| | ... | ${duts_locator_set} | ${dut1_ip4_eid} | ${dut2_ip4_eid} +| | ... | ${dut1_to_dut2_ip4_static_adjacency} +| | ... | ${dut2_to_dut1_ip4_static_adjacency} +| | Then Send Packet And Check Headers +| | ... | ${tg_node} | ${tg1_ip4} | ${tg2_ip4} +| | ... | ${tg_to_dut1} | ${tg_to_dut1_mac} | ${dut1_to_tg_mac} +| | ... | ${tg_to_dut2} | ${dut2_to_tg_mac} | ${tg_to_dut2_mac} +| | And Send Packet And Check Headers +| | ... | ${tg_node} | ${tg2_ip4} | ${tg1_ip4} +| | ... | ${tg_to_dut2} | ${tg_to_dut2_mac} | ${dut2_to_tg_mac} +| | ... | ${tg_to_dut1} | ${dut1_to_tg_mac} | ${tg_to_dut1_mac} + +| TC02: DUT1 and DUT2 route IPv4 bidirectionally over LISP GPE tunnel using physical interfaces and VRF is enabled +| | [Documentation] +| | ... | Case: ip4-lispgpe-ip4 - vrf, phy2lisp \ +| | ... | [Top] TG-DUT1-DUT2-TG. +| | ... | [Enc] Eth-IPv4-LISPGPE-IPv4-ICMPv4 on DUT1-DUT2, Eth-IPv4-ICMPv4 on +| | ... | TG-DUTn. +| | ... | [Cfg] Configure IPv4 LISP static adjacencies on DUT1 and DUT2. +| | ... | [Ver] Make TG send ICMPv4 Echo Req between its interfaces across both +| | ... | DUTs and LISP GPE tunnel between them; verify IPv4 headers on received +| | ... | packets are correct. +| | ... | [Ref] RFC6830. +| | ... +| | Given Path for 3-node testing is set +| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['DUT2']} | ${nodes['TG']} +| | And Interfaces in 3-node path are up +| | When Setup VRF on DUT | ${dut1_node} | ${dut1_fib_table} | ${dut1_to_dut2} +| | ... | ${dut2_to_dut1_ip4} | ${dut2_to_dut1_mac} | ${tg2_ip4} | ${dut1_to_tg} +| | ... | ${tg1_ip4} | ${tg_to_dut1_mac} | ${prefix4} +| | And Setup VRF on DUT | ${dut2_node} | ${dut2_fib_table} | ${dut2_to_dut1} +| | ... | ${dut1_to_dut2_ip4} | ${dut1_to_dut2_mac} | ${tg1_ip4} | ${dut2_to_tg} +| | ... | ${tg2_ip4} | ${tg_to_dut2_mac} | ${prefix4} +| | And IP addresses are set on interfaces +| | ... | ${dut1_node} | ${dut1_to_dut2} | ${dut1_to_dut2_ip4} | ${prefix4} +| | ... | ${dut1_node} | ${dut1_to_tg} | ${dut1_to_tg_ip4} | ${prefix4} +| | ... | ${dut2_node} | ${dut2_to_dut1} | ${dut2_to_dut1_ip4} | ${prefix4} +| | ... | ${dut2_node} | ${dut2_to_tg} | ${dut2_to_tg_ip4} | ${prefix4} +| | And Set up LISP GPE topology +| | ... | ${dut1_node} | ${dut1_to_dut2} | ${NONE} +| | ... | ${dut2_node} | ${dut2_to_dut1} | ${NONE} +| | ... | ${duts_locator_set} | ${dut1_ip4_eid} | ${dut2_ip4_eid} +| | ... | ${dut1_to_dut2_ip4_static_adjacency} +| | ... | ${dut2_to_dut1_ip4_static_adjacency} +| | Then Send Packet And Check Headers +| | ... | ${tg_node} | ${tg1_ip4} | ${tg2_ip4} +| | ... | ${tg_to_dut1} | ${tg_to_dut1_mac} | ${dut1_to_tg_mac} +| | ... | ${tg_to_dut2} | ${dut2_to_tg_mac} | ${tg_to_dut2_mac} +| | And Send Packet And Check Headers +| | ... | ${tg_node} | ${tg2_ip4} | ${tg1_ip4} +| | ... | ${tg_to_dut2} | ${tg_to_dut2_mac} | ${dut2_to_tg_mac} +| | ... | ${tg_to_dut1} | ${dut1_to_tg_mac} | ${tg_to_dut1_mac} + +*** Keywords *** +| Setup VRF on DUT +| | [Documentation] +| | ... | The keyword sets a FIB table on a DUT, assigns two interfaces to it,\ +| | ... | adds two ARP items and a route, see example. +| | ... +| | ... | *Example:* +| | ... | Three-node topology: +| | ... | TG_if1 - DUT1_if1-DUT1_if2 - DUT2_if1-DUT2_if2 - TG_if2 +| | ... | Create one VRF on each DUT: +| | ... | \| Setup VRF on DUT \| ${dut1_node} \| ${dut1_fib_table} \ +| | ... | \| ${dut1_to_dut2} \| ${dut2_to_dut1_ip4} \| ${dut2_to_dut1_mac} \ +| | ... | \| ${tg2_ip4} \| ${dut1_to_tg} \| ${tg1_ip4} \| ${tg_to_dut1_mac} \ +| | ... | \| 24 \| +| | ... | \| Setup VRF on DUT \| ${dut2_node} \| ${dut2_fib_table} \ +| | ... | \| ${dut2_to_dut1} \| ${dut1_to_dut2_ip4} \| ${dut1_to_dut2_mac} \ +| | ... | \| ${tg1_ip4} \| ${dut2_to_tg} \| ${tg2_ip4} \| ${tg_to_dut2_mac} \ +| | ... | \| 24 \| +| | ... +| | [Arguments] +| | ... | ${node} | ${table} | ${route_interface} | ${route_gateway_ip} +| | ... | ${route_gateway_mac} | ${route_dst_ip} | ${vrf_src_if} | ${src_if_ip} +| | ... | ${src_if_mac} | ${prefix_len} +| | ... +| | ${route_interface_idx}= | Get Interface SW Index +| | ... | ${node} | ${route_interface} +| | ... +| | Add fib table | ${node} +| | ... | ${route_dst_ip} | ${prefix_len} | ${table} +| | ... | via ${route_gateway_ip} sw_if_index ${route_interface_idx} multipath +| | ... +| | Assign Interface To Fib Table +| | ... | ${node} | ${route_interface} | ${table} +| | Assign Interface To Fib Table +| | ... | ${node} | ${vrf_src_if} | ${table} +| | ... +| | Add Arp On Dut | ${node} | ${vrf_src_if} +| | ... | ${src_if_ip} | ${src_if_mac} | vrf=${table} +| | Add Arp On Dut | ${node} | ${route_interface} +| | ... | ${route_gateway_ip} | ${route_gateway_mac} | vrf=${table} +| | ... +| | Vpp Route Add | ${node} | ${route_dst_ip} | ${prefix_len} +| | ... | ${route_gateway_ip} | ${route_interface} | vrf=${table} -- 2.16.6