Exemple #1
0
    def create_eid(eid, prefix_len):
        """Create lisp eid object.

        :param eid: Eid value.
        :param prefix_len: Prefix len if the eid is IP address.
        :type eid: str
        :type prefix_len: int
        """
        eid_addr = dict(prefix=IPUtil.create_prefix_object(
            ip_address(eid), prefix_len)) if prefix_len else dict(mac=str(eid))

        return dict(type=getattr(EidType,
                                 u"PREFIX" if prefix_len else u"MAC").value,
                    address=eid_addr)
Exemple #2
0
    def _get_sr_steer_policy_args(node,
                                  mode,
                                  interface=None,
                                  ip_addr=None,
                                  prefix=None):
        """Return values of sw_if_index, mask_width, prefix_addr and
            traffic_type for sr_steering_add_del API.

        :param node: Given node to create/delete steering policy on.
        :param mode: Mode of operation - L2 or L3.
        :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 prefix: IP address prefix (Optional, required in case of L3
            mode).
        :type node: dict
        :type mode: str
        :type interface: str
        :type ip_addr: str
        :type prefix: int
        :returns: Values for sw_if_index, prefix and traffic_type
        :rtype: tuple
        :raises ValueError: If unsupported mode used or required parameter
            is missing.
        """
        if mode.lower() == u"l2":
            if interface is None:
                raise ValueError(f"Required data missing.\n"
                                 f"interface: {interface}")
            sw_if_index = InterfaceUtil.get_interface_index(node, interface)
            prefix = 0
            traffic_type = getattr(SRv6PolicySteeringTypes,
                                   u"SR_STEER_L2").value
        elif mode.lower() == u"l3":
            if ip_addr is None or prefix is None:
                raise ValueError(f"Required data missing.\n"
                                 f"IP address:{ip_addr}\n"
                                 f"mask:{prefix}")
            sw_if_index = Constants.BITWISE_NON_ZERO
            ip_addr = ip_address(ip_addr)
            prefix = IPUtil.create_prefix_object(ip_addr, int(prefix))
            traffic_type = getattr(
                SRv6PolicySteeringTypes,
                u"SR_STEER_IPV4").value if ip_addr.version == 4 else getattr(
                    SRv6PolicySteeringTypes, u"SR_STEER_IPV6").value
        else:
            raise ValueError(f"Unsupported mode: {mode}")

        return sw_if_index, prefix, traffic_type
Exemple #3
0
    def vpp_all_ra_suppress_link_layer(nodes):
        """Suppress ICMPv6 router advertisement message for link scope address
        on all VPP nodes in the topology.

        :param nodes: Nodes of the test topology.
        :type nodes: dict
        """
        for node in nodes.values():
            if node[u"type"] == NodeType.TG:
                continue
            for port_k in node[u"interfaces"].keys():
                ip6_addr_list = IPUtil.vpp_get_interface_ip_addresses(
                    node, port_k, u"ipv6")
                if ip6_addr_list:
                    IPv6Util.vpp_ra_suppress_link_layer(node, port_k)
Exemple #4
0
    def vpp_interfaces_ra_suppress_on_all_nodes(nodes):
        """Disable sending ICMPv6 router-advertisement messages on all
        IPv6 enabled interfaces on all VPP nodes in the topology.

        :param nodes: Nodes of the test topology.
        :type nodes: dict
        """
        for node in nodes.values():
            if node[u"type"] == NodeType.TG:
                continue
            for port_k in node[u"interfaces"].keys():
                ip6_addr_list = IPUtil.vpp_get_interface_ip_addresses(
                    node, port_k, u"ipv6")
                if ip6_addr_list:
                    IPv6Util.vpp_interface_ra_suppress(node, port_k)
Exemple #5
0
    def add_macip_acl_multi_entries(node, rules=u""):
        """Add a new MACIP ACL.

        :param node: VPP node to set MACIP ACL on.
        :param rules: Required MACIP rules.
        :type node: dict
        :type rules: str
        """
        reg_ex_ip = re.compile(r"(ip [0-9a-fA-F.:/\d{1,2}]*)")
        reg_ex_mac = re.compile(r"(mac \S\S:\S\S:\S\S:\S\S:\S\S:\S\S)")
        reg_ex_mask = re.compile(r"(mask \S\S:\S\S:\S\S:\S\S:\S\S:\S\S)")

        acl_rules = list()
        for rule in rules.split(u", "):
            acl_rule = dict(is_permit=2 if u"permit+reflect" in rule else
                            1 if u"permit" in rule else 0,
                            src_mac=6 * b'0',
                            src_mac_mask=6 * b'0',
                            prefix=0)

            groups = re.search(reg_ex_mac, rule)
            if groups:
                mac = groups.group(1).split(u" ")[1].replace(u":", u"")
                acl_rule[u"src_mac"] = bytes.fromhex(mac)

            groups = re.search(reg_ex_mask, rule)
            if groups:
                mask = groups.group(1).split(u" ")[1].replace(u":", u"")
                acl_rule[u"src_mac_mask"] = bytes.fromhex(mask)

            groups = re.search(reg_ex_ip, rule)
            if groups:
                grp = groups.group(1).split(u" ")[1].split(u"/")
                acl_rule[u"src_prefix"] = IPUtil.create_prefix_object(
                    ip_address((grp[0])), int(grp[1]))

            acl_rules.append(acl_rule)

        Classify._macip_acl_add(node=node, rules=acl_rules)
Exemple #6
0
    def vpp_create_vxlan_and_vlan_interfaces(
            node, node_vxlan_if, node_vlan_if, vxlan_count, vni_start,
            src_ip_start, dst_ip_start, ip_step):
        """
        Configure IPs, create VXLAN interfaces and VLAN sub-interfaces on VPP
        node.

        :param node: VPP node.
        :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
            interfaces.
        :param node_vlan_if: VPP node interface key to create VLAN
            sub-interface.
        :param vxlan_count: Number of tunnel interfaces to create.
        :param vni_start: VNI start ID.
        :param src_ip_start: VXLAN tunnel source IP address start.
        :param dst_ip_start: VXLAN tunnel destination IP address start.
        :param ip_step: IP address incremental step.
        :type node: dict
        :type node_vxlan_if: str
        :type node_vlan_if: str
        :type vxlan_count: int
        :type vni_start: int
        :type src_ip_start: str
        :type dst_ip_start: str
        :type ip_step: int
        :returns: Number of created VXLAN interfaces.
        :rtype: int
        """
        src_ip_start = ip_address(src_ip_start)
        dst_ip_start = ip_address(dst_ip_start)

        if vxlan_count > 10:
            commands = list()
            for i in range(0, vxlan_count):
                try:
                    src_ip = src_ip_start + i * ip_step
                    dst_ip = dst_ip_start + i * ip_step
                except AddressValueError:
                    logger.warn(
                        u"Can't do more iterations - IP address limit "
                        u"has been reached."
                    )
                    vxlan_count = i
                    break
                commands.append(
                    f"sw_interface_add_del_address sw_if_index "
                    f"{Topology.get_interface_sw_index(node, node_vxlan_if)} "
                    f"{src_ip}/{128 if src_ip.version == 6 else 32}\n"
                )
                commands.append(
                    f"vxlan_add_del_tunnel src {src_ip} dst {dst_ip} "
                    f"vni {vni_start + i}\n"
                )
                commands.append(
                    f"create_vlan_subif sw_if_index "
                    f"{Topology.get_interface_sw_index(node, node_vlan_if)} "
                    f"vlan {i + 1}\n"
                )
            VatExecutor().write_and_execute_script(
                node, u"/tmp/create_vxlan_interfaces.config", commands
            )
            return vxlan_count

        cmd1 = u"sw_interface_add_del_address"
        args1 = dict(
            sw_if_index=InterfaceUtil.get_interface_index(node, node_vxlan_if),
            is_add=True,
            del_all=False,
            prefix=None
        )
        cmd2 = u"vxlan_add_del_tunnel_v3"
        args2 = dict(
            is_add=True,
            instance=Constants.BITWISE_NON_ZERO,
            src_address=None,
            dst_address=None,
            mcast_sw_if_index=Constants.BITWISE_NON_ZERO,
            encap_vrf_id=0,
            decap_next_index=Constants.BITWISE_NON_ZERO,
            vni=None
        )
        cmd3 = u"create_vlan_subif"
        args3 = dict(
            sw_if_index=InterfaceUtil.get_interface_index(
                node, node_vlan_if),
            vlan_id=None
        )

        with PapiSocketExecutor(node) as papi_exec:
            for i in range(0, vxlan_count):
                try:
                    src_ip = src_ip_start + i * ip_step
                    dst_ip = dst_ip_start + i * ip_step
                except AddressValueError:
                    logger.warn(
                        u"Can't do more iterations - IP address limit "
                        u"has been reached."
                    )
                    vxlan_count = i
                    break
                args1[u"prefix"] = IPUtil.create_prefix_object(
                    src_ip, 128 if src_ip_start.version == 6 else 32
                )
                args2[u"src_address"] = IPAddress.create_ip_address_object(
                    src_ip
                )
                args2[u"dst_address"] = IPAddress.create_ip_address_object(
                    dst_ip
                )
                args2[u"vni"] = int(vni_start) + i
                args3[u"vlan_id"] = i + 1
                history = bool(not 1 < i < vxlan_count - 1)
                papi_exec.add(cmd1, history=history, **args1).\
                    add(cmd2, history=history, **args2).\
                    add(cmd3, history=history, **args3)
            papi_exec.get_replies()

        return vxlan_count
Exemple #7
0
    def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
            node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
            ip_step, bd_id_start):
        """
        Configure ARPs and routes for VXLAN interfaces and put each pair of
        VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.

        :param node: VPP node.
        :param node_vxlan_if: VPP node interface key where VXLAN tunnel
            interfaces have been created.
        :param vxlan_count: Number of tunnel interfaces.
        :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
        :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
            interfaces.
        :param dst_ip_start: VXLAN tunnel destination IP address start.
        :param ip_step: IP address incremental step.
        :param bd_id_start: Bridge-domain ID start.
        :type node: dict
        :type node_vxlan_if: str
        :type vxlan_count: int
        :type op_node: dict
        :type op_node_if:
        :type dst_ip_start: str
        :type ip_step: int
        :type bd_id_start: int
        """
        dst_ip_start = ip_address(dst_ip_start)

        if vxlan_count > 1:
            idx_vxlan_if = Topology.get_interface_sw_index(node, node_vxlan_if)
            commands = list()
            for i in range(0, vxlan_count):
                dst_ip = dst_ip_start + i * ip_step
                commands.append(
                    f"exec ip neighbor "
                    f"{Topology.get_interface_name(node, node_vxlan_if)} "
                    f"{dst_ip} "
                    f"{Topology.get_interface_mac(op_node, op_node_if)} static "
                    f"\n"
                )
                commands.append(
                    f"ip_route_add_del "
                    f"{dst_ip}/{128 if dst_ip.version == 6 else 32} count 1 "
                    f"via {dst_ip} sw_if_index {idx_vxlan_if}\n"
                )
                sw_idx_vxlan = Topology.get_interface_sw_index(
                    node, f"vxlan_tunnel{i + 1}"
                )
                commands.append(
                    f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vxlan} "
                    f"bd_id {bd_id_start + i} shg 0 enable\n"
                )
                sw_idx_vlan = Topology.get_interface_sw_index(
                    node, f"vlan_subif{i + 1}"
                )
                commands.append(
                    f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vlan} "
                    f"bd_id {bd_id_start + i} shg 0 enable\n"
                )
            VatExecutor().write_and_execute_script(
                node, u"/tmp/configure_routes_and_bridge_domains.config",
                commands
            )
            return

        cmd1 = u"ip_neighbor_add_del"
        neighbor = dict(
            sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
            flags=0,
            mac_address=Topology.get_interface_mac(op_node, op_node_if),
            ip_address=u""
        )
        args1 = dict(
            is_add=1,
            neighbor=neighbor
        )
        cmd2 = u"ip_route_add_del"
        kwargs = dict(
            interface=node_vxlan_if,
            gateway=str(dst_ip_start)
        )
        route = IPUtil.compose_vpp_route_structure(
            node, str(dst_ip_start),
            128 if dst_ip_start.version == 6 else 32, **kwargs
        )
        args2 = dict(
            is_add=1,
            is_multipath=0,
            route=route
        )
        cmd3 = u"sw_interface_set_l2_bridge"
        args3 = dict(
            rx_sw_if_index=None,
            bd_id=None,
            shg=0,
            port_type=0,
            enable=1
        )
        args4 = dict(
            rx_sw_if_index=None,
            bd_id=None,
            shg=0,
            port_type=0,
            enable=1
        )

        with PapiSocketExecutor(node) as papi_exec:
            for i in range(0, vxlan_count):
                args1[u"neighbor"][u"ip_address"] = \
                    str(dst_ip_start + i * ip_step)
                args2[u"route"][u"prefix"][u"address"][u"un"] = \
                    IPAddress.union_addr(dst_ip_start + i * ip_step)
                args2[u"route"][u"paths"][0][u"nh"][u"address"] = \
                    IPAddress.union_addr(dst_ip_start + i * ip_step)
                args3[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
                    node, f"vxlan_tunnel{i+1}"
                )
                args3[u"bd_id"] = int(bd_id_start+i)
                args4[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
                    node, f"vlan_subif{i+1}"
                )
                args4[u"bd_id"] = int(bd_id_start+i)
                history = bool(not 1 < i < vxlan_count - 1)
                papi_exec.add(cmd1, history=history, **args1). \
                    add(cmd2, history=history, **args2). \
                    add(cmd3, history=history, **args3). \
                    add(cmd3, history=history, **args4)
            papi_exec.get_replies()
Exemple #8
0
    def add_replace_acl_multi_entries(node, acl_idx=None, rules=None, tag=u""):
        """Add a new ACL or replace the existing one. To replace an existing
        ACL, pass the ID of this ACL.

        :param node: VPP node to set ACL on.
        :param acl_idx: ID of ACL. (Optional)
        :param rules: Required rules. (Optional)
        :param tag: ACL tag (Optional).
        :type node: dict
        :type acl_idx: int
        :type rules: str
        :type tag: str
        """
        reg_ex_src_ip = re.compile(r"(src [0-9a-fA-F.:/\d{1,2}]*)")
        reg_ex_dst_ip = re.compile(r"(dst [0-9a-fA-F.:/\d{1,2}]*)")
        reg_ex_sport = re.compile(r"(sport \d{1,5})")
        reg_ex_dport = re.compile(r"(dport \d{1,5})")
        reg_ex_proto = re.compile(r"(proto \d{1,5})")

        acl_rules = list()
        for rule in rules.split(u", "):
            acl_rule = dict(is_permit=2 if u"permit+reflect" in rule else
                            1 if u"permit" in rule else 0,
                            src_prefix=0,
                            dst_prefix=0,
                            proto=0,
                            srcport_or_icmptype_first=0,
                            srcport_or_icmptype_last=65535,
                            dstport_or_icmpcode_first=0,
                            dstport_or_icmpcode_last=65535,
                            tcp_flags_mask=0,
                            tcp_flags_value=0)

            groups = re.search(reg_ex_src_ip, rule)
            if groups:
                grp = groups.group(1).split(u" ")[1].split(u"/")
                acl_rule[u"src_prefix"] = IPUtil.create_prefix_object(
                    ip_address(grp[0]), int(grp[1]))

            groups = re.search(reg_ex_dst_ip, rule)
            if groups:
                grp = groups.group(1).split(u" ")[1].split(u"/")
                acl_rule[u"dst_prefix"] = IPUtil.create_prefix_object(
                    ip_address(grp[0]), int(grp[1]))

            groups = re.search(reg_ex_sport, rule)
            if groups:
                port = int(groups.group(1).split(u" ")[1])
                acl_rule[u"srcport_or_icmptype_first"] = port
                acl_rule[u"srcport_or_icmptype_last"] = port

            groups = re.search(reg_ex_dport, rule)
            if groups:
                port = int(groups.group(1).split(u" ")[1])
                acl_rule[u"dstport_or_icmpcode_first"] = port
                acl_rule[u"dstport_or_icmpcode_last"] = port

            groups = re.search(reg_ex_proto, rule)
            if groups:
                proto = int(groups.group(1).split(' ')[1])
                acl_rule[u"proto"] = proto

            acl_rules.append(acl_rule)

        Classify._acl_add_replace(node,
                                  acl_idx=acl_idx,
                                  rules=acl_rules,
                                  tag=tag)
Exemple #9
0
    def initialize_iperf_server(self,
                                node,
                                pf_key,
                                interface,
                                bind,
                                bind_gw,
                                bind_mask,
                                namespace=None,
                                cpu_skip_cnt=0,
                                cpu_cnt=1,
                                instances=1):
        """iPerf3 initialization.

        :param node: Topology node running iPerf3 server.
        :param pf_key: First TG's interface (To compute numa location).
        :param interface: Name of TG bind interface.
        :param bind: Bind to host, one of node's addresses.
        :param bind_gw: Bind gateway (required for default route).
        :param bind_mask: Bind address mask.
        :param namespace: Name of TG namespace to execute.
        :param cpu_skip_cnt: Amount of CPU cores to skip.
        :param cpu_cnt: iPerf3 main thread count.
        :param instances: Number of simultaneous iPerf3 instances.
        :type node: dict
        :type pf_key: str
        :type interface: str
        :type bind: str
        :type bind_gw: str
        :type bind_mask: str
        :type namespace: str
        :type cpu_skip_cnt: int
        :type cpu_cnt: int
        :type instances: int
        """
        if Iperf3.is_iperf_running(node):
            Iperf3.teardown_iperf(node)

        if namespace:
            IPUtil.set_linux_interface_ip(node,
                                          interface=interface,
                                          ip_addr=bind,
                                          prefix=bind_mask,
                                          namespace=namespace)
            IPUtil.set_linux_interface_up(node,
                                          interface=interface,
                                          namespace=namespace)
            Namespaces.add_default_route_to_namespace(node,
                                                      namespace=namespace,
                                                      default_route=bind_gw)

        # Compute affinity for iPerf server.
        self._s_affinity = CpuUtils.get_affinity_iperf(
            node,
            pf_key,
            cpu_skip_cnt=cpu_skip_cnt,
            cpu_cnt=cpu_cnt * instances)
        # Compute affinity for iPerf client.
        self._c_affinity = CpuUtils.get_affinity_iperf(
            node,
            pf_key,
            cpu_skip_cnt=cpu_skip_cnt + cpu_cnt * instances,
            cpu_cnt=cpu_cnt * instances)

        for i in range(0, instances):
            Iperf3.start_iperf_server(node,
                                      namespace=namespace,
                                      port=5201 + i,
                                      affinity=self._s_affinity)
Exemple #10
0
    def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
            node, node_vxlan_if, vxlan_count, op_node, op_node_if,
            dst_ip_start, ip_step, bd_id_start):
        """
        Configure ARPs and routes for VXLAN interfaces and put each pair of
        VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.

        :param node: VPP node.
        :param node_vxlan_if: VPP node interface key where VXLAN tunnel
            interfaces have been created.
        :param vxlan_count: Number of tunnel interfaces.
        :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
        :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
            interfaces.
        :param dst_ip_start: VXLAN tunnel destination IP address start.
        :param ip_step: IP address incremental step.
        :param bd_id_start: Bridge-domain ID start.
        :type node: dict
        :type node_vxlan_if: str
        :type vxlan_count: int
        :type op_node: dict
        :type op_node_if:
        :type dst_ip_start: str
        :type ip_step: int
        :type bd_id_start: int
        """
        dst_ip_addr_start = ip_address(unicode(dst_ip_start))

        if vxlan_count > 1:
            sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
            tmp_fn = '/tmp/configure_routes_and_bridge_domains.config'
            commands = list()
            for i in xrange(0, vxlan_count):
                dst_ip = dst_ip_addr_start + i * ip_step
                commands.append(
                    'ip_neighbor_add_del sw_if_index {sw_idx} dst {ip} '
                    'mac {mac}\n'.format(sw_idx=sw_idx_vxlan,
                                         ip=dst_ip,
                                         mac=Topology.get_interface_mac(
                                             op_node, op_node_if)))
                commands.append(
                    'ip_route_add_del {ip}/{ip_len} count 1 via {ip} '
                    'sw_if_index {sw_idx}\n'.format(
                        ip=dst_ip,
                        ip_len=128 if dst_ip.version == 6 else 32,
                        sw_idx=sw_idx_vxlan))
                commands.append(
                    'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
                    'bd_id {bd_id} shg 0 enable\n'.format(
                        sw_idx=Topology.get_interface_sw_index(
                            node, 'vxlan_tunnel{nr}'.format(nr=i + 1)),
                        bd_id=bd_id_start + i))
                commands.append(
                    'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
                    'bd_id {bd_id} shg 0 enable\n'.format(
                        sw_idx=Topology.get_interface_sw_index(
                            node, 'vlan_subif{nr}'.format(nr=i + 1)),
                        bd_id=bd_id_start + i))
            VatExecutor().write_and_execute_script(node, tmp_fn, commands)
            return

        cmd1 = 'ip_neighbor_add_del'
        neighbor = dict(
            sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
            flags=0,
            mac_address=Topology.get_interface_mac(op_node, op_node_if),
            ip_address='')
        args1 = dict(is_add=1, neighbor=neighbor)
        cmd2 = 'ip_route_add_del'
        kwargs = dict(interface=node_vxlan_if, gateway=str(dst_ip_addr_start))
        route = IPUtil.compose_vpp_route_structure(
            node, str(dst_ip_addr_start),
            128 if dst_ip_addr_start.version == 6 else 32, **kwargs)
        args2 = dict(is_add=1, is_multipath=0, route=route)
        cmd3 = 'sw_interface_set_l2_bridge'
        args3 = dict(rx_sw_if_index=None,
                     bd_id=None,
                     shg=0,
                     port_type=0,
                     enable=1)
        args4 = dict(rx_sw_if_index=None,
                     bd_id=None,
                     shg=0,
                     port_type=0,
                     enable=1)
        err_msg = 'Failed to put VXLAN and VLAN interfaces to bridge domain ' \
                  'on host {host}'.format(host=node['host'])

        with PapiExecutor(node) as papi_exec:
            for i in xrange(0, vxlan_count):
                dst_ip = dst_ip_addr_start + i * ip_step
                args1['neighbor']['ip_address'] = str(dst_ip)
                args2['route']['prefix']['address']['un'] = \
                    IPUtil.union_addr(dst_ip)
                args2['route']['paths'][0]['nh']['address'] = \
                    IPUtil.union_addr(dst_ip)
                args3['rx_sw_if_index'] = Topology.get_interface_sw_index(
                    node, 'vxlan_tunnel{nr}'.format(nr=i + 1))
                args3['bd_id'] = int(bd_id_start + i)
                args4['rx_sw_if_index'] = Topology.get_interface_sw_index(
                    node, 'vlan_subif{nr}'.format(nr=i + 1))
                args4['bd_id'] = int(bd_id_start + i)
                history = False if 1 < i < vxlan_count else True
                papi_exec.add(cmd1, history=history, **args1). \
                    add(cmd2, history=history, **args2). \
                    add(cmd3, history=history, **args3). \
                    add(cmd3, history=history, **args4)
                if i > 0 and i % (Constants.PAPI_MAX_API_BULK / 4) == 0:
                    papi_exec.get_replies(err_msg)
            papi_exec.get_replies()