add new topology parameter: arch
[csit.git] / resources / libraries / python / SRv6.py
1 # Copyright (c) 2017 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 """Segment Routing over IPv6 dataplane utilities library."""
15
16 from enum import Enum
17
18 from resources.libraries.python.VatExecutor import VatTerminal
19 from resources.libraries.python.VatJsonUtil import VatJsonUtil
20 from resources.libraries.python.topology import Topology
21
22
23 class SRv6Behaviour(Enum):
24     """Defines SRv6 endpoint functions implemented in VPP."""
25     # Endpoint function
26     END = 'end'
27     # Endpoint function with Layer-3 cross-connect
28     END_X = 'end.x'
29     # Endpoint with decapsulation and Layer-2 cross-connect
30     END_DX2 = 'end.dx2'
31     # Endpoint with decapsulation and IPv4 cross-connect
32     END_DX4 = 'end.dx4'
33     # Endpoint with decapsulation and IPv4 table lookup
34     END_DT4 = 'end.dt4'
35     # Endpoint with decapsulation and IPv6 cross-connect
36     END_DX6 = 'end.dx6'
37     # Endpoint with decapsulation and IPv6 table lookup
38     END_DT6 = 'end.dt6'
39
40
41 class SRv6(object):
42     """SRv6 class."""
43
44     def __init__(self):
45         pass
46
47     @staticmethod
48     def configure_sr_localsid(node, local_sid, behavior, interface=None,
49                               next_hop=None, fib_table=None):
50         """Create SRv6 LocalSID and binds it to a particular behaviour on
51         the given node.
52
53         :param node: Given node to create localSID on.
54         :param local_sid: LocalSID IPv6 address.
55         :param behavior: SRv6 LocalSID function.
56         :param interface: Interface name (Optional, required for
57             L2/L3 xconnects).
58         :param next_hop: Next hop IPv4/IPv6 address (Optional, required for L3
59             xconnects).
60         :param fib_table: FIB table for IPv4/IPv6 lookup (Optional, required for
61             L3 routing).
62         :type node: dict
63         :type local_sid: str
64         :type behavior: str
65         :type interface: str
66         :type next_hop: int
67         :type fib_table: str
68         :raises ValueError: If unsupported SRv6 LocalSID function used or
69             required parameter is missing.
70         """
71         if behavior == SRv6Behaviour.END:
72             params = ''
73         elif behavior in [SRv6Behaviour.END_X, SRv6Behaviour.END_DX4,
74                           SRv6Behaviour.END_DX6]:
75             if interface is None or next_hop is None:
76                 raise ValueError('Required data missing.\ninterface:{0}\n'
77                                  'next_hop:{1}'.format(interface, next_hop))
78             interface_name = Topology.get_interface_name(node, interface)
79             params = '{0} {1}'.format(interface_name, next_hop)
80         elif behavior == SRv6Behaviour.END_DX2:
81             if interface is None:
82                 raise ValueError('Required data missing.\ninterface:{0}\n'.
83                                  format(interface))
84             params = '{0}'.format(interface)
85         elif behavior in [SRv6Behaviour.END_DT4, SRv6Behaviour.END_DT6]:
86             if fib_table is None:
87                 raise ValueError('Required data missing.\nfib_table:{0}\n'.
88                                  format(fib_table))
89             params = '{0}'.format(fib_table)
90         else:
91             raise ValueError('Unsupported SRv6 LocalSID function: {0}'.
92                              format(behavior))
93
94         with VatTerminal(node) as vat:
95             resp = vat.vat_terminal_exec_cmd_from_template(
96                 'srv6/sr_localsid_add.vat', local_sid=local_sid,
97                 behavior=behavior, params=params)
98
99         VatJsonUtil.verify_vat_retval(
100             resp[0],
101             err_msg='Create SRv6 LocalSID {0} failed on node {1}'.format(
102                 local_sid, node['host']))
103
104     @staticmethod
105     def delete_sr_localsid(node, local_sid):
106         """Delete SRv6 LocalSID on the given node.
107
108         :param node: Given node to delete localSID on.
109         :param local_sid: LocalSID IPv6 address.
110         :type node: dict
111         :type local_sid: str
112         """
113         with VatTerminal(node) as vat:
114             resp = vat.vat_terminal_exec_cmd_from_template(
115                 'srv6/sr_localsid_del.vat', local_sid=local_sid)
116
117         VatJsonUtil.verify_vat_retval(
118             resp[0],
119             err_msg='Delete SRv6 LocalSID {0} failed on node {1}'.format(
120                 local_sid, node['host']))
121
122     @staticmethod
123     def show_sr_localsids(node):
124         """Show SRv6 LocalSIDs on the given node.
125
126         :param node: Given node to show localSIDs on.
127         :type node: dict
128         """
129         with VatTerminal(node) as vat:
130             vat.vat_terminal_exec_cmd_from_template(
131                 'srv6/sr_localsids_show.vat')
132
133     @staticmethod
134     def configure_sr_policy(node, bsid, sid_list, mode='encap'):
135         """Create SRv6 policy on the given node.
136
137         :param node: Given node to create SRv6 policy on.
138         :param bsid: BindingSID - local SID IPv6 address.
139         :param sid_list: SID list.
140         :param mode: Encapsulation / insertion mode.
141         :type node: dict
142         :type bsid: str
143         :type sid_list: list
144         :type mode: str
145         """
146         sid_conf = 'next ' + ' next '.join(sid_list)
147
148         with VatTerminal(node) as vat:
149             resp = vat.vat_terminal_exec_cmd_from_template(
150                 'srv6/sr_policy_add.vat', bsid=bsid,
151                 sid_conf=sid_conf, mode=mode)
152
153         VatJsonUtil.verify_vat_retval(
154             resp[0],
155             err_msg='Create SRv6 policy for BindingSID {0} failed on node '
156                     '{1}'.format(bsid, node['host']))
157
158     @staticmethod
159     def delete_sr_policy(node, bsid):
160         """Delete SRv6 policy on the given node.
161
162         :param node: Given node to delete SRv6 policy on.
163         :param bsid: BindingSID IPv6 address.
164         :type node: dict
165         :type bsid: str
166         """
167         with VatTerminal(node) as vat:
168             resp = vat.vat_terminal_exec_cmd_from_template(
169                 'srv6/sr_policy_del.vat', bsid=bsid)
170
171         VatJsonUtil.verify_vat_retval(
172             resp[0],
173             err_msg='Delete SRv6 policy for BindingSID {0} failed on node '
174                     '{1}'.format(bsid, node['host']))
175
176     @staticmethod
177     def show_sr_policies(node):
178         """Show SRv6 policies on the given node.
179
180         :param node: Given node to show SRv6 policies on.
181         :type node: dict
182         """
183         with VatTerminal(node, json_param=False) as vat:
184             vat.vat_terminal_exec_cmd_from_template(
185                 'srv6/sr_policies_show.vat')
186
187     @staticmethod
188     def configure_sr_steer(node, mode, bsid, interface=None, ip_addr=None,
189                            mask=None):
190         """Create SRv6 steering policy on the given node.
191
192         :param node: Given node to create steering policy on.
193         :param mode: Mode of operation - L2 or L3.
194         :param bsid: BindingSID - local SID IPv6 address.
195         :param interface: Interface name (Optional, required in case of
196             L2 mode).
197         :param ip_addr: IPv4/IPv6 address (Optional, required in case of L3
198             mode).
199         :param mask: IP address mask (Optional, required in case of L3 mode).
200         :type node: dict
201         :type mode: str
202         :type bsid: str
203         :type interface: str
204         :type ip_addr: int
205         :type mask: int
206         :raises ValueError: If unsupported mode used or required parameter
207             is missing.
208         """
209         if mode == 'l2':
210             if interface is None:
211                 raise ValueError('Required data missing.\ninterface:{0}\n'.
212                                  format(interface))
213             interface_name = Topology.get_interface_name(node, interface)
214             params = 'l2 {0}'.format(interface_name)
215         elif mode == 'l3':
216             if ip_addr is None or mask is None:
217                 raise ValueError('Required data missing.\nIP address:{0}\n'
218                                  'mask:{1}'.format(ip_addr, mask))
219             params = '{0}/{1}'.format(ip_addr, mask)
220         else:
221             raise ValueError('Unsupported mode: {0}'.format(mode))
222
223         with VatTerminal(node) as vat:
224             resp = vat.vat_terminal_exec_cmd_from_template(
225                 'srv6/sr_steer_add_del.vat', params=params, bsid=bsid)
226
227         VatJsonUtil.verify_vat_retval(
228             resp[0],
229             err_msg='Create SRv6 steering policy for BindingSID {0} failed on '
230                     'node {1}'.format(bsid, node['host']))
231
232     @staticmethod
233     def delete_sr_steer(node, mode, bsid, interface=None, ip_addr=None,
234                         mask=None):
235         """Delete SRv6 steering policy on the given node.
236
237         :param node: Given node to delete steering policy on.
238         :param mode: Mode of operation - L2 or L3.
239         :param bsid: BindingSID - local SID IPv6 address.
240         :param interface: Interface name (Optional, required in case of
241             L2 mode).
242         :param ip_addr: IPv4/IPv6 address (Optional, required in case of L3
243             mode).
244         :param mask: IP address mask (Optional, required in case of L3 mode).
245         :type node: dict
246         :type mode: str
247         :type bsid: str
248         :type interface: str
249         :type ip_addr: int
250         :type mask: int
251         :raises ValueError: If unsupported mode used or required parameter
252             is missing.
253         """
254         params = 'del'
255         if mode == 'l2':
256             if interface is None:
257                 raise ValueError('Required data missing.\ninterface:{0}\n'.
258                                  format(interface))
259             interface_name = Topology.get_interface_name(node, interface)
260             params += 'l2 {0}'.format(interface_name)
261         elif mode == 'l3':
262             if ip_addr is None or mask is None:
263                 raise ValueError('Required data missing.\nIP address:{0}\n'
264                                  'mask:{1}'.format(ip_addr, mask))
265             params += '{0}/{1}'.format(ip_addr, mask)
266         else:
267             raise ValueError('Unsupported mode: {0}'.format(mode))
268
269         with VatTerminal(node) as vat:
270             resp = vat.vat_terminal_exec_cmd_from_template(
271                 'srv6/sr_steer_add_del.vat', params=params, bsid=bsid)
272
273         VatJsonUtil.verify_vat_retval(
274             resp[0],
275             err_msg='Delete SRv6 policy for bsid {0} failed on node {1}'.format(
276                 bsid, node['host']))
277
278     @staticmethod
279     def show_sr_steering_policies(node):
280         """Show SRv6 steering policies on the given node.
281
282         :param node: Given node to show SRv6 steering policies on.
283         :type node: dict
284         """
285         with VatTerminal(node, json_param=False) as vat:
286             vat.vat_terminal_exec_cmd_from_template(
287                 'srv6/sr_steer_policies_show.vat')
288
289     @staticmethod
290     def set_sr_encaps_source_address(node, ip6_addr):
291         """Set SRv6 encapsulation source address on the given node.
292
293         :param node: Given node to set SRv6 encapsulation source address on.
294         :param ip6_addr: Local SID IPv6 address.
295         :type node: dict
296         :type ip6_addr: str
297         """
298         with VatTerminal(node) as vat:
299             resp = vat.vat_terminal_exec_cmd_from_template(
300                 'srv6/sr_set_encaps_source.vat', ip6_addr=ip6_addr)
301
302         VatJsonUtil.verify_vat_retval(
303             resp[0],
304             err_msg='Set SRv6 encapsulation source address {0} failed on node'
305                     ' {1}'.format(ip6_addr, node['host']))