X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FIPUtil.py;h=d2f2adcf286479b2ed29fd29c22dc3f7025a721c;hp=5011708c3996a03d9a5010384d0ea116b6bcf1c1;hb=6e25bb5e8b8bcc2a1f741892508a68aec7d791b9;hpb=517ee7fd3eb28ecf030c5d50be09fcdabe508922 diff --git a/resources/libraries/python/IPUtil.py b/resources/libraries/python/IPUtil.py index 5011708c39..d2f2adcf28 100644 --- a/resources/libraries/python/IPUtil.py +++ b/resources/libraries/python/IPUtil.py @@ -17,13 +17,37 @@ from ipaddress import IPv4Network, ip_address from resources.libraries.python.ssh import SSH from resources.libraries.python.constants import Constants - +from resources.libraries.python.ssh import exec_cmd_no_error, exec_cmd from resources.libraries.python.topology import Topology class IPUtil(object): """Common IP utilities""" + @staticmethod + def ip_to_int(ip_str): + """Convert IP address from string format (e.g. 10.0.0.1) to integer + representation (167772161). + + :param ip_str: IP address in string representation. + :type ip_str: str + :returns: Integer representation of IP address. + :rtype: int + """ + return int(ip_address(unicode(ip_str))) + + @staticmethod + def int_to_ip(ip_int): + """Convert IP address from integer representation (e.g. 167772161) to + string format (10.0.0.1). + + :param ip_int: IP address in integer representation. + :type ip_int: int + :returns: String representation of IP address. + :rtype: str + """ + return str(ip_address(ip_int)) + @staticmethod def vpp_ip_probe(node, interface, addr, if_type="key"): """Run ip probe on VPP node. @@ -73,6 +97,93 @@ class IPUtil(object): raise AssertionError('IP addresses are not equal: {0} != {1}'. format(ip1, ip2)) + @staticmethod + def setup_network_namespace(node, namespace_name, interface_name, + ip_addr, prefix): + """Setup namespace on given node and attach interface and IP to + this namespace. Applicable also on TG node. + + :param node: Node to set namespace on. + :param namespace_name: Namespace name. + :param interface_name: Interface name. + :param ip_addr: IP address of namespace's interface. + :param prefix: IP address prefix length. + :type node: dict + :type namespace_name: str + :type vhost_if: str + :type ip_addr: str + :type prefix: int + """ + cmd = ('ip netns add {0}'.format(namespace_name)) + exec_cmd_no_error(node, cmd, sudo=True) + + cmd = ('ip link set dev {0} up netns {1}'.format(interface_name, + namespace_name)) + exec_cmd_no_error(node, cmd, sudo=True) + + cmd = ('ip netns exec {0} ip addr add {1}/{2} dev {3}'.format( + namespace_name, ip_addr, prefix, interface_name)) + exec_cmd_no_error(node, cmd, sudo=True) + + @staticmethod + def linux_enable_forwarding(node, ip_ver='ipv4'): + """Enable forwarding on a Linux node, e.g. VM. + + :param node: Node to enable forwarding on. + :param ip_ver: IP version, 'ipv4' or 'ipv6'. + :type node: dict + :type ip_ver: str + """ + cmd = 'sysctl -w net.{0}.ip_forward=1'.format(ip_ver) + exec_cmd_no_error(node, cmd, sudo=True) + + @staticmethod + def set_linux_interface_ip(node, interface, ip_addr, prefix, + namespace=None): + """Set IP address to interface in linux. + + :param node: Node where to execute command. + :param interface: Interface in namespace. + :param ip_addr: IP to be set on interface. + :param prefix: IP prefix. + :param namespace: Execute command in namespace. Optional + :type node: dict + :type interface: str + :type ip_addr: str + :type prefix: int + :type namespace: str + :raises RuntimeError: IP could not be set. + """ + if namespace is not None: + cmd = 'ip netns exec {} ip addr add {}/{} dev {}'.format( + namespace, ip_addr, prefix, interface) + else: + cmd = 'ip addr add {}/{} dev {}'.format(ip_addr, prefix, interface) + (ret_code, _, stderr) = exec_cmd(node, cmd, timeout=5, sudo=True) + if ret_code != 0: + raise RuntimeError( + 'Could not set IP for interface, reason:{}'.format(stderr)) + + @staticmethod + def set_linux_interface_route(node, interface, route, namespace=None): + """Set route via interface in linux. + + :param node: Node where to execute command. + :param interface: Interface in namespace. + :param route: Route to be added via interface. + :param namespace: Execute command in namespace. Optional parameter. + :type node: dict + :type interface: str + :type route: str + :type namespace: str + """ + if namespace is not None: + cmd = 'ip netns exec {} ip route add {} dev {}'.format( + namespace, route, interface) + else: + cmd = 'ip route add {} dev {}'.format(route, interface) + exec_cmd_no_error(node, cmd, sudo=True) + def convert_ipv4_netmask_prefix(network): """Convert network mask to equivalent network prefix length or vice versa. @@ -80,7 +191,7 @@ def convert_ipv4_netmask_prefix(network): Example: mask 255.255.0.0 -> prefix length 16 :param network: Network mask or network prefix length. :type network: str or int - :return: Network mask or network prefix length. + :returns: Network mask or network prefix length. :rtype: str or int """ temp_address = "0.0.0.0"