vpp-device: GENEVE tunnel test, l3 mode
[csit.git] / resources / libraries / python / GeneveUtil.py
1 # Copyright (c) 2020 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """VPP GENEVE Plugin utilities library."""
15
16 from ipaddress import ip_address
17
18 from resources.libraries.python.Constants import Constants
19 from resources.libraries.python.InterfaceUtil import InterfaceUtil
20 from resources.libraries.python.IPAddress import IPAddress
21 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
22 from resources.libraries.python.topology import Topology
23
24
25 class GeneveUtil:
26     """VPP GENEVE Plugin Keywords."""
27
28     @staticmethod
29     def add_geneve_tunnel(
30             node, local_address, remote_address, vni, multicast_if=None,
31             encap_vrf=0, l3_mode=False, next_index=None):
32         """Add GENEVE tunnel on the specified VPP node.
33
34         :param node: Topology node.
35         :param local_address: Local IP address.
36         :param remote_address: Remote IP address.
37         :param vni: Virtual network ID.
38         :param multicast_if: Interface key of multicast interface; used only if
39             remote is multicast. (Default value = None)
40         :param encap_vrf: The FIB ID for sending unicast GENEVE encap packets or
41             receiving multicast packets. (Default value = 0)
42         :param l3_mode: Use geneve tunnel in L3 mode (ip routing) if Tue else in
43             L2 mode (L2 switching). (Default value = False)
44         :param next_index: The index of the next node.
45         :type node: dict
46         :type local_address: str
47         :type remote_address: str
48         :type vni: int
49         :type multicast_if: str
50         :type encap_vrf: int
51         :type l3_mode: bool
52         :type next_index: int
53         :returns: SW interface index of created geneve tunnel.
54         :rtype: int
55         """
56         cmd = u"geneve_add_del_tunnel2"
57         args = dict(
58             is_add=True,
59             local_address=IPAddress.create_ip_address_object(
60                 ip_address(local_address)
61             ),
62             remote_address=IPAddress.create_ip_address_object(
63                 ip_address(remote_address)
64             ),
65             mcast_sw_if_index=Topology.get_interface_sw_index(
66                 node, multicast_if
67             ) if multicast_if else Constants.BITWISE_NON_ZERO,
68             encap_vrf_id=int(encap_vrf),
69             decap_next_index=next_index if l3_mode
70             else Constants.BITWISE_NON_ZERO,
71             vni=int(vni),
72             l3_mode=l3_mode
73         )
74         err_msg = f"Failed to configure GENEVE tunnel on host {node[u'host']}!"
75         with PapiSocketExecutor(node) as papi_exec:
76             sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg)
77
78         if_key = Topology.add_new_port(node, u"geneve_tunnel")
79         Topology.update_interface_sw_if_index(node, if_key, sw_if_index)
80
81         ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_index)
82         Topology.update_interface_name(node, if_key, ifc_name)
83
84         ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_index)
85         Topology.update_interface_mac_address(node, if_key, ifc_mac)
86
87         return sw_if_index
88
89     @staticmethod
90     def enable_interface_geneve_bypass(node, interface, is_ipv6=False):
91         """Add ipv4/ipv6-geneve-bypass graph node for a given interface on
92         the specified VPP node.
93
94         :param node: Topology node.
95         :param interface: Interface key from topology file of interface
96             to add geneve bypass node for.
97         :param is_ipv6: Enable ipv6-geneve-bypass graph node if True else enable
98             ipv4-geneve-bypass graph node.
99         :type node: dict
100         :type interface: str
101         :type is_ipv6: bool
102         """
103         cmd = u"sw_interface_set_geneve_bypass"
104         args = dict(
105             is_ipv6=is_ipv6,
106             enable=True,
107             sw_if_index=Topology.get_interface_sw_index(node, interface)
108         )
109         err_msg = (
110             f"Failed to enable {u'ipv6' if is_ipv6 else u'ipv4'}-geneve-bypass "
111             f"on interface {interface} on host {node[u'host']}!"
112         )
113         with PapiSocketExecutor(node) as papi_exec:
114             papi_exec.add(cmd, **args).get_reply(err_msg)
115
116     @staticmethod
117     def show_geneve_tunnel_data(node):
118         """Show the GENEVE tunnels data.
119
120         :param node: DUT node.
121         :type node: dict
122         """
123         cmds = [
124             u"geneve_tunnel_dump",
125         ]
126         PapiSocketExecutor.dump_and_log(node, cmds)