1 # Copyright (c) 2019 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 """GBP utilities library."""
16 from enum import IntEnum
17 from ipaddress import ip_address
19 from resources.libraries.python.IPUtil import IPUtil
20 from resources.libraries.python.L2Util import L2Util
21 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
24 class GBPEndpointFlags(IntEnum):
25 """GBP Endpoint Flags."""
26 GBP_API_ENDPOINT_FLAG_NONE = 0
27 GBP_API_ENDPOINT_FLAG_BOUNCE = 1
28 GBP_API_ENDPOINT_FLAG_REMOTE = 2
29 GBP_API_ENDPOINT_FLAG_LEARNT = 4
30 GBP_API_ENDPOINT_FLAG_EXTERNAL = 8
33 class GBPBridgeDomainFlags(IntEnum):
34 """GBP Bridge Domain Flags."""
35 GBP_BD_API_FLAG_NONE = 0
36 GBP_BD_API_FLAG_DO_NOT_LEARN = 1
37 GBP_BD_API_FLAG_UU_FWD_DROP = 2
38 GBP_BD_API_FLAG_MCAST_DROP = 4
39 GBP_BD_API_FLAG_UCAST_ARP = 8
42 class GBPSubnetType(IntEnum):
43 """GBP Subnet Type."""
44 GBP_API_SUBNET_TRANSPORT = 1
45 GBP_API_SUBNET_STITCHED_INTERNAL = 2 # pylint: disable=invalid-name
46 GBP_API_SUBNET_STITCHED_EXTERNAL = 3 # pylint: disable=invalid-name
47 GBP_API_SUBNET_L3_OUT = 4
48 GBP_API_SUBNET_ANON_L3_OUT = 5
51 class GBPExtItfFlags(IntEnum):
52 """GBP External Interface Flags."""
53 GBP_API_EXT_ITF_F_NONE = 0
54 GBP_API_EXT_ITF_F_ANON = 1
57 class GBPRuleAction(IntEnum):
58 """GBP Rule Action."""
59 GBP_API_RULE_PERMIT = 1
61 GBP_API_RULE_REDIRECT = 3
68 def gbp_route_domain_add(
69 node, rd_id=1, ip4_table_id=1, ip6_table_id=0,
70 ip4_uu_sw_if_index=0xffffffff, ip6_uu_sw_if_index=0xffffffff):
71 """Add GBP route domain.
73 :param node: Node to add GBP route domain on.
74 :param rd_id: GBP route domain ID.
75 :param ip4_table_id: IPv4 table.
76 :param ip6_table_id: IPv6 table.
77 :param ip4_uu_sw_if_index: IPv4 unicast interface index.
78 :param ip6_uu_sw_if_index: IPv6 unicast interface index.
81 :type ip4_table_id: int
82 :type ip6_table_id: int
83 :type ip4_uu_sw_if_index: int
84 :type ip6_uu_sw_if_index: int
86 cmd = 'gbp_route_domain_add'
87 err_msg = 'Failed to add GBP route domain on {node}!'\
88 .format(node=node['host'])
93 ip4_table_id=ip4_table_id,
94 ip6_table_id=ip6_table_id,
95 ip4_uu_sw_if_index=ip4_uu_sw_if_index,
96 ip6_uu_sw_if_index=ip6_uu_sw_if_index
100 with PapiSocketExecutor(node) as papi_exec:
101 papi_exec.add(cmd, **args_in).get_reply(err_msg)
104 def gbp_bridge_domain_add(
105 node, bvi_sw_if_index, bd_id=1, rd_id=1,
106 uu_fwd_sw_if_index=0xffffffff, bm_flood_sw_if_index=0xffffffff):
107 """Add GBP bridge domain.
109 :param node: Node to add GBP bridge domain on.
110 :param bvi_sw_if_index: SW index of BVI/loopback interface.
111 :param bd_id: GBP bridge domain ID.
112 :param rd_id: GBP route domain ID.
113 :param uu_fwd_sw_if_index: Unicast forward interface index.
114 :param bm_flood_sw_if_index: Bcast/Mcast flood interface index.
116 :type bvi_sw_if_index: int
119 :type uu_fwd_sw_if_index: int
120 :type bm_flood_sw_if_index: int
122 cmd = 'gbp_bridge_domain_add'
123 err_msg = 'Failed to add GBP bridge domain on {node}!'\
124 .format(node=node['host'])
128 flags=getattr(GBPBridgeDomainFlags,
129 'GBP_BD_API_FLAG_NONE').value,
130 bvi_sw_if_index=bvi_sw_if_index,
131 uu_fwd_sw_if_index=uu_fwd_sw_if_index,
132 bm_flood_sw_if_index=bm_flood_sw_if_index,
138 with PapiSocketExecutor(node) as papi_exec:
139 papi_exec.add(cmd, **args_in).get_reply(err_msg)
142 def gbp_endpoint_group_add(
143 node, sclass, bd_id=1, rd_id=1, vnid=1,
144 uplink_sw_if_index=0xffffffff, remote_ep_timeout=0xffffffff):
145 """Add GBP endpoint group.
147 :param node: Node to add GBP endpoint group on.
148 :param sclass: Source CLASS.
149 :param bd_id: GBP bridge domain ID.
150 :param rd_id: GBP route domain ID.
151 :param uplink_sw_if_index: Uplink interface index.
152 :param remote_ep_timeout: Remote endpoint interface index.
159 :type uplink_sw_if_index: int
160 :type remote_ep_timeout: int
162 cmd = 'gbp_endpoint_group_add'
163 err_msg = 'Failed to add GBP endpoint group on {node}!'\
164 .format(node=node['host'])
168 uplink_sw_if_index=uplink_sw_if_index,
174 remote_ep_timeout=remote_ep_timeout
179 with PapiSocketExecutor(node) as papi_exec:
180 papi_exec.add(cmd, **args_in).get_reply(err_msg)
183 def gbp_endpoint_add(node, sw_if_index, ip_addr, mac_addr, sclass):
186 :param node: Node to add GBP endpoint on.
187 :param sw_if_index: SW index of interface.
188 :param ip_addr: GBP route domain ID.
189 :param mac_addr: MAC address.
190 :param sclass: Source CLASS.
192 :type sw_if_index: int
197 cmd = 'gbp_endpoint_add'
198 err_msg = 'Failed to add GBP endpoint on {node}!'\
199 .format(node=node['host'])
202 ips.append(IPUtil.create_ip_address_object(
203 ip_address(unicode(ip_addr))))
204 tun_src = IPUtil.create_ip_address_object(
205 ip_address(unicode('0.0.0.0')))
206 tun_dst = IPUtil.create_ip_address_object(
207 ip_address(unicode('0.0.0.0')))
211 sw_if_index=sw_if_index,
214 mac=L2Util.mac_to_bin(mac_addr),
216 flags=getattr(GBPEndpointFlags,
217 'GBP_API_ENDPOINT_FLAG_EXTERNAL').value,
225 with PapiSocketExecutor(node) as papi_exec:
226 papi_exec.add(cmd, **args_in).get_reply(err_msg)
229 def gbp_ext_itf_add_del(node, sw_if_index, bd_id=1, rd_id=1):
230 """Add external interface to GBP.
232 :param node: Node to add external GBP interface on.
233 :param sw_if_index: SW index of interface.
234 :param bd_id: GBP bridge domain ID.
235 :param rd_id: GBP route domain ID.
237 :type sw_if_index: int
241 cmd = 'gbp_ext_itf_add_del'
242 err_msg = 'Failed to add external GBP interface on {node}!'\
243 .format(node=node['host'])
248 sw_if_index=sw_if_index,
251 flags=getattr(GBPExtItfFlags,
252 'GBP_API_EXT_ITF_F_NONE').value
256 with PapiSocketExecutor(node) as papi_exec:
257 papi_exec.add(cmd, **args_in).get_reply(err_msg)
260 def gbp_subnet_add_del(
261 node, address, subnet_length, sclass, rd_id=1,
262 sw_if_index=0xffffffff):
263 """Add external interface to GBP.
265 :param node: Node to add GBP subnet on.
266 :param address: IPv4 adddress.
267 :param subnet_length: IPv4 address subnet.
268 :param sclass: Source CLASS.
269 :param rd_id: GBP route domain ID.
270 :param sw_if_index: Interface index.
273 :type subnet_length: int
276 :type sw_if_index: int
278 cmd = 'gbp_subnet_add_del'
279 err_msg = 'Failed to add GBP subnet on {node}!'\
280 .format(node=node['host'])
285 type=getattr(GBPSubnetType,
286 'GBP_API_SUBNET_L3_OUT').value,
287 sw_if_index=sw_if_index,
290 address=IPUtil.create_ip_address_object(
291 ip_address(unicode(address))),
292 len=int(subnet_length)
298 with PapiSocketExecutor(node) as papi_exec:
299 papi_exec.add(cmd, **args_in).get_reply(err_msg)
302 def gbp_contract_add_del(node, sclass, dclass, acl_index=0):
305 :param node: Node to add GBP contract on.
306 :param sclass: Source CLASS.
307 :param dclass: Destination CLASS.
308 :param acl_index: Index of ACL rule.
314 cmd = 'gbp_contract_add_del'
315 err_msg = 'Failed to add GBP contract on {node}!'\
316 .format(node=node['host'])
319 action=getattr(GBPRuleAction,
320 'GBP_API_RULE_PERMIT').value,
327 rules = [rule_permit, rule_permit]
338 allowed_ethertypes=[0x800, 0x86dd] + [0]*14
342 with PapiSocketExecutor(node) as papi_exec:
343 papi_exec.add(cmd, **args_in).get_reply(err_msg)