Пример #1
0
    def vpp_get_span_configuration_by_interface(node, dst_interface,
                                                ret_format="sw_if_index"):
        """Get a list of all interfaces currently being mirrored
        to the specified interface.

        :param node: DUT node.
        :param dst_interface: Name, sw_if_index or key of interface.
        :param ret_format: Optional. Desired format of returned interfaces.
        :type node: dict
        :type dst_interface: str or int
        :type ret_format: string
        :returns: List of SPAN source interfaces for the provided destination
            interface.
        :rtype: list
        """

        data = SPAN.vpp_get_span_configuration(node)

        dst_interface = Topology.convert_interface_reference(
            node, dst_interface, "sw_if_index")
        src_interfaces = []
        for item in data:
            if item["dst-if-index"] == dst_interface:
                src_interfaces.append(item["src-if-index"])

        if ret_format != "sw_if_index":
            src_interfaces = [
                Topology.convert_interface_reference(
                    node, interface, ret_format
                ) for interface in src_interfaces]

        return src_interfaces
Пример #2
0
    def add_locator(node, interface, locator_set, priority=1, weight=1):
        """Configure a new LISP locator set.

        :param node: Honeycomb node.
        :param interface: An interface on the node.
        :param locator_set: Name for the new locator set.
        :param priority: Priority parameter for the locator.
        :param weight. Weight parameter for the locator.
        :type node: dict
        :type interface: str
        :type locator_set: str
        :type priority: int
        :type weight: int
        :returns: Content of response.
        :rtype: bytearray
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")

        path = "/lisp-feature-data/locator-sets/locator-set" \
               "/{0}".format(locator_set)

        data = {
            "locator-set": {
                "name": locator_set,
                "interface": {
                    "interface-ref": interface,
                    "priority": priority,
                    "weight": weight
                }
            }
        }

        return LispKeywords._set_lisp_properties(node, path, data)
Пример #3
0
    def get_interface_slaac_oper_data(node, interface):
        """Get operational data about SLAAC table present on the node.

        :param node: Honeycomb node.
        :param interface: Interface SLAAC data are retrieved from.
        :type node: dict
        :type interface: str
        :returns: dict of SLAAC operational data.
        :rtype: dict
        :raises HoneycombError: If status code differs from successful.
        """
        interface = Topology.convert_interface_reference(
            node, interface, 'name')
        interface = interface.replace('/', '%2F')
        path = 'interface/' + interface

        status_code, resp = HcUtil.\
            get_honeycomb_data(node, "config_slaac", path)

        if status_code != HTTPCodes.OK:
            raise HoneycombError(
                "Not possible to get operational information about SLAAC. "
                "Status code: {0}.".format(status_code))
        try:
            dict_of_str = resp['interface'][0][
                'hc2vpp-ietf-ipv6-unicast-routing:ipv6-router-advertisements']
            return {k: str(v) for k, v in dict_of_str.items()}
        except (KeyError, TypeError):
            return {}
Пример #4
0
    def configure_interface_slaac(node, interface, slaac_data=None):
        """Configure SLAAC on the specified interfaces.

        :param node: Honeycomb node.
        :param interface: Interface to configure SLAAC.
        :param slaac_data: Dictionary of configurations to apply. \
        If it is None then the existing configuration is removed.
        :type node: dict
        :type interface: str
        :type slaac_data: dict of dicts
        :returns: Content of response.
        :rtype: bytearray
        :raises HoneycombError: If RA could not be configured.
        """

        interface = Topology.convert_interface_reference(
            node, interface, 'name')
        interface = interface.replace('/', '%2F')
        path = 'interface/' + interface + '/ipv6/ipv6-router-advertisements'

        if not slaac_data:
            status_code, _ = HcUtil.delete_honeycomb_data(
                node, 'config_slaac', path)
        else:
            data = {
                       'ipv6-router-advertisements': slaac_data
            }

            status_code, _ = HcUtil.put_honeycomb_data(
                node, 'config_slaac', data, path)

        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
            raise HoneycombError(
                'Configuring SLAAC failed. Status code:{0}'.format(status_code))
Пример #5
0
    def set_proxyarp_interface_config(node, interface, state):
        """Enable or disable the proxyARP feature on the specified interface.

        :param node: Honeycomb node.
        :param interface: Name or sw_if_index of an interface on the node.
        :param state: Desired proxyARP state: enable, disable.
        :type node: dict
        :type interface: str
        :type state: str
        :raises ValueError: If the state argument is incorrect.
        :raises HoneycombError: If the status code in response is not
            200 = OK or 201 = ACCEPTED.
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")
        interface = interface.replace("/", "%2F")

        path = "/interface/{0}/proxy-arp".format(interface)

        if state == "disable":
            status_code, _ = HcUtil.delete_honeycomb_data(
                node, "config_vpp_interfaces", path)
        elif state == "enable":
            data = {"proxy-arp": {}}
            status_code, _ = HcUtil.put_honeycomb_data(
                node, "config_vpp_interfaces", data, path)
        else:
            raise ValueError("State argument has to be enable or disable.")

        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
            raise HoneycombError(
                "Interface proxyARP configuration on node {0} was not"
                " successful.".format(node["host"]))
Пример #6
0
    def get_ipv6nd_configuration(node, interface):
        """Read IPv6 Neighbor Discovery proxy configuration on the specified
        interface.

        :param node: Honeycomb node.
        :param interface: Name of an interface on the node.
        :type node: dict
        :type interface: str
        :returns: Content of response.
        :rtype: bytearray
        :raises HoneycombError: If the configuration could not be read.
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")
        interface = interface.replace("/", "%2F")

        path = "/interface/{0}/ietf-ip:ipv6/nd-proxies".format(interface)

        status_code, resp = HcUtil.get_honeycomb_data(node,
                                                      "config_vpp_interfaces",
                                                      path)
        if status_code != HTTPCodes.OK:
            raise HoneycombError("Could not read IPv6 ND proxy configuration. "
                                 "Status code: {0}.".format(status_code))
        else:
            return resp
Пример #7
0
    def configure_ipv6nd(node, interface, addresses=None):
        """Configure IPv6 Neighbor Discovery proxy on the specified interface,
        or remove/replace an existing configuration.

        :param node: Honeycomb node.
        :param interface: Name of an interface on the node.
        :param addresses: IPv6 addresses to configure ND proxy with. If no
            address is provided, ND proxy configuration will be removed.
        :type node: dict
        :type interface: str
        :type addresses: list
        :returns: Content of response.
        :rtype: bytearray
        :raises HoneycombError: If the operation fails.
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")
        interface = interface.replace("/", "%2F")

        path = "/interface/{0}/ietf-ip:ipv6/nd-proxies".format(interface)

        if addresses is None:
            status_code, resp = HcUtil. \
                delete_honeycomb_data(node, "config_vpp_interfaces", path)
        else:
            data = {
                "nd-proxies": {
                    "nd-proxy": [{
                        "address": x
                    } for x in addresses]
                }
            }

            status_code, resp = HcUtil. \
                put_honeycomb_data(node, "config_vpp_interfaces", data, path,
                                   data_representation=DataRepresentation.JSON)

        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
            raise HoneycombError("IPv6 ND proxy configuration unsuccessful. "
                                 "Status code: {0}.".format(status_code))
        else:
            return resp
Пример #8
0
    def set_acl_plugin_interface(node, interface, acl_name, direction):
        """Assign an interface to an ietf-acl classify chain.

        :param node: Honeycomb node.
        :param interface: Name of an interface on the node.
        :param acl_name: Name of an ACL chain configured through ACL-plugin.
        :param direction: Classify incoming or outgoing packets.
            Valid options are: ingress, egress
        :type node: dict
        :type interface: str or int
        :type acl_name: str
        :type direction: str
        :returns: Content of response.
        :rtype: bytearray
        :raises ValueError: If the direction argument is incorrect.
        :raises HoneycombError: If the operation fails.
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")

        interface = interface.replace("/", "%2F")

        if direction not in ("ingress", "egress"):
            raise ValueError(
                "Unknown traffic direction {0}. "
                "Valid options are: ingress, egress.".format(direction))

        path = "/attachment-points/interface/{0}/{1}/acl-sets/".format(
            interface, direction)

        data = {"acl-sets": {"acl-set": {"name": acl_name}}}

        status_code, resp = HcUtil.put_honeycomb_data(node,
                                                      "config_plugin_acl",
                                                      data, path)

        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
            raise HoneycombError("Could not configure ACL on interface. "
                                 "Status code: {0}.".format(status_code))

        return resp
Пример #9
0
    def delete_interface_plugin_acls(node, interface):
        """Remove all plugin-acl assignments from an interface.

        :param node: Honeycomb node.
        :param interface: Name of an interface on the node.
        :type node: dict
        :type interface: str or int
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")

        interface = interface.replace("/", "%2F")

        path = "/interface/{0}/interface-acl:acl/".format(interface)
        status_code, _ = HcUtil.delete_honeycomb_data(node,
                                                      "config_vpp_interfaces",
                                                      path)

        if status_code != HTTPCodes.OK:
            raise HoneycombError(
                "Could not remove ACL assignment from interface. "
                "Status code: {0}.".format(status_code))
Пример #10
0
    def configure_nat_on_interface(node, interface, direction, delete=False):
        """Configure NAT on the specified interface.

        :param node: Honeycomb node.
        :param interface: Name of an interface on the node.
        :param direction: NAT direction, outbound or inbound.
        :param delete: Delete an existing interface NAT configuration.
        :type node: dict
        :type interface: str
        :type direction: str
        :type delete: bool
        :returns: Content of response.
        :rtype: bytearray
        :raises HoneycombError: If the operation fails.
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")

        interface = interface.replace("/", "%2F")
        path = "/interface/{0}/interface-nat:nat/{1}".format(
            interface, direction)

        data = {direction: {}}

        if delete:
            status_code, resp = HcUtil.delete_honeycomb_data(
                node, "config_vpp_interfaces", path)
        else:
            status_code, resp = HcUtil.put_honeycomb_data(
                node, "config_vpp_interfaces", data, path)

        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
            raise HoneycombError("Could not configure NAT on interface. "
                                 "Status code: {0}.".format(status_code))

        return resp
Пример #11
0
    def vpp_get_interface_ip_addresses(node, interface, ip_version):
        """Get list of IP addresses from an interface on a VPP node.

         :param node: VPP node to get data from.
         :param interface: Name of an interface on the VPP node.
         :param ip_version: IP protocol version (ipv4 or ipv6).
         :type node: dict
         :type interface: str
         :type ip_version: str
         :returns: List of dictionaries, each containing IP address, subnet
            prefix length and also the subnet mask for ipv4 addresses.
            Note: A single interface may have multiple IP addresses assigned.
         :rtype: list
        """

        try:
            sw_if_index = Topology.convert_interface_reference(
                node, interface, "sw_if_index")
        except RuntimeError:
            if isinstance(interface, basestring):
                sw_if_index = InterfaceUtil.get_sw_if_index(node, interface)
            else:
                raise

        with VatTerminal(node) as vat:
            response = vat.vat_terminal_exec_cmd_from_template(
                "ip_address_dump.vat",
                ip_version=ip_version,
                sw_if_index=sw_if_index)

        data = response[0]

        if ip_version == "ipv4":
            for item in data:
                item["netmask"] = convert_ipv4_netmask_prefix(
                    item["prefix_length"])
        return data
Пример #12
0
def get_variables(node, ip_version, out_interface):

    out_interface = Topology.convert_interface_reference(
        node, out_interface, "name")

    ip_version = ip_version.lower()
    variables = {}

    # base network settings
    ipv4_base = {
        "dut_to_tg_if1_ip": "16.0.0.1",
        "dut_to_tg_if2_ip": "16.0.1.1",
        "src_ip": "16.0.0.2",
        "dst_ip": "16.0.2.1",
        "dst_net": "16.0.2.0",
        "prefix_len": 24,
        "next_hop": "16.0.1.2",
        "next_hop1": "16.0.1.3",
        "next_hop2": "16.0.1.4",
        "next_hop_mac1": "00:11:22:33:44:55",
        "next_hop_mac2": "11:22:33:44:55:66"
    }

    ipv6_base = {
        "dut_to_tg_if1_ip": "10::1",
        "dut_to_tg_if2_ip": "11::1",
        "src_ip": "10::2",
        "dst_ip": "12::1",
        "dst_net": "12::",
        "prefix_len": 64,
        "next_hop": "11::2",
        "next_hop1": "11::3",
        "next_hop2": "11::4",
        "next_hop_mac1": "00:11:22:33:44:55",
        "next_hop_mac2": "11:22:33:44:55:66"
    }

    if ip_version == "ipv4":
        variables.update(ipv4_base)
    elif ip_version == "ipv6":
        variables.update(ipv6_base)
    else:
        raise ValueError("IP version must be either IPv4 or IPv6.")

    # route configuration used in tests
    tables_cfg = {
        "table1": {
            "id":
            1,
            "description":
            "single hop ipv4",
            "destination-prefix":
            "{0}/{1}".format(ipv4_base["dst_net"], ipv4_base["prefix_len"]),
            "next-hop":
            ipv4_base["next_hop"],
            "outgoing-interface":
            out_interface,
            "vpp-ipv4-route": {}
        },
        "table2": {
            "id":
            1,
            "description":
            "multi hop ipv4",
            "destination-prefix":
            "{0}/{1}".format(ipv4_base["dst_net"], ipv4_base["prefix_len"]),
            "next-hop-list": {
                "next-hop": [{
                    "id": 1,
                    "address": ipv4_base["next_hop1"],
                    "outgoing-interface": out_interface,
                    "weight": "1"
                }, {
                    "id": 2,
                    "address": ipv4_base["next_hop2"],
                    "outgoing-interface": out_interface,
                    "weight": "1"
                }]
            }
        },
        "table3": {
            "id":
            1,
            "description":
            "blackhole ipv4",
            "destination-prefix":
            "{0}/{1}".format(ipv4_base["dst_net"], ipv4_base["prefix_len"]),
            "special-next-hop":
            "receive"
        },
        "table4": {
            "id":
            1,
            "description":
            "single hop ipv6",
            "destination-prefix":
            "{0}/{1}".format(ipv6_base["dst_net"], ipv6_base["prefix_len"]),
            "next-hop":
            ipv6_base["next_hop"],
            "outgoing-interface":
            out_interface,
            "vpp-ipv6-route": {}
        },
        "table5": {
            "id":
            1,
            "description":
            "multi hop ipv6",
            "destination-prefix":
            "{0}/{1}".format(ipv6_base["dst_net"], ipv6_base["prefix_len"]),
            "next-hop-list": {
                "next-hop": [{
                    "id": 1,
                    "address": ipv6_base["next_hop1"],
                    "outgoing-interface": out_interface,
                    "weight": "1"
                }, {
                    "id": 2,
                    "address": ipv6_base["next_hop2"],
                    "outgoing-interface": out_interface,
                    "weight": "1"
                }]
            }
        },
        "table6": {
            "id":
            1,
            "description":
            "blackhole ipv6",
            "destination-prefix":
            "{0}/{1}".format(ipv6_base["dst_net"], ipv6_base["prefix_len"]),
            "special-next-hop":
            "blackhole"
        }
    }

    # expected route operational data
    tables_oper = {
        "table1_oper": {
            "destination-prefix":
            "{0}/{1}".format(ipv4_base["dst_net"], ipv4_base["prefix_len"]),
            "next-hop":
            ipv4_base["next_hop"],
            "outgoing-interface":
            out_interface,
            "vpp-ipv4-route-state": {}
        },
        "table2_oper": {
            "destination-prefix":
            "{0}/{1}".format(ipv4_base["dst_net"], ipv4_base["prefix_len"]),
            "next-hop-list": {
                "next-hop": [{
                    "address": ipv4_base["next_hop1"],
                    "outgoing-interface": out_interface,
                    "weight": 1
                }, {
                    "address": ipv4_base["next_hop2"],
                    "outgoing-interface": out_interface,
                    "weight": 1
                }]
            },
            'vpp-ipv4-route-state': {}
        },
        "table3_oper": {
            "destination-prefix":
            "{0}/{1}".format(ipv4_base["dst_net"], ipv4_base["prefix_len"]),
            "special-next-hop":
            "receive",
            "vpp-ipv4-route-state": {}
        },
        "table4_oper": {
            "destination-prefix":
            "{0}/{1}".format(ipv6_base["dst_net"], ipv6_base["prefix_len"]),
            "next-hop":
            ipv6_base["next_hop"],
            "outgoing-interface":
            out_interface,
            "vpp-ipv6-route-state": {}
        },
        "table5_oper": {
            "destination-prefix":
            "{0}/{1}".format(ipv6_base["dst_net"], ipv6_base["prefix_len"]),
            "next-hop-list": {
                "next-hop": [{
                    "address": ipv6_base["next_hop1"],
                    "outgoing-interface": out_interface,
                    "weight": 1
                }, {
                    "address": ipv6_base["next_hop2"],
                    "outgoing-interface": out_interface,
                    "weight": 1
                }]
            },
            "vpp-ipv6-route-state": {}
        },
        "table6_oper": {
            "destination-prefix":
            "{0}/{1}".format(ipv6_base["dst_net"], ipv6_base["prefix_len"]),
            "special-next-hop":
            "blackhole",
            'vpp-ipv6-route-state': {}
        }
    }

    for item in tables_oper.values():
        if "next-hop-list" in item.keys():
            item["next-hop-list"]["next-hop"].sort()

    variables.update(tables_cfg)
    variables.update(tables_oper)
    return variables
Пример #13
0
    def set_acl_plugin_interface(node,
                                 interface,
                                 acl_name,
                                 direction,
                                 macip=False):
        """Assign an interface to an ietf-acl classify chain.

        :param node: Honeycomb node.
        :param interface: Name of an interface on the node.
        :param acl_name: Name of an ACL chain configured through ACL-plugin.
        :param direction: Classify incoming or outgiong packets.
            Valid options are: ingress, egress
        :param macip: Use simple MAC+IP classifier. Optional.
        :type node: dict
        :type interface: str or int
        :type acl_name: str
        :type direction: str
        :type macip: bool
        :returns: Content of response.
        :rtype: bytearray
        :raises ValueError: If the direction argument is incorrect.
        :raises HoneycombError: If the operation fails.
        """

        interface = Topology.convert_interface_reference(
            node, interface, "name")

        interface = interface.replace("/", "%2F")

        if direction not in ("ingress", "egress"):
            raise ValueError(
                "Unknown traffic direction {0}. "
                "Valid options are: ingress, egress.".format(direction))

        path = "/interface/{0}/interface-acl:acl/{1}".format(
            interface, direction)

        if macip:
            data = {
                direction: {
                    "vpp-macip-acl": {
                        "type": "vpp-acl:vpp-macip-acl",
                        "name": acl_name
                    }
                }
            }
        else:
            data = {
                direction: {
                    "vpp-acls": [{
                        "type": "vpp-acl:vpp-acl",
                        "name": acl_name
                    }]
                }
            }

        status_code, resp = HcUtil.put_honeycomb_data(node,
                                                      "config_vpp_interfaces",
                                                      data, path)

        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
            raise HoneycombError("Could not configure ACL on interface. "
                                 "Status code: {0}.".format(status_code))

        return resp
Пример #14
0
def get_variables(node, interface):
    """Create and return a dictionary of test variables.

    :param node: Honeycomb node.
    :param interface: Name, link name or sw_if_index of an interface.
    :type node: dict
    :type interface: str or int

    :returns: Dictionary of test variables - settings for Honeycomb's
    NAT node and expected operational data.
    :rtype: dict
    """
    sw_if_index = Topology.convert_interface_reference(node, interface,
                                                       "sw_if_index")

    variables = {
        "nat_empty": {
            'instances': {
                'instance': [{
                    'id': 0
                }]
            }
        },
        "entry1": {
            "mapping-entry": [{
                "index": 1,
                "type": "static",
                "internal-src-address": "192.168.0.1/32",
                "external-src-address": "192.168.1.1/32"
            }]
        },
        "entry2": {
            "mapping-entry": [{
                "index": 2,
                "type": "static",
                "internal-src-address": "192.168.0.2/32",
                "external-src-address": "192.168.1.2/32"
            }]
        },
        "entry1_2_oper": {
            "mapping-entry": [{
                "index": 1,
                "type": "static",
                "internal-src-address": "192.168.0.1/32",
                "external-src-address": "192.168.1.1/32"
            }, {
                "index": 2,
                "type": "static",
                "internal-src-address": "192.168.0.2/32",
                "external-src-address": "192.168.1.2/32"
            }]
        },
        "entry1_vat": [{
            "local_address": "192.168.0.1",
            "remote_address": "192.168.1.1",
            "vrf": "0"
        }],
        "entry1_2_vat": [{
            "local_address": "192.168.0.1",
            "remote_address": "192.168.1.1",
            "vrf": "0",
            "protocol": "17"
        }, {
            "local_address": "192.168.0.2",
            "remote_address": "192.168.1.2",
            "vrf": "0",
            "protocol": "17"
        }],
        "nat_interface_vat_in": [{
            "sw_if_index": str(sw_if_index),
            "direction": "in"
        }],
        "nat_interface_vat_out": [{
            "sw_if_index": str(sw_if_index),
            "direction": "out"
        }]
    }

    return variables