Commit 8db8bc9e authored by Rafael Monnerat's avatar Rafael Monnerat

slapos.core.format: Set extra configuration on TAP for unbridged interfaces.

  Configure in a way that KVM can use be set with real IPv6 inside provided by slapos.
parent 4e5c2e86
...@@ -446,7 +446,6 @@ class Computer(object): ...@@ -446,7 +446,6 @@ class Computer(object):
if partition_dict['tap']: if partition_dict['tap']:
tap = Tap(partition_dict['tap']['name']) tap = Tap(partition_dict['tap']['name'])
if tap_gateway_interface:
tap.ipv4_addr = partition_dict['tap'].get('ipv4_addr', '') tap.ipv4_addr = partition_dict['tap'].get('ipv4_addr', '')
tap.ipv4_netmask = partition_dict['tap'].get('ipv4_netmask', '') tap.ipv4_netmask = partition_dict['tap'].get('ipv4_netmask', '')
tap.ipv4_gateway = partition_dict['tap'].get('ipv4_gateway', '') tap.ipv4_gateway = partition_dict['tap'].get('ipv4_gateway', '')
...@@ -571,12 +570,20 @@ class Computer(object): ...@@ -571,12 +570,20 @@ class Computer(object):
instance_external_list.append(data_path) instance_external_list.append(data_path)
tap_address_list = [] tap_address_list = []
if alter_network and self.tap_gateway_interface and create_tap: if alter_network and create_tap:
if self.tap_gateway_interface:
gateway_addr_dict = getIfaceAddressIPv4(self.tap_gateway_interface) gateway_addr_dict = getIfaceAddressIPv4(self.tap_gateway_interface)
tap_address_list = getIPv4SubnetAddressRange(gateway_addr_dict['addr'], tap_address_list = getIPv4SubnetAddressRange(gateway_addr_dict['addr'],
gateway_addr_dict['netmask'], gateway_addr_dict['netmask'],
len(self.partition_list)) len(self.partition_list))
assert(len(self.partition_list) <= len(tap_address_list)) assert(len(self.partition_list) <= len(tap_address_list))
else:
gateway_addr_dict = {'peer': '10.0.0.1', 'netmask': '255.255.0.0',
'addr': '10.0.0.1', 'network': '10.0.0.0'}
tap_address_list = getIPv4SubnetAddressRange(gateway_addr_dict['addr'],
gateway_addr_dict['netmask'],
len(self.partition_list))
if alter_network: if alter_network:
self._speedHackAddAllOldIpsToInterface() self._speedHackAddAllOldIpsToInterface()
...@@ -607,7 +614,7 @@ class Computer(object): ...@@ -607,7 +614,7 @@ class Computer(object):
partition.tap.createWithOwner(owner) partition.tap.createWithOwner(owner)
# If tap_gateway_interface is specified, we don't add tap to bridge # If tap_gateway_interface is specified, we don't add tap to bridge
# but we create route for this tap # but we create route for this tap
if not self.tap_gateway_interface: if not self.tap_gateway_interface and self.interface.attach_to_tap:
self.interface.addTap(partition.tap) self.interface.addTap(partition.tap)
else: else:
next_ipv4_addr = '%s' % tap_address_list.pop(0) next_ipv4_addr = '%s' % tap_address_list.pop(0)
...@@ -617,6 +624,14 @@ class Computer(object): ...@@ -617,6 +624,14 @@ class Computer(object):
partition.tap.ipv4_netmask = gateway_addr_dict['netmask'] partition.tap.ipv4_netmask = gateway_addr_dict['netmask']
partition.tap.ipv4_gateway = gateway_addr_dict['addr'] partition.tap.ipv4_gateway = gateway_addr_dict['addr']
partition.tap.ipv4_network = gateway_addr_dict['network'] partition.tap.ipv4_network = gateway_addr_dict['network']
if not partition.tap.ipv6_addr:
ipv6_addr = self.interface.addAddr(tap=partition.tap)
partition.tap.ipv6_addr = ""
partition.tap.ipv6_netmask = ""
partition.tap.ipv6_gateway = ""
partition.tap.ipv6_network = ""
partition.tap.createRoutes() partition.tap.createRoutes()
if alter_network and partition.tun is not None: if alter_network and partition.tun is not None:
...@@ -835,6 +850,11 @@ class Tap(object): ...@@ -835,6 +850,11 @@ class Tap(object):
self.ipv4_netmask = "" self.ipv4_netmask = ""
self.ipv4_gateway = "" self.ipv4_gateway = ""
self.ipv4_network = "" self.ipv4_network = ""
self.ipv6_addr = ""
self.ipv6_netmask = ""
self.ipv6_gateway = ""
self.ipv6_network = ""
def __getinitargs__(self): def __getinitargs__(self):
return (self.name,) return (self.name,)
...@@ -1024,7 +1044,7 @@ class Interface(object): ...@@ -1024,7 +1044,7 @@ class Interface(object):
netaddr.cidr_to_glob(self.ipv4_local_network)) netaddr.cidr_to_glob(self.ipv4_local_network))
] ]
def getGlobalScopeAddressList(self): def getGlobalScopeAddressList(self, tap=None):
"""Returns currently configured global scope IPv6 addresses""" """Returns currently configured global scope IPv6 addresses"""
if self.ipv6_interface: if self.ipv6_interface:
interface_name = self.ipv6_interface interface_name = self.ipv6_interface
...@@ -1039,6 +1059,17 @@ class Interface(object): ...@@ -1039,6 +1059,17 @@ class Interface(object):
except KeyError: except KeyError:
raise ValueError("%s must have at least one IPv6 address assigned" % raise ValueError("%s must have at least one IPv6 address assigned" %
interface_name) interface_name)
if tap:
try:
address_list += [
q
for q in netifaces.ifaddresses(tap.name)[socket.AF_INET6]
if isGlobalScopeAddress(q['addr'].split('%')[0])
]
except KeyError:
pass
if sys.platform == 'cygwin': if sys.platform == 'cygwin':
for q in address_list: for q in address_list:
q.setdefault('netmask', 'FFFF:FFFF:FFFF:FFFF::') q.setdefault('netmask', 'FFFF:FFFF:FFFF:FFFF::')
...@@ -1094,13 +1125,14 @@ class Interface(object): ...@@ -1094,13 +1125,14 @@ class Interface(object):
"TUN/TAP interface {} might not have internet connection." "TUN/TAP interface {} might not have internet connection."
"".format(self.name, tap.name)) "".format(self.name, tap.name))
def _addSystemAddress(self, address, netmask, ipv6=True): def _addSystemAddress(self, address, netmask, ipv6=True, tap=None):
"""Adds system address to interface """Adds system address to interface
Returns True if address was added successfully. Returns True if address was added successfully.
Returns False if there was issue. Returns False if there was issue.
""" """
if ipv6: if ipv6:
address_string = '%s/%s' % (address, netmaskToPrefixIPv6(netmask)) address_string = '%s/%s' % (address, netmaskToPrefixIPv6(netmask))
af = socket.AF_INET6 af = socket.AF_INET6
...@@ -1113,6 +1145,9 @@ class Interface(object): ...@@ -1113,6 +1145,9 @@ class Interface(object):
address_string = '%s/%s' % (address, netmaskToPrefixIPv4(netmask)) address_string = '%s/%s' % (address, netmaskToPrefixIPv4(netmask))
interface_name = self.name interface_name = self.name
if tap:
interface_name = tap.name
# check if address is already took by any other interface # check if address is already took by any other interface
for interface in netifaces.interfaces(): for interface in netifaces.interfaces():
if interface != interface_name: if interface != interface_name:
...@@ -1143,7 +1178,7 @@ class Interface(object): ...@@ -1143,7 +1178,7 @@ class Interface(object):
_, result = callAndRead(['ip', '-6', 'addr', 'list', interface_name]) _, result = callAndRead(['ip', '-6', 'addr', 'list', interface_name])
for l in result.split('\n'): for l in result.split('\n'):
if address in l: if address in l:
if 'tentative' in l: if 'tentative' in l and not tap:
# duplicate, remove # duplicate, remove
callAndRead(['ip', 'addr', 'del', address_string, 'dev', interface_name]) callAndRead(['ip', 'addr', 'del', address_string, 'dev', interface_name])
return False return False
...@@ -1186,7 +1221,7 @@ class Interface(object): ...@@ -1186,7 +1221,7 @@ class Interface(object):
# confirmed to be configured # confirmed to be configured
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
def addAddr(self, addr=None, netmask=None): def addAddr(self, addr=None, netmask=None, tap=None):
""" """
Adds IP address to interface. Adds IP address to interface.
...@@ -1199,6 +1234,7 @@ class Interface(object): ...@@ -1199,6 +1234,7 @@ class Interface(object):
Args: Args:
addr: Wished address to be added to interface. addr: Wished address to be added to interface.
netmask: Wished netmask to be used. netmask: Wished netmask to be used.
tap: tap interface
Returns: Returns:
Tuple of (address, netmask). Tuple of (address, netmask).
...@@ -1233,7 +1269,7 @@ class Interface(object): ...@@ -1233,7 +1269,7 @@ class Interface(object):
netmaskToPrefixIPv6(netmask))) netmaskToPrefixIPv6(netmask)))
if interface_network.network == requested_network.network: if interface_network.network == requested_network.network:
# same network, try to add # same network, try to add
if self._addSystemAddress(addr, netmask): if self._addSystemAddress(addr, netmask, tap=tap):
# succeed, return it # succeed, return it
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
else: else:
...@@ -1244,13 +1280,22 @@ class Interface(object): ...@@ -1244,13 +1280,22 @@ class Interface(object):
try_num = 10 try_num = 10
netmask = address_dict['netmask'] netmask = address_dict['netmask']
while try_num > 0: while try_num > 0:
if tap:
cut = -3
if "::" in address_dict['addr']:
cut = -2
addr = ':'.join(address_dict['addr'].split(':')[:cut] + ['%x' % (
random.randint(1, 65000), )] + ["ff", "ff"])
netmask = "ffff:ffff:ffff:ffff:ffff:ffff::"
else:
addr = ':'.join(address_dict['addr'].split(':')[:-1] + ['%x' % ( addr = ':'.join(address_dict['addr'].split(':')[:-1] + ['%x' % (
random.randint(1, 65000), )]) random.randint(1, 65000), )])
socket.inet_pton(socket.AF_INET6, addr) socket.inet_pton(socket.AF_INET6, addr)
if (dict(addr=addr, netmask=netmask) not in if (dict(addr=addr, netmask=netmask) not in
self.getGlobalScopeAddressList()): self.getGlobalScopeAddressList(tap=tap)):
# Checking the validity of the IPv6 address # Checking the validity of the IPv6 address
if self._addSystemAddress(addr, netmask): if self._addSystemAddress(addr, netmask, tap=tap):
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
try_num -= 1 try_num -= 1
......
...@@ -414,7 +414,6 @@ class TestComputer(SlapformatMixin): ...@@ -414,7 +414,6 @@ class TestComputer(SlapformatMixin):
'netmask': '255.255.255.0'}], 'netmask': '255.255.255.0'}],
socket.AF_INET6: [{'addr': '2a01:e35:2e27::e59c', 'netmask': 'ffff:ffff:ffff:ffff::'}] socket.AF_INET6: [{'addr': '2a01:e35:2e27::e59c', 'netmask': 'ffff:ffff:ffff:ffff::'}]
} }
computer.format() computer.format()
self.assertEqual([ self.assertEqual([
"makedirs('/instance_root', 493)", "makedirs('/instance_root', 493)",
...@@ -463,6 +462,10 @@ class TestComputer(SlapformatMixin): ...@@ -463,6 +462,10 @@ class TestComputer(SlapformatMixin):
socket.AF_INET6: [{'addr': '2a01:e35:2e27::e59c', 'netmask': 'ffff:ffff:ffff:ffff::'}] socket.AF_INET6: [{'addr': '2a01:e35:2e27::e59c', 'netmask': 'ffff:ffff:ffff:ffff::'}]
} }
INTERFACE_DICT['tap'] = {
socket.AF_INET6: [{'addr': '2a01:e35:2e27::e59c', 'netmask': 'ffff:ffff:ffff:ffff::'}]
}
computer.format(alter_user=False) computer.format(alter_user=False)
self.assertEqual([ self.assertEqual([
"makedirs('/instance_root', 493)", "makedirs('/instance_root', 493)",
...@@ -477,9 +480,13 @@ class TestComputer(SlapformatMixin): ...@@ -477,9 +480,13 @@ class TestComputer(SlapformatMixin):
'brctl show', 'brctl show',
'ip tuntap add dev tap mode tap user testuser', 'ip tuntap add dev tap mode tap user testuser',
'ip link set tap up', 'ip link set tap up',
'brctl show', #'brctl show',
'brctl show', #'brctl show',
'brctl addif bridge tap', #'brctl addif bridge tap',
'ip addr add ip/ffff:ffff:ffff:ffff:ffff:ffff:: dev tap',
'ip -6 addr list tap',
'ip route show 10.0.0.2',
'ip route add 10.0.0.2 dev tap',
'ip addr add ip/255.255.255.255 dev bridge', 'ip addr add ip/255.255.255.255 dev bridge',
# 'ip addr list bridge', # 'ip addr list bridge',
'ip addr add ip/ffff:ffff:ffff:ffff:: dev bridge', 'ip addr add ip/ffff:ffff:ffff:ffff:: dev bridge',
...@@ -512,6 +519,10 @@ class TestComputer(SlapformatMixin): ...@@ -512,6 +519,10 @@ class TestComputer(SlapformatMixin):
'netmask': '255.255.255.0'}] 'netmask': '255.255.255.0'}]
} }
INTERFACE_DICT['tap'] = {
socket.AF_INET6: [{'addr': '2a01:e35:2e27::e59c', 'netmask': 'ffff:ffff:ffff:ffff::'}]
}
computer.format(alter_user=False) computer.format(alter_user=False)
self.assertEqual([ self.assertEqual([
"makedirs('/instance_root', 493)", "makedirs('/instance_root', 493)",
...@@ -526,6 +537,8 @@ class TestComputer(SlapformatMixin): ...@@ -526,6 +537,8 @@ class TestComputer(SlapformatMixin):
'brctl show', 'brctl show',
'ip tuntap add dev tap mode tap user testuser', 'ip tuntap add dev tap mode tap user testuser',
'ip link set tap up', 'ip link set tap up',
'ip addr add ip/ffff:ffff:ffff:ffff:ffff:ffff:: dev tap',
'ip -6 addr list tap',
'ip route show 10.8.0.2', 'ip route show 10.8.0.2',
'ip route add 10.8.0.2 dev tap', 'ip route add 10.8.0.2 dev tap',
'ip addr add ip/255.255.255.255 dev iface', 'ip addr add ip/255.255.255.255 dev iface',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment