1 # Copyright (c) 2021 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:
6 # http://www.apache.org/licenses/LICENSE-2.0
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.
14 """VPP GENEVE Plugin utilities library."""
16 from ipaddress import ip_address
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.IPUtil import IPUtil
22 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
23 from resources.libraries.python.topology import Topology
27 """VPP GENEVE Plugin Keywords."""
30 def add_geneve_tunnel(
31 node, local_address, remote_address, vni, multicast_if=None,
32 encap_vrf=0, l3_mode=False, next_index=None):
33 """Add GENEVE tunnel on the specified VPP node.
35 :param node: Topology node.
36 :param local_address: Local IP address.
37 :param remote_address: Remote IP address.
38 :param vni: Virtual network ID.
39 :param multicast_if: Interface key of multicast interface; used only if
40 remote is multicast. (Default value = None)
41 :param encap_vrf: The FIB ID for sending unicast GENEVE encap packets or
42 receiving multicast packets. (Default value = 0)
43 :param l3_mode: Use geneve tunnel in L3 mode (ip routing) if Tue else in
44 L2 mode (L2 switching). (Default value = False)
45 :param next_index: The index of the next node.
47 :type local_address: str
48 :type remote_address: str
50 :type multicast_if: str
54 :returns: SW interface index of created geneve tunnel.
57 cmd = u"geneve_add_del_tunnel2"
60 local_address=IPAddress.create_ip_address_object(
61 ip_address(local_address)
63 remote_address=IPAddress.create_ip_address_object(
64 ip_address(remote_address)
66 mcast_sw_if_index=Topology.get_interface_sw_index(
68 ) if multicast_if else Constants.BITWISE_NON_ZERO,
69 encap_vrf_id=int(encap_vrf),
70 decap_next_index=next_index if l3_mode
71 else Constants.BITWISE_NON_ZERO,
75 err_msg = f"Failed to configure GENEVE tunnel on host {node[u'host']}!"
76 with PapiSocketExecutor(node) as papi_exec:
77 sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg)
79 if_key = Topology.add_new_port(node, u"geneve_tunnel")
80 Topology.update_interface_sw_if_index(node, if_key, sw_if_index)
82 ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_index)
83 Topology.update_interface_name(node, if_key, ifc_name)
85 ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_index)
86 Topology.update_interface_mac_address(node, if_key, ifc_mac)
91 def enable_interface_geneve_bypass(node, interface, is_ipv6=False):
92 """Add ipv4/ipv6-geneve-bypass graph node for a given interface on
93 the specified VPP node.
95 :param node: Topology node.
96 :param interface: Interface key from topology file of interface
97 to add geneve bypass node for.
98 :param is_ipv6: Enable ipv6-geneve-bypass graph node if True else enable
99 ipv4-geneve-bypass graph node.
104 cmd = u"sw_interface_set_geneve_bypass"
108 sw_if_index=Topology.get_interface_sw_index(node, interface)
111 f"Failed to enable {u'ipv6' if is_ipv6 else u'ipv4'}-geneve-bypass "
112 f"on interface {interface} on host {node[u'host']}!"
114 with PapiSocketExecutor(node) as papi_exec:
115 papi_exec.add(cmd, **args).get_reply(err_msg)
118 def show_geneve_tunnel_data(node):
119 """Show the GENEVE tunnels data.
121 :param node: DUT node.
125 u"geneve_tunnel_dump",
127 PapiSocketExecutor.dump_and_log(node, cmds)
130 def vpp_geneve_add_multiple_tunnels(
131 node, gen_tunnel, n_tunnels, dut_if1, dut_if2, tg_if1_ip4,
132 tg_if2_ip4, tg_pf2_mac, next_idx):
133 """Create multiple GENEVE tunnels.
135 :param node: DUT node.
136 :param gen_tunnel: Parameters of the GENEVE tunnel.
137 :param n_tunnels: Number of tunnels.
138 :param dut_if1: The first DUT interface.
139 :param dut_if2: The second DUT interface.
140 :param tg_if1_ip4: TG interface 1 IP address.
141 :param tg_if2_ip4: TG interface 2 IP address.
142 :param tg_pf2_mac: TG interface 2 MAC address.
143 :param next_idx: The index of the next node.
145 :type gen_tunnel: dict
149 :type tg_if1_ip4: str
150 :type tg_if2_ip4: str
151 :type tg_pf2_mac: str
155 src_ip_int = IPUtil.ip_to_int(gen_tunnel[u"src_ip"])
156 dst_ip_int = IPUtil.ip_to_int(gen_tunnel[u"dst_ip"])
157 if_ip_int = IPUtil.ip_to_int(gen_tunnel[u"if_ip"])
159 for idx in range(n_tunnels):
160 src_ip = IPUtil.int_to_ip(src_ip_int + idx * 256)
161 dst_ip = IPUtil.int_to_ip(dst_ip_int + idx * 256)
162 if_ip = IPUtil.int_to_ip(if_ip_int + idx * 256)
164 IPUtil.vpp_route_add(
165 node, src_ip, gen_tunnel[u"ip_mask"],
166 gateway=tg_if1_ip4, interface=dut_if1
168 tunnel_sw_index = GeneveUtil.add_geneve_tunnel(
169 node, gen_tunnel[u"local"], gen_tunnel[u"remote"],
170 gen_tunnel[u"vni"] + idx, l3_mode=True, next_index=next_idx
172 tunnel_if_key = Topology.get_interface_by_sw_index(
173 node, tunnel_sw_index
175 tunnel_if_mac = Topology.get_interface_mac(
178 IPUtil.vpp_interface_set_ip_address(node, tunnel_if_key, if_ip, 24)
179 IPUtil.vpp_add_ip_neighbor(
180 node, tunnel_if_key, tg_if2_ip4, tg_pf2_mac
182 IPUtil.vpp_route_add(
183 node, dst_ip, gen_tunnel[u"ip_mask"],
184 gateway=tg_if2_ip4, interface=tunnel_if_key
186 IPUtil.vpp_route_add(
187 node, gen_tunnel[u"remote"], 32,
188 gateway=tg_if2_ip4, interface=dut_if2
190 IPUtil.vpp_add_ip_neighbor(
191 node, tunnel_if_key, gen_tunnel[u"local"], tunnel_if_mac
193 IPUtil.vpp_route_add(
194 node, gen_tunnel[u"local"], 32, gateway=if_ip
196 InterfaceUtil.set_interface_state(node, tunnel_if_key, u"up")