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