def removeBond(self, bonding): if not self.owned_device(bonding.name): IfcfgAcquire.acquire_device(bonding.name) to_be_removed = self._ifaceDownAndCleanup(bonding) if to_be_removed: self.configApplier.removeBonding(bonding.name) if bonding.on_removal_just_detach_from_network: # Recreate the bond with ip and master info cleared bonding.ipv4 = address.IPv4() bonding.ipv6 = address.IPv6() bonding.master = None bonding.configure() else: for slave in bonding.slaves: slave.remove() self.runningConfig.removeBonding(bonding.name) else: set_mtu = self._setNewMtu(bonding, vlans.vlan_devs_for_iface(bonding.name)) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value. # Note that ip link set dev bondX mtu Y sets Y on all its links if set_mtu is not None: ipwrapper.linkSet(bonding.name, ['mtu', str(set_mtu)]) # If the bond was bridged, we must remove BRIDGE parameter from its # ifcfg configuration file. if bonding.bridge: self.configApplier.dropBridgeParameter(bonding.name)
def test_restore_missing_dynamic_ipv4_network( self, adapter, switch, bridged ): with veth_pair() as (server, client): linkSet(server, ['up']) linkSet(client, ['up']) SETUP_NET = { NETWORK_NAME: { 'nic': client, 'bridged': bridged, 'bootproto': 'dhcp', 'switch': switch, } } REMOVE_NET = {NETWORK_NAME: {'remove': True}} with adapter.reset_persistent_config(): with adapter.setupNetworks(SETUP_NET, {}, NOCHK): adapter.setSafeNetworkConfig() adapter.setupNetworks(REMOVE_NET, {}, NOCHK) adapter.assertNoNetworkExists(NETWORK_NAME) adapter.restore_nets() adapter.assertNetworkExists(NETWORK_NAME)
def test_switch_change_bonded_network_with_dhclient(self): with veth_pair() as (server, nic1): with dummy_device() as nic2: NETSETUP_SOURCE = { NET1_NAME: { 'bonding': BOND_NAME, 'bootproto': 'dhcp', 'blockingdhcp': True, 'switch': self.switch_type_source } } NETSETUP_TARGET = _change_switch_type(NETSETUP_SOURCE, self.switch_type_target) BONDSETUP_SOURCE = { BOND_NAME: { 'nics': [nic1, nic2], 'switch': self.switch_type_source } } BONDSETUP_TARGET = _change_switch_type(BONDSETUP_SOURCE, self.switch_type_target) addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO): with self.setupNetworks(NETSETUP_SOURCE, BONDSETUP_SOURCE, NOCHK): self.setupNetworks(NETSETUP_TARGET, BONDSETUP_TARGET, NOCHK) self.assertNetwork(NET1_NAME, NETSETUP_TARGET[NET1_NAME]) self.assertBond(BOND_NAME, BONDSETUP_TARGET[BOND_NAME])
def removeBond(self, bonding): if not self.owned_device(bonding.name): IfcfgAcquire.acquire_device(bonding.name) to_be_removed = self._ifaceDownAndCleanup(bonding) if to_be_removed: self.configApplier.removeBonding(bonding.name) if bonding.on_removal_just_detach_from_network: # Recreate the bond with ip and master info cleared bonding.ipv4 = address.IPv4() bonding.ipv6 = address.IPv6() bonding.master = None bonding.configure() else: for slave in bonding.slaves: slave.remove() if self.unifiedPersistence: self.runningConfig.removeBonding(bonding.name) else: set_mtu = self._setNewMtu(bonding, vlans.vlan_devs_for_iface(bonding.name)) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value. # Note that ip link set dev bondX mtu Y sets Y on all its links if set_mtu is not None: ipwrapper.linkSet(bonding.name, ["mtu", str(set_mtu)]) # If the bond was bridged, we must remove BRIDGE parameter from its # ifcfg configuration file. if bonding.bridge: self.configApplier.dropBridgeParameter(bonding.name)
def _down(self): with monitor.Monitor(groups=('link',), timeout=2) as mon: linkSet(self.devName, ['down']) for event in mon: if (event.get('name') == self.devName and event.get('state') == 'down'): return
def _down(self): with monitor.Monitor(groups=('link', ), timeout=2) as mon: linkSet(self.devName, ['down']) for event in mon: if (event.get('name') == self.devName and event.get('state') == 'down'): return
def test_attach_dhcp_nic_to_dhcpv4_bridged_network(self, switch): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO, router=DHCPv4_GATEWAY): with dhclient_run(client): adapter.assertDhclient(client, family=IpFamily.IPv4) NETCREATE = { NETWORK_NAME: { 'nic': client, 'bootproto': 'dhcp', 'blockingdhcp': True, 'switch': switch } } with adapter.setupNetworks(NETCREATE, {}, NOCHK): nic_netinfo = adapter.netinfo.nics[client] adapter.assertDisabledIPv4(nic_netinfo) adapter.assertNoDhclient(client, family=IpFamily.IPv4) net_netinfo = adapter.netinfo.networks[NETWORK_NAME] adapter.assertDHCPv4(net_netinfo) adapter.assertDhclient(NETWORK_NAME, family=IpFamily.IPv4)
def test_attach_dhcp_nic_to_dhcpv6_bridged_network(self, switch): if switch == 'ovs': pytest.xfail('IPv6 dynamic fails with OvS' 'see https://bugzilla.redhat.com/1773471') with veth_pair() as (server, client): addrAdd(server, IPv6_ADDRESS, IPv6_CIDR, IpFamily.IPv6) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO): with dhcp_client_run(client, family=IpFamily.IPv6): adapter.assertDhclient(client, family=IpFamily.IPv6) NETCREATE = { NETWORK_NAME: { 'nic': client, 'dhcpv6': True, 'blockingdhcp': True, 'switch': switch, } } with adapter.setupNetworks(NETCREATE, {}, NOCHK): nic_netinfo = adapter.netinfo.nics[client] adapter.assertDisabledIPv6(nic_netinfo) adapter.assertNoDhclient(client, family=IpFamily.IPv6) net_netinfo = adapter.netinfo.networks[NETWORK_NAME] adapter.assertDHCPv6(net_netinfo) adapter.assertDhclient(NETWORK_NAME, family=IpFamily.IPv6)
def removeNic(self, nic, remove_even_if_used=False): if not self.owned_device(nic.name): IfcfgAcquire.acquire_device(nic.name) # If the nic is top device we should ifdown it even if it is # used by a VLAN. Otherwise we would keep its IP address. remove_even_if_used |= nic.master is None to_be_removed = self._ifaceDownAndCleanup(nic, remove_even_if_used) if to_be_removed: self.configApplier.removeNic(nic.name) if nic.name in nics.nics(): _exec_ifup(nic) else: logging.warning('host interface %s missing', nic.name) else: vlans = link_vlan.get_vlans_on_base_device(nic.name) set_mtu = self._setNewMtu(nic, vlans) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value if set_mtu is not None: ipwrapper.linkSet(nic.name, ['mtu', str(set_mtu)]) # If the nic was bridged, we must remove BRIDGE parameter from its # ifcfg configuration file. if nic.bridge: self.configApplier.dropBridgeParameter(nic.name)
def test_ovirtmgmtm_to_ovs(self): """ Test transformation of initial management network to OVS. # TODO: test it with ovirtmgmt and test-network # NOTE: without default route # TODO: more asserts """ with veth_pair() as (left, right): addrAdd(left, IP_ADDRESS, IP_CIDR) addrAdd(left, IPv6_ADDRESS, IPv6_CIDR, 6) linkSet(left, ['up']) with dnsmasq_run(left, DHCP_RANGE_FROM, DHCP_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, IP_GATEWAY): network = { NETWORK_NAME: {'nic': right, 'bootproto': 'dhcp', 'bridged': True, 'blockingdhcp': True}} options = NOCHK options['ovs'] = False try: status, msg = self.setupNetworks(network, {}, options) self.assertEqual(status, SUCCESS, msg) self.assertNetworkExists(NETWORK_NAME) options['ovs'] = True status, msg = self.setupNetworks(network, {}, options) self.assertEqual(status, SUCCESS, msg) self.assertNetworkExists(NETWORK_NAME) finally: dhcp.delete_dhclient_leases(NETWORK_NAME, True, False)
def test_add_net_with_dhcp(self, switch, families, bridged): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) addrAdd(server, IPv6_ADDRESS, IPv6_CIDR, IpFamily.IPv6) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, router=DHCPv4_GATEWAY): network_attrs = {'bridged': bridged, 'nic': client, 'blockingdhcp': True, 'switch': switch} if IpFamily.IPv4 in families: network_attrs['bootproto'] = 'dhcp' if IpFamily.IPv6 in families: network_attrs['dhcpv6'] = True netcreate = {NETWORK_NAME: network_attrs} with adapter.setupNetworks(netcreate, {}, NOCHK): adapter.assertNetworkIp( NETWORK_NAME, netcreate[NETWORK_NAME])
def removeNic(self, nic, remove_even_if_used=False): if not self.owned_device(nic.name): IfcfgAcquire.acquire_device(nic.name) # If the nic is top device we should ifdown it even if it is # used by a VLAN. Otherwise we would keep its IP address. remove_even_if_used |= nic.master is None to_be_removed = self._ifaceDownAndCleanup(nic, remove_even_if_used) if to_be_removed: self.configApplier.removeNic(nic.name) if nic.name in nics.nics(): _exec_ifup(nic) else: logging.warning('host interface %s missing', nic.name) else: set_mtu = self._setNewMtu(nic, vlans.vlan_devs_for_iface(nic.name)) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value if set_mtu is not None: ipwrapper.linkSet(nic.name, ['mtu', str(set_mtu)]) # If the nic was bridged, we must remove BRIDGE parameter from its # ifcfg configuration file. if nic.bridge: self.configApplier.dropBridgeParameter(nic.name)
def test_ovirtmgmtm_to_ovs(self): """ Test transformation of initial management network to OVS. # TODO: test it with ovirtmgmt and test-network # NOTE: without default route # TODO: more asserts """ with veth_pair() as (left, right): addrAdd(left, IP_ADDRESS, IP_CIDR) addrAdd(left, IPv6_ADDRESS, IPv6_CIDR, 6) linkSet(left, ['up']) with dnsmasq_run(left, DHCP_RANGE_FROM, DHCP_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, IP_GATEWAY): network = { NETWORK_NAME: { 'nic': right, 'bootproto': 'dhcp', 'bridged': True, 'blockingdhcp': True } } options = NOCHK options['ovs'] = False try: status, msg = self.setupNetworks(network, {}, options) self.assertEqual(status, SUCCESS, msg) self.assertNetworkExists(NETWORK_NAME) options['ovs'] = True status, msg = self.setupNetworks(network, {}, options) self.assertEqual(status, SUCCESS, msg) self.assertNetworkExists(NETWORK_NAME) finally: dhcp.delete_dhclient_leases(NETWORK_NAME, True, False)
def removeBond(self, bonding): if not self.owned_device(bonding.name): IfcfgAcquire.acquire_device(bonding.name) to_be_removed = self._ifaceDownAndCleanup(bonding) if to_be_removed: self.configApplier.removeBonding(bonding.name) if bonding.on_removal_just_detach_from_network: # Recreate the bond with ip and master info cleared bonding.ipv4 = address.IPv4() bonding.ipv6 = address.IPv6() bonding.master = None bonding.configure() else: for slave in bonding.slaves: slave.remove() self.runningConfig.removeBonding(bonding.name) else: vlans = link_vlan.get_vlans_on_base_device(bonding.name) set_mtu = self._setNewMtu(bonding, vlans) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value. # Note that ip link set dev bondX mtu Y sets Y on all its links if set_mtu is not None: ipwrapper.linkSet(bonding.name, ['mtu', str(set_mtu)]) # If the bond was bridged, we must remove BRIDGE parameter from its # ifcfg configuration file. if bonding.bridge: self.configApplier.dropBridgeParameter(bonding.name) bond_used_by_net = self.net_info.getNetworkForIface(bonding.name) bond_info = self.net_info.bondings[bonding.name] if (not bond_used_by_net and (bond_info['ipv4addrs'] or bond_info['ipv6addrs'])): ipwrapper.addrFlush(bonding.name)
def test_attach_dhcp_nic_to_ipless_network(self, switch): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) addrAdd(server, IPv6_ADDRESS, IPv6_CIDR, IpFamily.IPv6) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, router=DHCPv4_GATEWAY): with dhclient_run(client): adapter.assertDhclient(client, family=IpFamily.IPv4) adapter.assertDhclient(client, family=IpFamily.IPv6) NETCREATE = { NETWORK_NAME: { 'nic': client, 'switch': switch } } with adapter.setupNetworks(NETCREATE, {}, NOCHK): nic_netinfo = adapter.netinfo.nics[client] adapter.assertDisabledIPv4(nic_netinfo) adapter.assertDisabledIPv6(nic_netinfo) net_netinfo = adapter.netinfo.networks[NETWORK_NAME] adapter.assertDisabledIPv4(net_netinfo) adapter.assertDisabledIPv6(nic_netinfo)
def test_local_auto_with_dynamic_address_from_ra(self): IPV6_NETADDRESS = '2001:1:1:1' IPV6_NETPREFIX_LEN = '64' with veth_pair() as (server, client): with dnsmasq_run(server, ipv6_slaac_prefix=IPV6_NETADDRESS + '::'): with wait_for_ipv6(client): ipwrapper.linkSet(client, ['up']) ipwrapper.linkSet(server, ['up']) ipwrapper.addrAdd(server, IPV6_NETADDRESS + '::1', IPV6_NETPREFIX_LEN, family=6) # Expecting link and global addresses on client iface # The addresses are given randomly, so we sort them ip_addrs = sorted(addresses.getIpAddrs()[client], key=lambda ip: ip['address']) self.assertEqual(2, len(ip_addrs)) self.assertTrue(addresses.is_dynamic(ip_addrs[0])) self.assertEqual('global', ip_addrs[0]['scope']) self.assertEqual(IPV6_NETADDRESS, ip_addrs[0]['address'][:len(IPV6_NETADDRESS)]) self.assertEqual('link', ip_addrs[1]['scope'])
def test_switch_change_bonded_network_with_dhclient(self): with veth_pair() as (server, nic1): with dummy_device() as nic2: NETSETUP_SOURCE = {NET1_NAME: { 'bonding': BOND_NAME, 'bootproto': 'dhcp', 'blockingdhcp': True, 'switch': self.switch_type_source}} NETSETUP_TARGET = _change_switch_type( NETSETUP_SOURCE, self.switch_type_target) BONDSETUP_SOURCE = {BOND_NAME: { 'nics': [nic1, nic2], 'switch': self.switch_type_source}} BONDSETUP_TARGET = _change_switch_type( BONDSETUP_SOURCE, self.switch_type_target) addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO): with self.setupNetworks( NETSETUP_SOURCE, BONDSETUP_SOURCE, NOCHK): self.setupNetworks( NETSETUP_TARGET, BONDSETUP_TARGET, NOCHK) self.assertNetwork( NET1_NAME, NETSETUP_TARGET[NET1_NAME]) self.assertBond(BOND_NAME, BONDSETUP_TARGET[BOND_NAME])
def test_add_net_with_dhcp(self, switch, families, bridged): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) addrAdd(server, IPv6_ADDRESS, IPv6_CIDR, IpFamily.IPv6) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, router=DHCPv4_GATEWAY): network_attrs = { 'bridged': bridged, 'nic': client, 'blockingdhcp': True, 'switch': switch } if IpFamily.IPv4 in families: network_attrs['bootproto'] = 'dhcp' if IpFamily.IPv6 in families: network_attrs['dhcpv6'] = True netcreate = {NETWORK_NAME: network_attrs} with adapter.setupNetworks(netcreate, {}, NOCHK): adapter.assertNetworkIp(NETWORK_NAME, netcreate[NETWORK_NAME])
def test_restore_dynamic_ipv4_network(self, switch): if switch == 'ovs': # With OVS, the restoration creates the network without an IP. pytest.xfail('Inconsistent behaviour with OVS') with veth_pair() as (server, client): linkSet(server, ['up']) SETUP_NET = { NETWORK_NAME: { 'nic': client, 'bridged': False, 'bootproto': 'dhcp', 'switch': switch, } } REMOVE_NET = {NETWORK_NAME: {'remove': True}} with adapter.reset_persistent_config(): with adapter.setupNetworks(SETUP_NET, {}, NOCHK): adapter.setSafeNetworkConfig() adapter.setupNetworks(REMOVE_NET, {}, NOCHK) adapter.assertNoNetworkExists(NETWORK_NAME) adapter.restore_nets() # Attempt to restore network without dhcp server. # As expected, restoration occurs with blockingdhcp=True # and therefore it should fail the setup. adapter.assertNoNetworkExists(NETWORK_NAME)
def ifup(self, iface): ipwrapper.linkSet(iface.name, ['up']) if iface.ipv4.bootproto == 'dhcp': dhclient.run(iface.name, 4, iface.ipv4.defaultRoute, iface.duid_source, iface.blockingdhcp) if iface.ipv6.dhcpv6: dhclient.run(iface.name, 6, iface.ipv6.defaultRoute, iface.duid_source, iface.blockingdhcp)
def up(self, admin_blocking=True, oper_blocking=False): if self._is_dpdk_type: dpdk.up(self._dev) return if admin_blocking: self._up_blocking(oper_blocking) else: ipwrapper.linkSet(self._dev, [STATE_UP])
def dynamic_ipv4_iface(): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO, router=IPv4_ADDRESS): yield client
def test_routes_device_to(self, ip_addr, ip_netmask, nic0): addr_in_net = ipaddress.ip_address(ip_addr) + 1 ip_version = addr_in_net.version ipwrapper.addrAdd(nic0, ip_addr, ip_netmask, family=ip_version) try: ipwrapper.linkSet(nic0, ['up']) assert routes.getRouteDeviceTo(str(addr_in_net)) == nic0 finally: ipwrapper.addrFlush(nic0, ip_version)
def testDhcpReplaceNicWithBridge(self): with veth_pair() as (left, right): addrAdd(left, IP_ADDRESS, IP_CIDR) addrAdd(left, IPv6_ADDRESS, IPv6_CIDR, 6) linkSet(left, ['up']) with dnsmasq_run(left, DHCP_RANGE_FROM, DHCP_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, IP_GATEWAY): # first, a network without a bridge should get a certain # address network = { NETWORK_NAME: { 'nic': right, 'bridged': False, 'bootproto': 'dhcp', 'blockingdhcp': True } } try: status, msg = self.setupNetworks(network, {}, NOCHK) self.assertEqual(status, SUCCESS, msg) self.assertNetworkExists(NETWORK_NAME) test_net = self.vdsm_net.netinfo.networks[NETWORK_NAME] self.assertEqual(test_net['dhcpv4'], True) devs = self.vdsm_net.netinfo.nics device_name = right self.assertIn(device_name, devs) net_attrs = devs[device_name] self.assertEqual(net_attrs['dhcpv4'], True) self.assertEqual(test_net['gateway'], IP_GATEWAY) ip_addr = test_net['addr'] self.assertSourceRoutingConfiguration(device_name, ip_addr) # now, a bridged network should get the same address # (because dhclient should send the same dhcp-client- # identifier) network[NETWORK_NAME]['bridged'] = True status, msg = self.setupNetworks(network, {}, NOCHK) self.assertEqual(status, SUCCESS, msg) test_net = self.vdsm_net.netinfo.networks[NETWORK_NAME] self.assertEqual(ip_addr, test_net['addr']) network = {NETWORK_NAME: {'remove': True}} status, msg = self.setupNetworks(network, {}, NOCHK) self.assertEqual(status, SUCCESS, msg) self.assertNetworkDoesntExist(NETWORK_NAME) finally: dhcp.delete_dhclient_leases(right, True, False) dhcp.delete_dhclient_leases(NETWORK_NAME, True, False)
def dynamic_ipv6_iface(): if running_on_ovirt_ci(): pytest.skip('Using dnsmasq for ipv6 RA is unstable on CI') with veth_pair() as (server, client): ipwrapper.addrAdd(server, IPV6_ADDR1, IPV6_PREFIX_LENGTH, family=6) ipwrapper.linkSet(server, ['up']) with dnsmasq_run(server, ipv6_slaac_prefix=IPV6_NET_ADDR): with wait_for_ipv6(client): ipwrapper.linkSet(client, ['up']) yield client
def up(dev, admin_blocking=True, oper_blocking=False): """ Set link state to UP, optionally blocking on the action. :param dev: iface name. :param admin_blocking: Block until the administrative state changes to UP. :param oper_blocking: Block until the link is operational. admin state is at kernel level, while link state is at driver level. """ if admin_blocking: _up_blocking(dev, oper_blocking) else: ipwrapper.linkSet(dev, [STATE_UP])
def _create_dhcp_client_server_peers(network_config, vlan_id): with veth_pair(max_length=10) as (server, client): linkSet(server, ['up']) linkSet(client, ['up']) if vlan_id: with vlan_device(server, vlan_id) as vlan_iface: vlan_iface_name = vlan_iface.devName _configure_iface_ip(vlan_iface_name, network_config) yield vlan_iface_name, client else: _configure_iface_ip(server, network_config) yield server, client
def removeNic(self, nic, remove_even_if_used=False): to_be_removed = self._ifaceDownAndCleanup(nic, remove_even_if_used) if to_be_removed: self.configApplier.removeNic(nic.name) if nic.name in nics.nics(): _exec_ifup(nic) else: logging.warning('host interface %s missing', nic.name) else: set_mtu = self._setNewMtu(nic, vlans.vlan_devs_for_iface(nic.name)) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value if set_mtu is not None: ipwrapper.linkSet(nic.name, ['mtu', str(set_mtu)])
def configureNic(self, nic, **opts): if not self.owned_device(nic.name): IfcfgAcquire.acquire_device(nic.name) self.configApplier.addNic(nic, self.net_info, **opts) self._addSourceRoute(nic) if nic.bond is None: if not link_vlan.is_base_device(nic.name): if nic.bridge is not None: dhclient.stop(nic.name, 4) dhclient.stop(nic.name, 6) ipwrapper.linkSet(nic.name, ['down']) else: ifdown(nic.name) _ifup(nic)
def _test_add_net_with_dhcpv4(self, bridged=False): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO): netcreate = {NETWORK_NAME: { 'bridged': bridged, 'nic': client, 'blockingdhcp': True, 'bootproto': 'dhcp', 'switch': self.switch}} with self.setupNetworks(netcreate, {}, NOCHK): self.assertNetworkIp( NETWORK_NAME, netcreate[NETWORK_NAME])
def test_move_nic_between_bridgeless_and_bridged_keep_ip( self, switch, families): if switch == 'ovs' and IpFamily.IPv6 in families: pytest.xfail('IPv6 dynamic fails with OvS' 'see https://bugzilla.redhat.com/1773471') if (switch == 'legacy' and IpFamily.IPv6 in families and not nftestlib.is_nmstate_backend()): pytest.xfail('Fails with ifcfg for IPv6') with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) addrAdd(server, IPv6_ADDRESS, IPv6_CIDR, IpFamily.IPv6) linkSet(server, ['up']) linkSet(client, ['up']) with dnsmasq_run( server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, router=DHCPv4_GATEWAY, ): network_attrs = { 'bridged': False, 'nic': client, 'blockingdhcp': True, 'switch': switch, } if IpFamily.IPv4 in families: network_attrs['bootproto'] = 'dhcp' if IpFamily.IPv6 in families: network_attrs['dhcpv6'] = True netcreate = {NETWORK_NAME: network_attrs} with adapter.setupNetworks(netcreate, {}, NOCHK): adapter.assertNetworkIp(NETWORK_NAME, netcreate[NETWORK_NAME]) client_info = adapter.netinfo.nics[client] ipv4_addr = client_info['ipv4addrs'] ipv6_addr = client_info['ipv6addrs'] network_attrs['bridged'] = True adapter.setupNetworks(netcreate, {}, NOCHK) adapter.assertNetworkIp(NETWORK_NAME, netcreate[NETWORK_NAME]) network_info = adapter.netinfo.networks[NETWORK_NAME] assert ipv4_addr == network_info['ipv4addrs'] assert ipv6_addr == network_info['ipv6addrs']
def test_attach_dhcp_nic_to_ipless_network(self): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ["up"]) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO): with dhclient_run(client): self.assertDhclient(client, family=4) NETCREATE = {NETWORK_NAME: {"nic": client, "switch": self.switch}} with self.setupNetworks(NETCREATE, {}, NOCHK): nic_netinfo = self.netinfo.nics[client] self.assertDisabledIPv4(nic_netinfo) net_netinfo = self.netinfo.networks[NETWORK_NAME] self.assertDisabledIPv4(net_netinfo)
def test_attach_dhcp_nic_to_ipless_network(self): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO): with dhclient_run(client): self.assertDhclient(client, family=4) NETCREATE = {NETWORK_NAME: { 'nic': client, 'switch': self.switch}} with self.setupNetworks(NETCREATE, {}, NOCHK): nic_netinfo = self.netinfo.nics[client] self.assertDisabledIPv4(nic_netinfo) net_netinfo = self.netinfo.networks[NETWORK_NAME] self.assertDisabledIPv4(net_netinfo)
def change_numvfs(pci_path, numvfs, net_name): """Change number of virtual functions of a device. The persistence is stored in the same place as other network persistence is stored. A call to setSafeNetworkConfig() will persist it across reboots. """ # TODO: net_name is here only because it is hard to call pf_to_net_name # TODO: from here. once all our code will be under lib/vdsm this should be # TODO: removed. logging.info("Changing number of vfs on device %s -> %s.", pci_path, numvfs) _update_numvfs(pci_path, numvfs) logging.info("Changing number of vfs on device %s -> %s. succeeded.", pci_path, numvfs) _persist_numvfs(pci_path, numvfs) ipwrapper.linkSet(net_name, ["up"])
def _set_devices_up(nets, bonds): devices = set() for net, attrs in six.iteritems(nets): if 'remove' not in attrs: if 'vlan' in attrs: devices.add(net) if 'nic' in attrs or 'bond' in attrs: devices.add(attrs.get('nic') or attrs.get('bond')) for bond, attrs in six.iteritems(bonds): if 'remove' not in attrs: devices.add(bond) devices.update(attrs['nics']) if ovs_bridge_exists(BRIDGE_NAME): devices.add(BRIDGE_NAME) for device in devices: linkSet(device, ['up'])
def testSetupNetworksOverDhcpIface(self): """When asked to setupNetwork on top of an interface with a running dhclient process, Vdsm is expected to stop that dhclient and start owning the interface. BZ#1100264""" def _get_dhclient_ifaces(): pids = pgrep('dhclient') return [ open('/proc/%s/cmdline' % pid).read().strip('\0').split('\0')[-1] for pid in pids ] with veth_pair() as (server, client): addrAdd(server, IP_ADDRESS, IP_CIDR) linkSet(server, ['up']) with dnsmasq_run(server, DHCP_RANGE_FROM, DHCP_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, IP_GATEWAY): with namedTemporaryDir(dir='/var/lib/dhclient') as dhdir: # Start a non-vdsm owned dhclient for the 'client' iface dhclient_runner = dhcp.DhclientRunner( client, 4, dhdir, 'default') with running(dhclient_runner): # Set up a network over it and wait for dhcp success status, msg = self.setupNetworks( { NETWORK_NAME: { 'nic': client, 'bridged': False, 'bootproto': 'dhcp', 'blockingdhcp': True } }, {}, NOCHK) self.assertEqual(status, SUCCESS, msg) self.assertNetworkExists(NETWORK_NAME) # Verify that dhclient is running for the device ifaces = _get_dhclient_ifaces() vdsm_dhclient = [ iface for iface in ifaces if iface == client ] self.assertEqual( len(vdsm_dhclient), 1, 'There should be one and only one ' 'running dhclient for the device') # cleanup self.setupNetworks({NETWORK_NAME: {'remove': True}}, {}, NOCHK)
def _create_dhcp_client_server_peers(network_config): with veth_pair() as (server, client): addrAdd( server, network_config.ipv4_address, network_config.ipv4_prefix_length, ) if network_config.ipv6_address: addrAdd( server, network_config.ipv6_address, network_config.ipv6_prefix_length, IpFamily.IPv6, ) linkSet(server, ['up']) linkSet(client, ['up']) yield server, client
def change_numvfs(pci_path, numvfs, net_name): """Change number of virtual functions of a device. The persistence is stored in the same place as other network persistence is stored. A call to setSafeNetworkConfig() will persist it across reboots. """ # TODO: net_name is here only because it is hard to call pf_to_net_name # TODO: from here. once all our code will be under lib/vdsm this should be # TODO: removed. logging.info('Changing number of vfs on device %s -> %s.', pci_path, numvfs) _update_numvfs(pci_path, numvfs) logging.info('Changing number of vfs on device %s -> %s. succeeded.', pci_path, numvfs) _persist_numvfs(pci_path, numvfs) ipwrapper.linkSet(net_name, ['up'])
def testGetRouteDeviceTo(self): with dummyIf(1) as nics: nic, = nics addrAdd(nic, IP_ADDRESS, IP_CIDR) try: linkSet(nic, ['up']) self.assertEqual(getRouteDeviceTo(IP_ADDRESS_IN_NETWORK), nic) finally: addrFlush(nic) sysctl.disable_ipv6(nic, False) addrAdd(nic, IPv6_ADDRESS, IPv6_CIDR, family=6) try: linkSet(nic, ['up']) self.assertEqual(getRouteDeviceTo(IPv6_ADDRESS_IN_NETWORK), nic) finally: addrFlush(nic)
def _test_add_net_with_dhcpv4(self, bridged=False): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) linkSet(server, ["up"]) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO): netcreate = { NETWORK_NAME: { "bridged": bridged, "nic": client, "blockingdhcp": True, "bootproto": "dhcp", "switch": self.switch, } } with self.setupNetworks(netcreate, {}, NOCHK): self.assertNetworkIp(NETWORK_NAME, netcreate[NETWORK_NAME])
def test_attach_dhcp_nic_to_dhcpv6_bridged_network(self, switch): with veth_pair() as (server, client): addrAdd(server, IPv6_ADDRESS, IPv6_CIDR, IpFamily.IPv6) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO): with dhclient_run(client, family=IpFamily.IPv6): adapter.assertDhclient(client, family=IpFamily.IPv6) NETCREATE = {NETWORK_NAME: { 'nic': client, 'dhcpv6': True, 'blockingdhcp': True, 'switch': switch}} with adapter.setupNetworks(NETCREATE, {}, NOCHK): nic_netinfo = adapter.netinfo.nics[client] adapter.assertDisabledIPv6(nic_netinfo) adapter.assertNoDhclient(client, family=IpFamily.IPv6) net_netinfo = adapter.netinfo.networks[NETWORK_NAME] adapter.assertDHCPv6(net_netinfo) adapter.assertDhclient(NETWORK_NAME, family=IpFamily.IPv6)
def test_attach_dhcp_nic_to_ipless_network(self, switch): with veth_pair() as (server, client): addrAdd(server, IPv4_ADDRESS, IPv4_PREFIX_LEN) addrAdd(server, IPv6_ADDRESS, IPv6_CIDR, IpFamily.IPv6) linkSet(server, ['up']) with dnsmasq_run(server, DHCPv4_RANGE_FROM, DHCPv4_RANGE_TO, DHCPv6_RANGE_FROM, DHCPv6_RANGE_TO, router=DHCPv4_GATEWAY): with dhclient_run(client): adapter.assertDhclient(client, family=IpFamily.IPv4) adapter.assertDhclient(client, family=IpFamily.IPv6) NETCREATE = {NETWORK_NAME: { 'nic': client, 'switch': switch}} with adapter.setupNetworks(NETCREATE, {}, NOCHK): nic_netinfo = adapter.netinfo.nics[client] adapter.assertDisabledIPv4(nic_netinfo) adapter.assertDisabledIPv6(nic_netinfo) net_netinfo = adapter.netinfo.networks[NETWORK_NAME] adapter.assertDisabledIPv4(net_netinfo) adapter.assertDisabledIPv6(nic_netinfo)
def removeNic(self, nic, remove_even_if_used=False): if not self.owned_device(nic.name): IfcfgAcquire.acquire_device(nic.name) to_be_removed = self._ifaceDownAndCleanup(nic, remove_even_if_used) if to_be_removed: self.configApplier.removeNic(nic.name) if nic.name in nics.nics(): _exec_ifup(nic) else: logging.warning("host interface %s missing", nic.name) else: set_mtu = self._setNewMtu(nic, vlans.vlan_devs_for_iface(nic.name)) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value if set_mtu is not None: ipwrapper.linkSet(nic.name, ["mtu", str(set_mtu)]) # If the nic was bridged, we must remove BRIDGE parameter from its # ifcfg configuration file. if nic.bridge: self.configApplier.dropBridgeParameter(nic.name)
def _set_network_ip_config(ip_config): """Set IP configuration on Vdsm controlled OVS network""" iface = ip_config.top_dev ipv4 = ip_config.ipv4 ipv6 = ip_config.ipv6 port = ip_config.port blocking_dhcp = ip_config.blocking_dhcp net_dev = NetDevice(iface, iproute2, ipv4=ipv4, ipv6=ipv6, blockingdhcp=blocking_dhcp) DynamicSourceRoute.addInterfaceTracking(net_dev) ipwrapper.linkSet(iface, ['down']) if ipv4.address: ipwrapper.addrAdd(iface, ipv4.address, ipv4.netmask) if ipv4.gateway and ipv4.defaultRoute: ipwrapper.routeAdd(['default', 'via', ipv4.gateway]) if ipv6.address or ipv6.ipv6autoconf or ipv6.dhcpv6: sysctl.disable_ipv6(iface, disable=False) else: sysctl.disable_ipv6(iface) if ipv6.address: ipv6addr, ipv6netmask = ipv6.address.split('/') ipwrapper.addrAdd(iface, ipv6addr, ipv6netmask, family=6) if ipv6.gateway: ipwrapper.routeAdd(['default', 'via', ipv6.gateway], dev=iface, family=6) ipwrapper.linkSet(port, ['up']) ipwrapper.linkSet(iface, ['up']) if ipv4.bootproto == 'dhcp': _run_dhclient(iface, blocking_dhcp, ipv4.defaultRoute, 4) if ipv6.dhcpv6: _run_dhclient(iface, blocking_dhcp, ipv6.defaultRoute, 6) iproute2._addSourceRoute(net_dev)
def removeBond(self, bonding): to_be_removed = self._ifaceDownAndCleanup(bonding) if to_be_removed: self.configApplier.removeBonding(bonding.name) if bonding.on_removal_just_detach_from_network: # Recreate the bond with ip and master info cleared bonding.ipv4 = IPv4() bonding.ipv6 = IPv6() bonding.master = None bonding.configure() else: for slave in bonding.slaves: slave.remove() if self.unifiedPersistence: self.runningConfig.removeBonding(bonding.name) else: set_mtu = self._setNewMtu(bonding, vlans.vlan_devs_for_iface(bonding.name)) # Since we are not taking the device up again, ifcfg will not be # read at this point and we need to set the live mtu value. # Note that ip link set dev bondX mtu Y sets Y on all its links if set_mtu is not None: ipwrapper.linkSet(bonding.name, ['mtu', str(set_mtu)])
def test_local_auto_with_dynamic_address_from_ra(self): IPV6_NETADDRESS = '2001:1:1:1' IPV6_NETPREFIX_LEN = '64' with veth_pair() as (server, client): ipwrapper.addrAdd(server, IPV6_NETADDRESS + '::1', IPV6_NETPREFIX_LEN, family=6) ipwrapper.linkSet(server, ['up']) with dnsmasq_run(server, ipv6_slaac_prefix=IPV6_NETADDRESS + '::'): with wait_for_ipv6(client): ipwrapper.linkSet(client, ['up']) # Expecting link and global addresses on client iface # The addresses are given randomly, so we sort them ip_addrs = sorted(addresses.getIpAddrs()[client], key=lambda ip: ip['address']) self.assertEqual(2, len(ip_addrs), ip_addrs) self.assertTrue(addresses.is_dynamic(ip_addrs[0])) self.assertEqual('global', ip_addrs[0]['scope']) self.assertEqual(IPV6_NETADDRESS, ip_addrs[0]['address'][:len(IPV6_NETADDRESS)]) self.assertEqual('link', ip_addrs[1]['scope'])
def test_iperf_upper_limit(self): # Upper limit is not an accurate measure. This is because it converges # over time and depends on current machine hardware (CPU). # Hence, it is hard to make hard assertions on it. The test should run # at least 60 seconds (the longer the better) and the user should # inspect the computed average rate and optionally the additional # traffic data that was collected in client.out in order to be # convinced QOS is working properly. limit_kbps = 1000 # 1 Mbps (in kbps) server_ip = '192.0.2.1' client_ip = '192.0.2.10' qos_out = {'ul': {'m2': limit_kbps}, 'ls': {'m2': limit_kbps}} # using a network namespace is essential since otherwise the kernel # short-circuits the traffic and bypasses the veth devices and the # classfull qdisc. with network_namespace('server_ns') as ns, bridge_device() as bridge, \ veth_pair() as (server_peer, server_dev), \ veth_pair() as (client_dev, client_peer): linkSet(server_peer, ['up']) linkSet(client_peer, ['up']) # iperf server and its veth peer lie in a separate network # namespace link_set_netns(server_dev, ns) bridge.addIf(server_peer) bridge.addIf(client_peer) linkSet(client_dev, ['up']) netns_exec(ns, ['ip', 'link', 'set', 'dev', server_dev, 'up']) addrAdd(client_dev, client_ip, 24) netns_exec(ns, ['ip', '-4', 'addr', 'add', 'dev', server_dev, '%s/24' % server_ip]) qos.configure_outbound(qos_out, client_peer, None) with running(IperfServer(server_ip, network_ns=ns)): client = IperfClient(server_ip, client_ip, test_time=60) client.start() max_rate = max([float( interval['streams'][0]['bits_per_second']) / (2**10) for interval in client.out['intervals']]) self.assertTrue(0 < max_rate < limit_kbps * 1.5)
def ifdown(self, iface): ipwrapper.linkSet(iface.name, ['down']) dhclient = DhcpClient(iface.name) dhclient.shutdown()
def ifup(self, iface): ipwrapper.linkSet(iface.name, ['up']) if iface.ipv4.bootproto == 'dhcp': runDhclient(iface, 4, iface.ipv4.defaultRoute) if iface.ipv6.dhcpv6: runDhclient(iface, 6, iface.ipv6.defaultRoute)
def setIfaceMtu(self, iface, mtu): ipwrapper.linkSet(iface, ['mtu', str(mtu)])
def ifdown(self, iface): ipwrapper.linkSet(iface.name, ['down']) dhclient.stop(iface.name)
def addIf(self, dev): linkSet(dev, ['master', self.devName])
def _update_bridge_ports_mtu(bridge, mtu): for port in bridges.ports(bridge): ipwrapper.linkSet(port, ['mtu', str(mtu)])
def _disconnect_bridge_port(port): ipwrapper.linkSet(port, ['nomaster'])