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:
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 """Segment Routing over IPv6 dataplane utilities library."""
16 from resources.libraries.python.VatExecutor import VatTerminal
17 from resources.libraries.python.topology import Topology
20 # SRv6 LocalSID supported functions.
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 # Endpoint to SR-unaware appliance via static proxy
36 SRV6BEHAVIOUR_END_AS = 'end.as'
37 # Endpoint to SR-unaware appliance via dynamic proxy
38 SRV6BEHAVIOUR_END_AD = 'end.ad'
39 # Endpoint to SR-unaware appliance via masquerading
40 SRV6BEHAVIOUR_END_AM = 'end.am'
50 def configure_sr_localsid(node, local_sid, behavior, interface=None,
51 next_hop=None, fib_table=None, out_if=None,
52 in_if=None, src_addr=None, sid_list=None):
53 """Create SRv6 LocalSID and binds it to a particular behaviour on
56 :param node: Given node to create localSID on.
57 :param local_sid: LocalSID IPv6 address.
58 :param behavior: SRv6 LocalSID function.
59 :param interface: Interface name (Optional, required for
61 :param next_hop: Next hop IPv4/IPv6 address (Optional, required for L3
63 :param fib_table: FIB table for IPv4/IPv6 lookup (Optional, required for
65 :param out_if: Interface name of local interface for sending traffic
66 towards the Service Function (Optional, required for SRv6 endpoint
67 to SR-unaware appliance).
68 :param in_if: Interface name of local interface receiving the traffic
69 coming back from the Service Function (Optional, required for SRv6
70 endpoint to SR-unaware appliance).
71 :param src_addr: Source address on the packets coming back on in_if
72 interface (Optional, required for SRv6 endpoint to SR-unaware
73 appliance via static proxy).
74 :param sid_list: SID list (Optional, required for SRv6 endpoint to
75 SR-unaware appliance via static proxy).
86 :raises ValueError: If unsupported SRv6 LocalSID function used or
87 required parameter is missing.
89 if behavior == SRV6BEHAVIOUR_END:
91 elif behavior in [SRV6BEHAVIOUR_END_X, SRV6BEHAVIOUR_END_DX4,
92 SRV6BEHAVIOUR_END_DX6]:
93 if interface is None or next_hop is None:
94 raise ValueError('Required parameter(s) missing.\ninterface:{0}'
95 '\nnext_hop:{1}'.format(interface, next_hop))
96 interface_name = Topology.get_interface_name(node, interface)
97 params = '{0} {1}'.format(interface_name, next_hop)
98 elif behavior == SRV6BEHAVIOUR_END_DX2:
100 raise ValueError('Required parameter missing.\ninterface:{0}'.
102 params = '{0}'.format(interface)
103 elif behavior in [SRV6BEHAVIOUR_END_DT4, SRV6BEHAVIOUR_END_DT6]:
104 if fib_table is None:
105 raise ValueError('Required parameter missing.\nfib_table: {0}'.
107 params = '{0}'.format(fib_table)
108 elif behavior == SRV6BEHAVIOUR_END_AS:
109 if next_hop is None or out_if is None or in_if is None or \
110 src_addr is None or sid_list is None:
111 raise ValueError('Required parameter(s) missing.\nnext_hop:{0}'
112 '\nout_if:{1}\nin_if:{2}\nsrc_addr:{3}\n'
113 'sid_list:{4}'.format(next_hop, out_if, in_if,
115 sid_conf = 'next ' + ' next '.join(sid_list)
116 params = 'nh {0} oif {1} iif {2} src {3} {4}'.\
117 format(next_hop, out_if, in_if, src_addr, sid_conf)
118 elif behavior in [SRV6BEHAVIOUR_END_AD, SRV6BEHAVIOUR_END_AM]:
119 if next_hop is None or out_if is None or in_if is None:
120 raise ValueError('Required parameter(s) missing.\nnext_hop:{0}'
121 '\nout_if:{1}\nin_if:{2}'.
122 format(next_hop, out_if, in_if))
123 params = 'nh {0} oif {1} iif {2}'.format(next_hop, out_if, in_if)
125 raise ValueError('Unsupported SRv6 LocalSID function: {0}'.
128 with VatTerminal(node, json_param=False) as vat:
129 vat.vat_terminal_exec_cmd_from_template(
130 'srv6/sr_localsid_add.vat', local_sid=local_sid,
131 behavior=behavior, params=params)
133 if "exec error: Misc" in vat.vat_stdout:
134 raise RuntimeError('Create SRv6 LocalSID {0} failed on node {1}'.
135 format(local_sid, node['host']))
138 def delete_sr_localsid(node, local_sid):
139 """Delete SRv6 LocalSID on the given node.
141 :param node: Given node to delete localSID on.
142 :param local_sid: LocalSID IPv6 address.
146 with VatTerminal(node, json_param=False) as vat:
147 vat.vat_terminal_exec_cmd_from_template(
148 'srv6/sr_localsid_del.vat', local_sid=local_sid)
150 if "exec error: Misc" in vat.vat_stdout:
151 raise RuntimeError('Delete SRv6 LocalSID {0} failed on node {1}'.
152 format(local_sid, node['host']))
155 def show_sr_localsids(node):
156 """Show SRv6 LocalSIDs on the given node.
158 :param node: Given node to show localSIDs on.
161 with VatTerminal(node, json_param=False) as vat:
162 vat.vat_terminal_exec_cmd_from_template(
163 'srv6/sr_localsids_show.vat')
166 def configure_sr_policy(node, bsid, sid_list, mode='encap'):
167 """Create SRv6 policy on the given node.
169 :param node: Given node to create SRv6 policy on.
170 :param bsid: BindingSID - local SID IPv6 address.
171 :param sid_list: SID list.
172 :param mode: Encapsulation / insertion mode.
178 sid_conf = 'next ' + ' next '.join(sid_list)
180 with VatTerminal(node, json_param=False) as vat:
181 vat.vat_terminal_exec_cmd_from_template(
182 'srv6/sr_policy_add.vat', bsid=bsid,
183 sid_conf=sid_conf, mode=mode)
185 if "exec error: Misc" in vat.vat_stdout:
186 raise RuntimeError('Create SRv6 policy for BindingSID {0} failed on'
187 ' node {1}'.format(bsid, node['host']))
190 def delete_sr_policy(node, bsid):
191 """Delete SRv6 policy on the given node.
193 :param node: Given node to delete SRv6 policy on.
194 :param bsid: BindingSID IPv6 address.
198 with VatTerminal(node, json_param=False) as vat:
199 vat.vat_terminal_exec_cmd_from_template(
200 'srv6/sr_policy_del.vat', bsid=bsid)
202 if "exec error: Misc" in vat.vat_stdout:
203 raise RuntimeError('Delete SRv6 policy for BindingSID {0} failed on'
204 ' node {1}'.format(bsid, node['host']))
207 def show_sr_policies(node):
208 """Show SRv6 policies on the given node.
210 :param node: Given node to show SRv6 policies on.
213 with VatTerminal(node, json_param=False) as vat:
214 vat.vat_terminal_exec_cmd_from_template(
215 'srv6/sr_policies_show.vat')
218 def configure_sr_steer(node, mode, bsid, interface=None, ip_addr=None,
220 """Create SRv6 steering policy on the given node.
222 :param node: Given node to create steering policy on.
223 :param mode: Mode of operation - L2 or L3.
224 :param bsid: BindingSID - local SID IPv6 address.
225 :param interface: Interface name (Optional, required in case of
227 :param ip_addr: IPv4/IPv6 address (Optional, required in case of L3
229 :param prefix: IP address prefix (Optional, required in case of L3
237 :raises ValueError: If unsupported mode used or required parameter
240 if mode.lower() == 'l2':
241 if interface is None:
242 raise ValueError('Required data missing.\ninterface:{0}\n'.
244 interface_name = Topology.get_interface_name(node, interface)
245 params = 'l2 {0}'.format(interface_name)
246 elif mode.lower() == 'l3':
247 if ip_addr is None or prefix is None:
248 raise ValueError('Required data missing.\nIP address:{0}\n'
249 'mask:{1}'.format(ip_addr, prefix))
250 params = 'l3 {0}/{1}'.format(ip_addr, prefix)
252 raise ValueError('Unsupported mode: {0}'.format(mode))
254 with VatTerminal(node, json_param=False) as vat:
255 vat.vat_terminal_exec_cmd_from_template(
256 'srv6/sr_steer_add_del.vat', params=params, bsid=bsid)
258 sr_steer_errors = ("exec error: Misc",
259 "sr steer: No SR policy specified")
260 for err in sr_steer_errors:
261 if err in vat.vat_stdout:
262 raise RuntimeError('Create SRv6 steering policy for BindingSID'
263 ' {0} failed on node {1}'.
264 format(bsid, node['host']))
267 def delete_sr_steer(node, mode, bsid, interface=None, ip_addr=None,
269 """Delete SRv6 steering policy on the given node.
271 :param node: Given node to delete steering policy on.
272 :param mode: Mode of operation - L2 or L3.
273 :param bsid: BindingSID - local SID IPv6 address.
274 :param interface: Interface name (Optional, required in case of
276 :param ip_addr: IPv4/IPv6 address (Optional, required in case of L3
278 :param mask: IP address mask (Optional, required in case of L3 mode).
285 :raises ValueError: If unsupported mode used or required parameter
290 if interface is None:
291 raise ValueError('Required data missing.\ninterface:{0}\n'.
293 interface_name = Topology.get_interface_name(node, interface)
294 params += 'l2 {0}'.format(interface_name)
296 if ip_addr is None or mask is None:
297 raise ValueError('Required data missing.\nIP address:{0}\n'
298 'mask:{1}'.format(ip_addr, mask))
299 params += '{0}/{1}'.format(ip_addr, mask)
301 raise ValueError('Unsupported mode: {0}'.format(mode))
303 with VatTerminal(node, json_param=False) as vat:
304 vat.vat_terminal_exec_cmd_from_template(
305 'srv6/sr_steer_add_del.vat', params=params, bsid=bsid)
307 if "exec error: Misc" in vat.vat_stdout:
308 raise RuntimeError('Delete SRv6 policy for bsid {0} failed on node'
309 ' {1}'.format(bsid, node['host']))
312 def show_sr_steering_policies(node):
313 """Show SRv6 steering policies on the given node.
315 :param node: Given node to show SRv6 steering policies on.
318 with VatTerminal(node, json_param=False) as vat:
319 vat.vat_terminal_exec_cmd_from_template(
320 'srv6/sr_steer_policies_show.vat')
323 def set_sr_encaps_source_address(node, ip6_addr):
324 """Set SRv6 encapsulation source address on the given node.
326 :param node: Given node to set SRv6 encapsulation source address on.
327 :param ip6_addr: Local SID IPv6 address.
331 with VatTerminal(node, json_param=False) as vat:
332 vat.vat_terminal_exec_cmd_from_template(
333 'srv6/sr_set_encaps_source.vat', ip6_addr=ip6_addr)