daemon: updates to support configuring and tracking mtu, along with over refactoring
This commit is contained in:
parent
0b531d7fd8
commit
871b1ae2af
7 changed files with 93 additions and 151 deletions
|
@ -196,10 +196,10 @@ class DistributedController:
|
|||
continue
|
||||
for name in self.servers:
|
||||
server = self.servers[name]
|
||||
self.create_gre_tunnel(node, server, mtu)
|
||||
self.create_gre_tunnel(node, server, mtu, True)
|
||||
|
||||
def create_gre_tunnel(
|
||||
self, node: CoreNetwork, server: DistributedServer, mtu: int
|
||||
self, node: CoreNetwork, server: DistributedServer, mtu: int, start: bool
|
||||
) -> Tuple[GreTap, GreTap]:
|
||||
"""
|
||||
Create gre tunnel using a pair of gre taps between the local and remote server.
|
||||
|
@ -207,6 +207,7 @@ class DistributedController:
|
|||
:param node: node to create gre tunnel for
|
||||
:param server: server to create tunnel for
|
||||
:param mtu: mtu for gre taps
|
||||
:param start: True to start gre taps, False otherwise
|
||||
:return: local and remote gre taps created for tunnel
|
||||
"""
|
||||
host = server.host
|
||||
|
@ -216,15 +217,17 @@ class DistributedController:
|
|||
return tunnel
|
||||
# local to server
|
||||
logger.info("local tunnel node(%s) to remote(%s) key(%s)", node.name, host, key)
|
||||
local_tap = GreTap(session=self.session, remoteip=host, key=key, mtu=mtu)
|
||||
local_tap = GreTap(self.session, host, key=key, mtu=mtu)
|
||||
if start:
|
||||
local_tap.startup()
|
||||
local_tap.net_client.set_iface_master(node.brname, local_tap.localname)
|
||||
# server to local
|
||||
logger.info(
|
||||
"remote tunnel node(%s) to local(%s) key(%s)", node.name, self.address, key
|
||||
)
|
||||
remote_tap = GreTap(
|
||||
session=self.session, remoteip=self.address, key=key, server=server, mtu=mtu
|
||||
)
|
||||
remote_tap = GreTap(self.session, self.address, key=key, server=server, mtu=mtu)
|
||||
if start:
|
||||
remote_tap.startup()
|
||||
remote_tap.net_client.set_iface_master(node.brname, remote_tap.localname)
|
||||
# save tunnels for shutdown
|
||||
tunnel = (local_tap, remote_tap)
|
||||
|
|
|
@ -1496,6 +1496,7 @@ class Session:
|
|||
mac=utils.random_mac(),
|
||||
ip4=ip4,
|
||||
ip4_mask=ip4_mask,
|
||||
mtu=DEFAULT_MTU,
|
||||
)
|
||||
iface = node.new_iface(control_net, iface_data)
|
||||
iface.control = True
|
||||
|
|
|
@ -712,9 +712,7 @@ class CoreNode(CoreNodeBase):
|
|||
with self.lock:
|
||||
return super().next_iface_id()
|
||||
|
||||
def newveth(
|
||||
self, iface_id: int = None, ifname: str = None, mtu: int = DEFAULT_MTU
|
||||
) -> int:
|
||||
def newveth(self, iface_id: int = None, ifname: str = None, mtu: int = None) -> int:
|
||||
"""
|
||||
Create a new interface.
|
||||
|
||||
|
@ -724,6 +722,7 @@ class CoreNode(CoreNodeBase):
|
|||
:return: nothing
|
||||
"""
|
||||
with self.lock:
|
||||
mtu = mtu if mtu is not None else DEFAULT_MTU
|
||||
iface_id = iface_id if iface_id is not None else self.next_iface_id()
|
||||
ifname = ifname if ifname is not None else f"eth{iface_id}"
|
||||
sessionid = self.session.short_session_id()
|
||||
|
@ -732,32 +731,9 @@ class CoreNode(CoreNodeBase):
|
|||
except TypeError:
|
||||
suffix = f"{self.id}.{iface_id}.{sessionid}"
|
||||
localname = f"veth{suffix}"
|
||||
if len(localname) >= 16:
|
||||
raise CoreError(f"interface local name ({localname}) too long")
|
||||
name = f"{localname}p"
|
||||
if len(name) >= 16:
|
||||
raise CoreError(f"interface name ({name}) too long")
|
||||
veth = Veth(self.session, self, name, localname, mtu, self.server, self.up)
|
||||
if self.up:
|
||||
self.net_client.device_ns(veth.name, str(self.pid))
|
||||
self.node_net_client.device_name(veth.name, ifname)
|
||||
self.node_net_client.checksums_off(ifname)
|
||||
veth.name = ifname
|
||||
if self.up:
|
||||
flow_id = self.node_net_client.get_ifindex(veth.name)
|
||||
veth.flow_id = int(flow_id)
|
||||
logger.debug("interface flow index: %s - %s", veth.name, veth.flow_id)
|
||||
mac = self.node_net_client.get_mac(veth.name)
|
||||
logger.debug("interface mac: %s - %s", veth.name, mac)
|
||||
veth.set_mac(mac)
|
||||
try:
|
||||
# add network interface to the node. If unsuccessful, destroy the
|
||||
# network interface and raise exception.
|
||||
self.add_iface(veth, iface_id)
|
||||
except CoreError as e:
|
||||
veth.shutdown()
|
||||
del veth
|
||||
raise e
|
||||
veth = Veth(self.session, name, localname, mtu, self.server, self)
|
||||
veth.adopt_node(iface_id, ifname, self.up)
|
||||
return iface_id
|
||||
|
||||
def newtuntap(self, iface_id: int = None, ifname: str = None) -> int:
|
||||
|
@ -774,12 +750,13 @@ class CoreNode(CoreNodeBase):
|
|||
sessionid = self.session.short_session_id()
|
||||
localname = f"tap{self.id}.{iface_id}.{sessionid}"
|
||||
name = ifname
|
||||
tuntap = TunTap(self.session, self, name, localname, start=self.up)
|
||||
tuntap = TunTap(self.session, name, localname, node=self)
|
||||
if self.up:
|
||||
tuntap.startup()
|
||||
try:
|
||||
self.add_iface(tuntap, iface_id)
|
||||
except CoreError as e:
|
||||
tuntap.shutdown()
|
||||
del tuntap
|
||||
raise e
|
||||
return iface_id
|
||||
|
||||
|
|
|
@ -33,25 +33,28 @@ class CoreInterface:
|
|||
def __init__(
|
||||
self,
|
||||
session: "Session",
|
||||
node: "CoreNode",
|
||||
name: str,
|
||||
localname: str,
|
||||
mtu: int,
|
||||
mtu: int = DEFAULT_MTU,
|
||||
server: "DistributedServer" = None,
|
||||
node: "CoreNode" = None,
|
||||
) -> None:
|
||||
"""
|
||||
Creates a CoreInterface instance.
|
||||
|
||||
:param session: core session instance
|
||||
:param node: node for interface
|
||||
:param name: interface name
|
||||
:param localname: interface local name
|
||||
:param mtu: mtu value
|
||||
:param server: remote server node
|
||||
will run on, default is None for localhost
|
||||
:param server: remote server node will run on, default is None for localhost
|
||||
:param node: node for interface
|
||||
"""
|
||||
if len(name) >= 16:
|
||||
raise CoreError(f"interface name ({name}) too long, max 16")
|
||||
if len(localname) >= 16:
|
||||
raise CoreError(f"interface local name ({localname}) too long, max 16")
|
||||
self.session: "Session" = session
|
||||
self.node: "CoreNode" = node
|
||||
self.node: Optional["CoreNode"] = node
|
||||
self.name: str = name
|
||||
self.localname: str = localname
|
||||
self.up: bool = False
|
||||
|
@ -128,7 +131,6 @@ class CoreInterface:
|
|||
if self.net:
|
||||
self.detachnet()
|
||||
self.net = None
|
||||
|
||||
net.attach(self)
|
||||
self.net = net
|
||||
|
||||
|
@ -279,11 +281,9 @@ class CoreInterface:
|
|||
logger.debug("setting param: %s - %s", key, value)
|
||||
if value is None or value < 0:
|
||||
return False
|
||||
|
||||
current_value = self._params.get(key)
|
||||
if current_value is not None and current_value == value:
|
||||
return False
|
||||
|
||||
self._params[key] = value
|
||||
return True
|
||||
|
||||
|
@ -342,33 +342,32 @@ class Veth(CoreInterface):
|
|||
Provides virtual ethernet functionality for core nodes.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
session: "Session",
|
||||
node: "CoreNode",
|
||||
name: str,
|
||||
localname: str,
|
||||
mtu: int = DEFAULT_MTU,
|
||||
server: "DistributedServer" = None,
|
||||
start: bool = True,
|
||||
) -> None:
|
||||
def adopt_node(self, iface_id: int, name: str, start: bool) -> None:
|
||||
"""
|
||||
Creates a VEth instance.
|
||||
Adopt this interface to the provided node, configuring and associating
|
||||
with the node as needed.
|
||||
|
||||
:param session: core session instance
|
||||
:param node: related core node
|
||||
:param name: interface name
|
||||
:param localname: interface local name
|
||||
:param mtu: interface mtu
|
||||
:param server: remote server node
|
||||
will run on, default is None for localhost
|
||||
:param start: start flag
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
:param iface_id: interface id for node
|
||||
:param name: name of interface fo rnode
|
||||
:param start: True to start interface, False otherwise
|
||||
:return: nothing
|
||||
"""
|
||||
# note that net arg is ignored
|
||||
super().__init__(session, node, name, localname, mtu, server)
|
||||
if start:
|
||||
self.startup()
|
||||
self.net_client.device_ns(self.name, str(self.node.pid))
|
||||
self.node.node_net_client.checksums_off(self.name)
|
||||
self.flow_id = self.node.node_net_client.get_ifindex(self.name)
|
||||
logger.debug("interface flow index: %s - %s", self.name, self.flow_id)
|
||||
mac = self.node.node_net_client.get_mac(self.name)
|
||||
logger.debug("interface mac: %s - %s", self.name, mac)
|
||||
self.set_mac(mac)
|
||||
self.node.node_net_client.device_name(self.name, name)
|
||||
self.name = name
|
||||
try:
|
||||
self.node.add_iface(self, iface_id)
|
||||
except CoreError as e:
|
||||
self.shutdown()
|
||||
raise e
|
||||
|
||||
def startup(self) -> None:
|
||||
"""
|
||||
|
@ -410,32 +409,6 @@ class TunTap(CoreInterface):
|
|||
TUN/TAP virtual device in TAP mode
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
session: "Session",
|
||||
node: "CoreNode",
|
||||
name: str,
|
||||
localname: str,
|
||||
mtu: int = DEFAULT_MTU,
|
||||
server: "DistributedServer" = None,
|
||||
start: bool = True,
|
||||
) -> None:
|
||||
"""
|
||||
Create a TunTap instance.
|
||||
|
||||
:param session: core session instance
|
||||
:param node: related core node
|
||||
:param name: interface name
|
||||
:param localname: local interface name
|
||||
:param mtu: interface mtu
|
||||
:param server: remote server node
|
||||
will run on, default is None for localhost
|
||||
:param start: start flag
|
||||
"""
|
||||
super().__init__(session, node, name, localname, mtu, server)
|
||||
if start:
|
||||
self.startup()
|
||||
|
||||
def startup(self) -> None:
|
||||
"""
|
||||
Startup logic for a tunnel tap.
|
||||
|
@ -582,47 +555,53 @@ class GreTap(CoreInterface):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
session: "Session",
|
||||
remoteip: str,
|
||||
key: int = None,
|
||||
node: "CoreNode" = None,
|
||||
name: str = None,
|
||||
session: "Session" = None,
|
||||
mtu: int = DEFAULT_MTU,
|
||||
remoteip: str = None,
|
||||
_id: int = None,
|
||||
localip: str = None,
|
||||
ttl: int = 255,
|
||||
key: int = None,
|
||||
start: bool = True,
|
||||
server: "DistributedServer" = None,
|
||||
) -> None:
|
||||
"""
|
||||
Creates a GreTap instance.
|
||||
|
||||
:param node: related core node
|
||||
:param name: interface name
|
||||
:param session: core session instance
|
||||
:param mtu: interface mtu
|
||||
:param remoteip: remote address
|
||||
:param key: gre tap key
|
||||
:param node: related core node
|
||||
:param mtu: interface mtu
|
||||
:param _id: object id
|
||||
:param localip: local address
|
||||
:param ttl: ttl value
|
||||
:param key: gre tap key
|
||||
:param start: start flag
|
||||
:param server: remote server node
|
||||
will run on, default is None for localhost
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
"""
|
||||
if _id is None:
|
||||
_id = ((id(self) >> 16) ^ (id(self) & 0xFFFF)) & 0xFFFF
|
||||
self.id = _id
|
||||
self.id: int = _id
|
||||
sessionid = session.short_session_id()
|
||||
localname = f"gt.{self.id}.{sessionid}"
|
||||
super().__init__(session, node, name, localname, mtu, server)
|
||||
self.transport_type = TransportType.RAW
|
||||
if not start:
|
||||
return
|
||||
if remoteip is None:
|
||||
raise CoreError("missing remote IP required for GRE TAP device")
|
||||
self.net_client.create_gretap(self.localname, remoteip, localip, ttl, key)
|
||||
name = f"{localname}p"
|
||||
super().__init__(session, name, localname, mtu, server, node)
|
||||
self.transport_type: TransportType = TransportType.RAW
|
||||
self.remote_ip: str = remoteip
|
||||
self.ttl: int = ttl
|
||||
self.key: Optional[int] = key
|
||||
self.local_ip: Optional[str] = localip
|
||||
|
||||
def startup(self) -> None:
|
||||
"""
|
||||
Startup logic for a GreTap.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.net_client.create_gretap(
|
||||
self.localname, self.remote_ip, self.local_ip, self.ttl, self.key
|
||||
)
|
||||
if self.mtu > 0:
|
||||
self.net_client.set_mtu(self.localname, self.mtu)
|
||||
self.net_client.device_up(self.localname)
|
||||
|
|
|
@ -95,14 +95,14 @@ class LinuxNetClient:
|
|||
"""
|
||||
return self.run(f"cat /sys/class/net/{device}/address")
|
||||
|
||||
def get_ifindex(self, device: str) -> str:
|
||||
def get_ifindex(self, device: str) -> int:
|
||||
"""
|
||||
Retrieve ifindex for a given device.
|
||||
|
||||
:param device: device to get ifindex for
|
||||
:return: ifindex
|
||||
"""
|
||||
return self.run(f"cat /sys/class/net/{device}/ifindex")
|
||||
return int(self.run(f"cat /sys/class/net/{device}/ifindex"))
|
||||
|
||||
def device_ns(self, device: str, namespace: str) -> None:
|
||||
"""
|
||||
|
|
|
@ -484,21 +484,15 @@ class CoreNetwork(CoreNetworkBase):
|
|||
_id = f"{self.id:x}"
|
||||
except TypeError:
|
||||
_id = str(self.id)
|
||||
|
||||
try:
|
||||
net_id = f"{net.id:x}"
|
||||
except TypeError:
|
||||
net_id = str(net.id)
|
||||
|
||||
localname = f"veth{_id}.{net_id}.{sessionid}"
|
||||
if len(localname) >= 16:
|
||||
raise ValueError(f"interface local name {localname} too long")
|
||||
|
||||
name = f"veth{net_id}.{_id}.{sessionid}"
|
||||
if len(name) >= 16:
|
||||
raise ValueError(f"interface name {name} too long")
|
||||
|
||||
iface = Veth(self.session, None, name, localname, start=self.up)
|
||||
iface = Veth(self.session, name, localname)
|
||||
if self.up:
|
||||
iface.startup()
|
||||
self.attach(iface)
|
||||
if net.up and net.brname:
|
||||
iface.net_client.set_iface_master(net.brname, iface.name)
|
||||
|
@ -578,14 +572,14 @@ class GreTapBridge(CoreNetwork):
|
|||
self.localip: Optional[str] = localip
|
||||
self.ttl: int = ttl
|
||||
self.gretap: Optional[GreTap] = None
|
||||
if remoteip is not None:
|
||||
if self.remoteip is not None:
|
||||
self.gretap = GreTap(
|
||||
session,
|
||||
remoteip,
|
||||
key=self.grekey,
|
||||
node=self,
|
||||
session=session,
|
||||
remoteip=remoteip,
|
||||
localip=localip,
|
||||
ttl=ttl,
|
||||
key=self.grekey,
|
||||
mtu=self.mtu,
|
||||
)
|
||||
|
||||
|
@ -597,6 +591,7 @@ class GreTapBridge(CoreNetwork):
|
|||
"""
|
||||
super().startup()
|
||||
if self.gretap:
|
||||
self.gretap.startup()
|
||||
self.attach(self.gretap)
|
||||
|
||||
def shutdown(self) -> None:
|
||||
|
@ -628,13 +623,14 @@ class GreTapBridge(CoreNetwork):
|
|||
if len(ips) > 1:
|
||||
localip = ips[1].split("/")[0]
|
||||
self.gretap = GreTap(
|
||||
session=self.session,
|
||||
remoteip=remoteip,
|
||||
self.session,
|
||||
remoteip,
|
||||
key=self.grekey,
|
||||
localip=localip,
|
||||
ttl=self.ttl,
|
||||
key=self.grekey,
|
||||
mtu=self.mtu,
|
||||
)
|
||||
self.startup()
|
||||
self.attach(self.gretap)
|
||||
|
||||
def setkey(self, key: int, iface_data: InterfaceData) -> None:
|
||||
|
|
|
@ -14,7 +14,7 @@ from core.errors import CoreCommandError, CoreError
|
|||
from core.executables import MOUNT, TEST, UMOUNT
|
||||
from core.nodes.base import CoreNetworkBase, CoreNodeBase
|
||||
from core.nodes.interface import DEFAULT_MTU, CoreInterface
|
||||
from core.nodes.network import CoreNetwork, GreTap
|
||||
from core.nodes.network import CoreNetwork
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -173,25 +173,11 @@ class PhysicalNode(CoreNodeBase):
|
|||
name = iface_data.name
|
||||
if name is None:
|
||||
name = f"gt{iface_id}"
|
||||
if self.up:
|
||||
# this is reached when this node is linked to a network node
|
||||
# tunnel to net not built yet, so build it now and adopt it
|
||||
_, remote_tap = self.session.distributed.create_gre_tunnel(
|
||||
net, self.server, iface_data.mtu
|
||||
net, self.server, iface_data.mtu, self.up
|
||||
)
|
||||
self.adopt_iface(remote_tap, iface_id, iface_data.mac, ips)
|
||||
return remote_tap
|
||||
else:
|
||||
# this is reached when configuring services (self.up=False)
|
||||
iface = GreTap(
|
||||
node=self,
|
||||
name=name,
|
||||
session=self.session,
|
||||
start=False,
|
||||
mtu=iface_data.mtu,
|
||||
)
|
||||
self.adopt_iface(iface, iface_id, iface_data.mac, ips)
|
||||
return iface
|
||||
|
||||
def privatedir(self, dir_path: Path) -> None:
|
||||
if not str(dir_path).startswith("/"):
|
||||
|
|
Loading…
Reference in a new issue