From 2291eaac7509aadf30be407a6eb84cfa3d3a33d0 Mon Sep 17 00:00:00 2001 From: Jan Gelety Date: Wed, 13 Dec 2017 08:16:38 +0100 Subject: [PATCH] CSIT-816: SRv6 L1 KWs Current implementation doesn't contain: * weight * fib-table for BSID * policy index identification These features will be added on demand later. Change-Id: I1386c0a0e71f7ae3182b84e0ec5bb245366632d1 Signed-off-by: Jan Gelety --- resources/libraries/python/SRv6.py | 287 +++++++++++++++++++++ resources/templates/vat/srv6/sr_localsid_add.vat | 1 + resources/templates/vat/srv6/sr_localsid_del.vat | 1 + resources/templates/vat/srv6/sr_localsids_show.vat | 1 + resources/templates/vat/srv6/sr_policies_show.vat | 1 + resources/templates/vat/srv6/sr_policy_add.vat | 1 + resources/templates/vat/srv6/sr_policy_del.vat | 1 + resources/templates/vat/srv6/sr_steer_add_del.vat | 1 + .../templates/vat/srv6/sr_steer_policies_show.vat | 1 + 9 files changed, 295 insertions(+) create mode 100644 resources/libraries/python/SRv6.py create mode 100644 resources/templates/vat/srv6/sr_localsid_add.vat create mode 100644 resources/templates/vat/srv6/sr_localsid_del.vat create mode 100644 resources/templates/vat/srv6/sr_localsids_show.vat create mode 100644 resources/templates/vat/srv6/sr_policies_show.vat create mode 100644 resources/templates/vat/srv6/sr_policy_add.vat create mode 100644 resources/templates/vat/srv6/sr_policy_del.vat create mode 100644 resources/templates/vat/srv6/sr_steer_add_del.vat create mode 100644 resources/templates/vat/srv6/sr_steer_policies_show.vat diff --git a/resources/libraries/python/SRv6.py b/resources/libraries/python/SRv6.py new file mode 100644 index 0000000000..a22bb5e832 --- /dev/null +++ b/resources/libraries/python/SRv6.py @@ -0,0 +1,287 @@ +# Copyright (c) 2017 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Segment Routing over IPv6 dataplane utilities library.""" + +from enum import Enum + +from resources.libraries.python.VatExecutor import VatTerminal +from resources.libraries.python.VatJsonUtil import VatJsonUtil +from resources.libraries.python.topology import Topology + + +class SRv6Behaviour(Enum): + """Defines SRv6 endpoint functions implemented in VPP.""" + # Endpoint function + END = 'end' + # Endpoint function with Layer-3 cross-connect + END_X = 'end.x' + # Endpoint with decapsulation and Layer-2 cross-connect + END_DX2 = 'end.dx2' + # Endpoint with decapsulation and IPv4 cross-connect + END_DX4 = 'end.dx4' + # Endpoint with decapsulation and IPv4 table lookup + END_DT4 = 'end.dt4' + # Endpoint with decapsulation and IPv6 cross-connect + END_DX6 = 'end.dx6' + # Endpoint with decapsulation and IPv6 table lookup + END_DT6 = 'end.dt6' + + +class SRv6(object): + """SRv6 class.""" + + def __init__(self): + pass + + @staticmethod + def configure_sr_localsid(node, local_sid, behavior, interface=None, + next_hop=None, fib_table=None): + """Create SRv6 LocalSID and binds it to a particular behaviour on + the given node. + + :param node: Given node to create localSID on. + :param local_sid: LocalSID IPv6 address. + :param behavior: SRv6 LocalSID function. + :param interface: Interface name (Optional, required for + L2/L3 xconnects). + :param next_hop: Next hop IPv4/IPv6 address (Optional, required for L3 + xconnects). + :param fib_table: FIB table for IPv4/IPv6 lookup (Optional, required for + L3 routing). + :type node: dict + :type local_sid: str + :type behavior: str + :type interface: str + :type next_hop: int + :type fib_table: str + :raises ValueError: If unsupported SRv6 LocalSID function used or + required parameter is missing. + """ + if behavior == SRv6Behaviour.END: + params = '' + elif behavior in [SRv6Behaviour.END_X, SRv6Behaviour.END_DX4, + SRv6Behaviour.END_DX6]: + if interface is None or next_hop is None: + raise ValueError('Required data missing.\ninterface:{0}\n' + 'next_hop:{1}'.format(interface, next_hop)) + interface_name = Topology.get_interface_name(node, interface) + params = '{0} {1}'.format(interface_name, next_hop) + elif behavior == SRv6Behaviour.END_DX2: + if interface is None: + raise ValueError('Required data missing.\ninterface:{0}\n'. + format(interface)) + params = '{0}'.format(interface) + elif behavior in [SRv6Behaviour.END_DT4, SRv6Behaviour.END_DT6]: + if fib_table is None: + raise ValueError('Required data missing.\nfib_table:{0}\n'. + format(fib_table)) + params = '{0}'.format(fib_table) + else: + raise ValueError('Unsupported SRv6 LocalSID function: {0}'. + format(behavior)) + + with VatTerminal(node) as vat: + resp = vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_localsid_add.vat', local_sid=local_sid, + behavior=behavior, params=params) + + VatJsonUtil.verify_vat_retval( + resp[0], + err_msg='Create SRv6 LocalSID {0} failed on node {1}'.format( + local_sid, node['host'])) + + @staticmethod + def delete_sr_localsid(node, local_sid): + """Delete SRv6 LocalSID on the given node. + + :param node: Given node to delete localSID on. + :param local_sid: LocalSID IPv6 address. + :type node: dict + :type local_sid: str + """ + with VatTerminal(node) as vat: + resp = vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_localsid_del.vat', local_sid=local_sid) + + VatJsonUtil.verify_vat_retval( + resp[0], + err_msg='Delete SRv6 LocalSID {0} failed on node {1}'.format( + local_sid, node['host'])) + + @staticmethod + def show_sr_localsids(node): + """Show SRv6 LocalSIDs on the given node. + + :param node: Given node to show localSIDs on. + :type node: dict + """ + with VatTerminal(node) as vat: + vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_localsids_show.vat') + + @staticmethod + def configure_sr_policy(node, bsid, sid_list, mode='encap'): + """Create SRv6 policy on the given node. + + :param node: Given node to create SRv6 policy on. + :param bsid: BindingSID - local SID IPv6 address. + :param sid_list: SID list. + :param mode: Encapsulation / insertion mode. + :type node: dict + :type bsid: str + :type sid_list: list + :type mode: str + """ + sid_conf = 'next ' + ' next '.join(sid_list) + + with VatTerminal(node) as vat: + resp = vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_policy_add.vat', bsid=bsid, + sid_conf=sid_conf, mode=mode) + + VatJsonUtil.verify_vat_retval( + resp[0], + err_msg='Create SRv6 policy for BindingSID {0} failed on node ' + '{1}'.format(bsid, node['host'])) + + @staticmethod + def delete_sr_policy(node, bsid): + """Delete SRv6 policy on the given node. + + :param node: Given node to delete SRv6 policy on. + :param bsid: BindingSID IPv6 address. + :type node: dict + :type bsid: str + """ + with VatTerminal(node) as vat: + resp = vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_policy_del.vat', bsid=bsid) + + VatJsonUtil.verify_vat_retval( + resp[0], + err_msg='Delete SRv6 policy for BindingSID {0} failed on node ' + '{1}'.format(bsid, node['host'])) + + @staticmethod + def show_sr_policies(node): + """Show SRv6 policies on the given node. + + :param node: Given node to show SRv6 policies on. + :type node: dict + """ + with VatTerminal(node, json_param=False) as vat: + vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_policies_show.vat') + + @staticmethod + def configure_sr_steer(node, mode, bsid, interface=None, ip_addr=None, + mask=None): + """Create SRv6 steering policy on the given node. + + :param node: Given node to create steering policy on. + :param mode: Mode of operation - L2 or L3. + :param bsid: BindingSID - local SID IPv6 address. + :param interface: Interface name (Optional, required in case of + L2 mode). + :param ip_addr: IPv4/IPv6 address (Optional, required in case of L3 + mode). + :param mask: IP address mask (Optional, required in case of L3 mode). + :type node: dict + :type mode: str + :type bsid: str + :type interface: str + :type ip_addr: int + :type mask: int + :raises ValueError: If unsupported mode used or required parameter + is missing. + """ + if mode == 'l2': + if interface is None: + raise ValueError('Required data missing.\ninterface:{0}\n'. + format(interface)) + interface_name = Topology.get_interface_name(node, interface) + params = 'l2 {0}'.format(interface_name) + elif mode == 'l3': + if ip_addr is None or mask is None: + raise ValueError('Required data missing.\nIP address:{0}\n' + 'mask:{1}'.format(ip_addr, mask)) + params = '{0}/{1}'.format(ip_addr, mask) + else: + raise ValueError('Unsupported mode: {0}'.format(mode)) + + with VatTerminal(node) as vat: + resp = vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_steer_add_del.vat', params=params, bsid=bsid) + + VatJsonUtil.verify_vat_retval( + resp[0], + err_msg='Create SRv6 steering policy for BindingSID {0} failed on ' + 'node {1}'.format(bsid, node['host'])) + + @staticmethod + def delete_sr_steer(node, mode, bsid, interface=None, ip_addr=None, + mask=None): + """Delete SRv6 steering policy on the given node. + + :param node: Given node to delete steering policy on. + :param mode: Mode of operation - L2 or L3. + :param bsid: BindingSID - local SID IPv6 address. + :param interface: Interface name (Optional, required in case of + L2 mode). + :param ip_addr: IPv4/IPv6 address (Optional, required in case of L3 + mode). + :param mask: IP address mask (Optional, required in case of L3 mode). + :type node: dict + :type mode: str + :type bsid: str + :type interface: str + :type ip_addr: int + :type mask: int + :raises ValueError: If unsupported mode used or required parameter + is missing. + """ + params = 'del' + if mode == 'l2': + if interface is None: + raise ValueError('Required data missing.\ninterface:{0}\n'. + format(interface)) + interface_name = Topology.get_interface_name(node, interface) + params += 'l2 {0}'.format(interface_name) + elif mode == 'l3': + if ip_addr is None or mask is None: + raise ValueError('Required data missing.\nIP address:{0}\n' + 'mask:{1}'.format(ip_addr, mask)) + params += '{0}/{1}'.format(ip_addr, mask) + else: + raise ValueError('Unsupported mode: {0}'.format(mode)) + + with VatTerminal(node) as vat: + resp = vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_steer_add_del.vat', params=params, bsid=bsid) + + VatJsonUtil.verify_vat_retval( + resp[0], + err_msg='Delete SRv6 policy for bsid {0} failed on node {1}'.format( + bsid, node['host'])) + + @staticmethod + def show_sr_steering_policies(node): + """Show SRv6 steering policies on the given node. + + :param node: Given node to show SRv6 steering policies on. + :type node: dict + """ + with VatTerminal(node, json_param=False) as vat: + vat.vat_terminal_exec_cmd_from_template( + 'srv6/sr_steer_policies_show.vat') diff --git a/resources/templates/vat/srv6/sr_localsid_add.vat b/resources/templates/vat/srv6/sr_localsid_add.vat new file mode 100644 index 0000000000..1b43ad4409 --- /dev/null +++ b/resources/templates/vat/srv6/sr_localsid_add.vat @@ -0,0 +1 @@ +exec sr localsid address {local_sid} behavior {behavior} {params} \ No newline at end of file diff --git a/resources/templates/vat/srv6/sr_localsid_del.vat b/resources/templates/vat/srv6/sr_localsid_del.vat new file mode 100644 index 0000000000..0adf4a19fb --- /dev/null +++ b/resources/templates/vat/srv6/sr_localsid_del.vat @@ -0,0 +1 @@ +exec sr localsid del address {local_sid} \ No newline at end of file diff --git a/resources/templates/vat/srv6/sr_localsids_show.vat b/resources/templates/vat/srv6/sr_localsids_show.vat new file mode 100644 index 0000000000..8ab09381cc --- /dev/null +++ b/resources/templates/vat/srv6/sr_localsids_show.vat @@ -0,0 +1 @@ +exec show sr localsids \ No newline at end of file diff --git a/resources/templates/vat/srv6/sr_policies_show.vat b/resources/templates/vat/srv6/sr_policies_show.vat new file mode 100644 index 0000000000..ead5a29f46 --- /dev/null +++ b/resources/templates/vat/srv6/sr_policies_show.vat @@ -0,0 +1 @@ +exec show sr policies \ No newline at end of file diff --git a/resources/templates/vat/srv6/sr_policy_add.vat b/resources/templates/vat/srv6/sr_policy_add.vat new file mode 100644 index 0000000000..befec9f371 --- /dev/null +++ b/resources/templates/vat/srv6/sr_policy_add.vat @@ -0,0 +1 @@ +exec sr policy add bsid {bsid} {sid_conf} {mode} \ No newline at end of file diff --git a/resources/templates/vat/srv6/sr_policy_del.vat b/resources/templates/vat/srv6/sr_policy_del.vat new file mode 100644 index 0000000000..a1aaff038d --- /dev/null +++ b/resources/templates/vat/srv6/sr_policy_del.vat @@ -0,0 +1 @@ +exec sr policy del bsid {bsid} \ No newline at end of file diff --git a/resources/templates/vat/srv6/sr_steer_add_del.vat b/resources/templates/vat/srv6/sr_steer_add_del.vat new file mode 100644 index 0000000000..19591f7523 --- /dev/null +++ b/resources/templates/vat/srv6/sr_steer_add_del.vat @@ -0,0 +1 @@ +exec sr steer {params} via sr policy bsid {bsid} \ No newline at end of file diff --git a/resources/templates/vat/srv6/sr_steer_policies_show.vat b/resources/templates/vat/srv6/sr_steer_policies_show.vat new file mode 100644 index 0000000000..af4f783082 --- /dev/null +++ b/resources/templates/vat/srv6/sr_steer_policies_show.vat @@ -0,0 +1 @@ +exec show sr steering policies \ No newline at end of file -- 2.16.6