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']))
def vpp_ipsec_add_spd(node, spd_id): """Create Security Policy Database on the VPP node. :param node: VPP node to add SPD on. :param spd_id: SPD ID. :type node: dict :type spd_id: int """ out = VatExecutor.cmd_from_template(node, "ipsec/ipsec_spd_add.vat", spd_id=spd_id) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add SPD {0} failed on {1}'.format(spd_id, node['host']))
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']))
def vpp_ipsec_add_sad_entry(node, sad_id, spi, crypto_alg, crypto_key, integ_alg, integ_key, tunnel_src=None, tunnel_dst=None): """Create Security Association Database entry on the VPP node. :param node: VPP node to add SAD entry on. :param sad_id: SAD entry ID. :param spi: Security Parameter Index of this SAD entry. :param crypto_alg: The encryption algorithm name. :param crypto_key: The encryption key string. :param integ_alg: The integrity algorithm name. :param integ_key: The integrity key string. :param tunnel_src: Tunnel header source IPv4 or IPv6 address. If not specified ESP transport mode is used. :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address. If not specified ESP transport mode is used. :type node: dict :type sad_id: int :type spi: int :type crypto_alg: CryptoAlg :type crypto_key: str :type integ_alg: str :type integ_key: str :type tunnel_src: str :type tunnel_dst: str """ ckey = crypto_key.encode('hex') ikey = integ_key.encode('hex') tunnel = 'tunnel_src {0} tunnel_dst {1}'.format(tunnel_src, tunnel_dst)\ if tunnel_src is not None and tunnel_dst is not None else '' out = VatExecutor.cmd_from_template(node, "ipsec/ipsec_sad_add_entry.vat", sad_id=sad_id, spi=spi, calg=crypto_alg.alg_name, ckey=ckey, ialg=integ_alg.alg_name, ikey=ikey, tunnel=tunnel) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add SAD entry failed on {0}'.format(node['host']))
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']))
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']))
def vpp_ipsec_spd_add_if(node, spd_id, interface): """Add interface to the Security Policy Database. :param node: VPP node. :param spd_id: SPD ID to add interface on. :param interface: Interface name or sw_if_index. :type node: dict :type spd_id: int :type interface: str or int """ sw_if_index = Topology.get_interface_sw_index(node, interface)\ if isinstance(interface, basestring) else interface out = VatExecutor.cmd_from_template(node, "ipsec/ipsec_interface_add_spd.vat", spd_id=spd_id, sw_if_id=sw_if_index) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add interface {0} to SPD {1} failed on {2}'.format( interface, spd_id, node['host']))
def vpp_ipsec_sa_set_key(node, sa_id, crypto_key, integ_key): """Update Security Association (SA) keys. :param node: VPP node to update SA keys. :param sa_id: SAD entry ID. :param crypto_key: The encryption key string. :param integ_key: The integrity key string. :type node: dict :type sa_id: int :type crypto_key: str :type integ_key: str """ ckey = crypto_key.encode('hex') ikey = integ_key.encode('hex') out = VatExecutor.cmd_from_template(node, "ipsec/ipsec_sa_set_key.vat", sa_id=sa_id, ckey=ckey, ikey=ikey) VatJsonUtil.verify_vat_retval( out[0], err_msg='Update SA key failed on {0}'.format(node['host']))
def vpp_ipsec_spd_add_entry(node, spd_id, priority, action, inbound=True, sa_id=None, laddr_range=None, raddr_range=None, proto=None, lport_range=None, rport_range=None): """Create Security Policy Database entry on the VPP node. :param node: VPP node to add SPD entry on. :param spd_id: SPD ID to add entry on. :param priority: SPD entry priority, higher number = higher priority. :param action: Policy action. :param inbound: If True policy is for inbound traffic, otherwise outbound. :param sa_id: SAD entry ID for protect action. :param laddr_range: Policy selector local IPv4 or IPv6 address range in format IP/prefix or IP/mask. If no mask is provided, it's considered to be /32. :param raddr_range: Policy selector remote IPv4 or IPv6 address range in format IP/prefix or IP/mask. If no mask is provided, it's considered to be /32. :param proto: Policy selector next layer protocol number. :param lport_range: Policy selector local TCP/UDP port range in format <port_start>-<port_end>. :param rport_range: Policy selector remote TCP/UDP port range in format <port_start>-<port_end>. :type node: dict :type spd_id: int :type priority: int :type action: PolicyAction :type inbound: bool :type sa_id: int :type laddr_range: string :type raddr_range: string :type proto: int :type lport_range: string :type rport_range: string """ direction = 'inbound' if inbound else 'outbound' act_str = action.value if PolicyAction.PROTECT == action and sa_id is not None: act_str += 'sa_id {0}'.format(sa_id) selector = '' if laddr_range is not None: net = ip_network(unicode(laddr_range), strict=False) selector += 'laddr_start {0} laddr_stop {1} '.format( net.network_address, net.broadcast_address) if raddr_range is not None: net = ip_network(unicode(raddr_range), strict=False) selector += 'raddr_start {0} raddr_stop {1} '.format( net.network_address, net.broadcast_address) if proto is not None: selector += 'protocol {0} '.format(proto) if lport_range is not None: selector += 'lport_start {p[0]} lport_stop {p[1]} '.format( p=lport_range.split('-')) if rport_range is not None: selector += 'rport_start {p[0]} rport_stop {p[1]} '.format( p=rport_range.split('-')) out = VatExecutor.cmd_from_template(node, "ipsec/ipsec_spd_add_entry.vat", spd_id=spd_id, priority=priority, action=act_str, direction=direction, selector=selector) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add entry to SPD {0} failed on {1}'.format( spd_id, node['host']))
def vpp_ipsec_policy_add(node, spd_id, priority, action, inbound=True, sa_id=None, laddr_range=None, raddr_range=None, proto=None, lport_range=None, rport_range=None, is_ipv6=False): """Create Security Policy Database entry on the VPP node. :param node: VPP node to add SPD entry on. :param spd_id: SPD ID to add entry on. :param priority: SPD entry priority, higher number = higher priority. :param action: Policy action. :param inbound: If True policy is for inbound traffic, otherwise outbound. :param sa_id: SAD entry ID for protect action. :param laddr_range: Policy selector local IPv4 or IPv6 address range in format IP/prefix or IP/mask. If no mask is provided, it's considered to be /32. :param raddr_range: Policy selector remote IPv4 or IPv6 address range in format IP/prefix or IP/mask. If no mask is provided, it's considered to be /32. :param proto: Policy selector next layer protocol number. :param lport_range: Policy selector local TCP/UDP port range in format <port_start>-<port_end>. :param rport_range: Policy selector remote TCP/UDP port range in format <port_start>-<port_end>. :param is_ipv6: True in case of IPv6 policy when IPv6 address range is not defined so it will default to address ::/0, otherwise False. :type node: dict :type spd_id: int :type priority: int :type action: PolicyAction :type inbound: bool :type sa_id: int :type laddr_range: string :type raddr_range: string :type proto: int :type lport_range: string :type rport_range: string :type is_ipv6: bool """ direction = 'inbound' if inbound else 'outbound' if laddr_range is None and is_ipv6: laddr_range = '::/0' if raddr_range is None and is_ipv6: raddr_range = '::/0' act_str = action.value if PolicyAction.PROTECT == action and sa_id is not None: act_str += ' sa {0}'.format(sa_id) selector = '' if laddr_range is not None: net = ip_network(unicode(laddr_range), strict=False) selector += 'local-ip-range {0} - {1} '.format( net.network_address, net.broadcast_address) if raddr_range is not None: net = ip_network(unicode(raddr_range), strict=False) selector += 'remote-ip-range {0} - {1} '.format( net.network_address, net.broadcast_address) if proto is not None: selector += 'protocol {0} '.format(proto) if lport_range is not None: selector += 'local-port-range {0} '.format(lport_range) if rport_range is not None: selector += 'remote-port-range {0} '.format(rport_range) out = VatExecutor.cmd_from_template(node, 'ipsec/ipsec_policy_add.vat', json_param=False, spd_id=spd_id, priority=priority, action=act_str, direction=direction, selector=selector) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add IPsec policy ID {0} failed on {1}'.format( spd_id, node['host']))
def policer_set_configuration(self): """Configure policer on VPP node. ...note:: First set all required parameters. """ node = self._node # create policer color_aware = 'color-aware' if self._color_aware else '' # pylint: disable=no-member conform_action = self._conform_action.value if PolicerAction.MARK_AND_TRANSMIT == self._conform_action: conform_action += ' {0}'.format(self._conform_dscp.string) exceed_action = self._exceed_action.value if PolicerAction.MARK_AND_TRANSMIT == self._exceed_action: exceed_action += ' {0}'.format(self._exceed_dscp.string) violate_action = self._violate_action.value if PolicerAction.MARK_AND_TRANSMIT == self._violate_action: violate_action += ' {0}'.format(self._violate_dscp.string) out = VatExecutor.cmd_from_template(node, "policer/policer_add_3c.vat", name=self._policer_name, cir=self._cir, eir=self._eir, cb=self._cb, eb=self._eb, rate_type=self._rate_type.value, round_type=self._round_type.value, p_type=self._policer_type.value, conform_action=conform_action, exceed_action=exceed_action, violate_action=violate_action, color_aware=color_aware) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add policer {0} failed on {1}'.format(self._policer_name, node['host'])) policer_index = out[0].get('policer_index') # create classify table direction = 'src' if self._classify_match_is_src else 'dst' if ip_address(unicode(self._classify_match_ip)).version == 6: ip_version = 'ip6' table_type = PolicerClassifyTableType.IP6_TABLE else: ip_version = 'ip4' table_type = PolicerClassifyTableType.IP4_TABLE out = VatExecutor.cmd_from_template(node, "classify_add_table.vat", ip_version=ip_version, direction=direction) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add classify table failed on {0}'.format(node['host'])) new_table_index = out[0].get('new_table_index') skip_n_vectors = out[0].get('skip_n_vectors') match_n_vectors = out[0].get('match_n_vectors') # create classify session match = 'l3 {0} {1} {2}'.format(ip_version, direction, self._classify_match_ip) out = VatExecutor.cmd_from_template( node, "policer/policer_classify_add_session.vat", policer_index=policer_index, pre_color=self._classify_precolor.value, # pylint: disable=no-member table_index=new_table_index, skip_n=skip_n_vectors, match_n=match_n_vectors, match=match) VatJsonUtil.verify_vat_retval( out[0], err_msg='Add classify session failed on {0}'.format(node['host'])) # set classify interface out = VatExecutor.cmd_from_template( node, "policer/policer_classify_set_interface.vat", sw_if_index=self._sw_if_index, table_type=table_type.value, # pylint: disable=no-member table_index=new_table_index) VatJsonUtil.verify_vat_retval( out[0], err_msg='Set classify interface failed on {0}'.format(node['host']))
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']))