changes to make rj45 maintain the interface information, instead of trying to be 2 classes at once
This commit is contained in:
parent
8fed201fd8
commit
7e4ef0b280
5 changed files with 47 additions and 74 deletions
|
@ -353,7 +353,7 @@ class Session:
|
||||||
node_two.name,
|
node_two.name,
|
||||||
)
|
)
|
||||||
start = self.state.should_start()
|
start = self.state.should_start()
|
||||||
net_one = self.create_node(_class=PtpNet, start=start)
|
net_one = self.create_node(PtpNet, start=start)
|
||||||
|
|
||||||
# node to network
|
# node to network
|
||||||
if node_one and net_one:
|
if node_one and net_one:
|
||||||
|
|
|
@ -71,13 +71,22 @@ class LinuxNetClient:
|
||||||
|
|
||||||
def device_show(self, device: str) -> str:
|
def device_show(self, device: str) -> str:
|
||||||
"""
|
"""
|
||||||
Show information for a device.
|
Show link information for a device.
|
||||||
|
|
||||||
:param device: device to get information for
|
:param device: device to get information for
|
||||||
:return: device information
|
:return: device information
|
||||||
"""
|
"""
|
||||||
return self.run(f"{IP_BIN} link show {device}")
|
return self.run(f"{IP_BIN} link show {device}")
|
||||||
|
|
||||||
|
def address_show(self, device: str) -> str:
|
||||||
|
"""
|
||||||
|
Show address information for a device.
|
||||||
|
|
||||||
|
:param device: device name
|
||||||
|
:return: address information
|
||||||
|
"""
|
||||||
|
return self.run(f"{IP_BIN} address show {device}")
|
||||||
|
|
||||||
def get_mac(self, device: str) -> str:
|
def get_mac(self, device: str) -> str:
|
||||||
"""
|
"""
|
||||||
Retrieve MAC address for a given device.
|
Retrieve MAC address for a given device.
|
||||||
|
@ -114,7 +123,8 @@ class LinuxNetClient:
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
self.run(
|
self.run(
|
||||||
f"[ -e /sys/class/net/{device} ] && {IP_BIN} -6 address flush dev {device} || true",
|
f"[ -e /sys/class/net/{device} ] && "
|
||||||
|
f"{IP_BIN} address flush dev {device} || true",
|
||||||
shell=True,
|
shell=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ class PhysicalNode(CoreNodeBase):
|
||||||
return self.host_cmd(args, wait=wait)
|
return self.host_cmd(args, wait=wait)
|
||||||
|
|
||||||
|
|
||||||
class Rj45Node(CoreNodeBase, CoreInterface):
|
class Rj45Node(CoreNodeBase):
|
||||||
"""
|
"""
|
||||||
RJ45Node is a physical interface on the host linked to the emulated
|
RJ45Node is a physical interface on the host linked to the emulated
|
||||||
network.
|
network.
|
||||||
|
@ -279,13 +279,13 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:param server: remote server node
|
:param server: remote server node
|
||||||
will run on, default is None for localhost
|
will run on, default is None for localhost
|
||||||
"""
|
"""
|
||||||
CoreNodeBase.__init__(self, session, _id, name, start, server)
|
super().__init__(session, _id, name, start, server)
|
||||||
CoreInterface.__init__(self, session, self, name, name, mtu, server)
|
self.interface = CoreInterface(session, self, name, name, mtu, server)
|
||||||
|
self.interface.transport_type = "raw"
|
||||||
self.lock: threading.RLock = threading.RLock()
|
self.lock: threading.RLock = threading.RLock()
|
||||||
self.ifindex: Optional[int] = None
|
self.ifindex: Optional[int] = None
|
||||||
self.transport_type: str = "raw"
|
|
||||||
self.old_up: bool = False
|
self.old_up: bool = False
|
||||||
self.old_addrs: List[str] = []
|
self.old_addrs: List[Tuple[str, Optional[str]]] = []
|
||||||
if start:
|
if start:
|
||||||
self.startup()
|
self.startup()
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
"""
|
"""
|
||||||
# interface will also be marked up during net.attach()
|
# interface will also be marked up during net.attach()
|
||||||
self.savestate()
|
self.savestate()
|
||||||
self.net_client.device_up(self.localname)
|
self.net_client.device_up(self.interface.localname)
|
||||||
self.up = True
|
self.up = True
|
||||||
|
|
||||||
def shutdown(self) -> None:
|
def shutdown(self) -> None:
|
||||||
|
@ -310,38 +310,16 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
"""
|
"""
|
||||||
if not self.up:
|
if not self.up:
|
||||||
return
|
return
|
||||||
|
localname = self.interface.localname
|
||||||
|
self.net_client.device_down(localname)
|
||||||
|
self.net_client.device_flush(localname)
|
||||||
try:
|
try:
|
||||||
self.net_client.device_down(self.localname)
|
self.net_client.delete_tc(localname)
|
||||||
self.net_client.device_flush(self.localname)
|
|
||||||
self.net_client.delete_tc(self.localname)
|
|
||||||
except CoreCommandError:
|
except CoreCommandError:
|
||||||
logging.exception("error shutting down")
|
pass
|
||||||
|
|
||||||
self.up = False
|
self.up = False
|
||||||
self.restorestate()
|
self.restorestate()
|
||||||
|
|
||||||
# TODO: issue in that both classes inherited from provide the same method with
|
|
||||||
# different signatures
|
|
||||||
def attachnet(self, net: CoreNetworkBase) -> None:
|
|
||||||
"""
|
|
||||||
Attach a network.
|
|
||||||
|
|
||||||
:param net: network to attach
|
|
||||||
:return: nothing
|
|
||||||
"""
|
|
||||||
CoreInterface.attachnet(self, net)
|
|
||||||
|
|
||||||
# TODO: issue in that both classes inherited from provide the same method with
|
|
||||||
# different signatures
|
|
||||||
def detachnet(self) -> None:
|
|
||||||
"""
|
|
||||||
Detach a network.
|
|
||||||
|
|
||||||
:return: nothing
|
|
||||||
"""
|
|
||||||
CoreInterface.detachnet(self)
|
|
||||||
|
|
||||||
def newnetif(
|
def newnetif(
|
||||||
self,
|
self,
|
||||||
net: CoreNetworkBase = None,
|
net: CoreNetworkBase = None,
|
||||||
|
@ -366,22 +344,15 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
if ifindex is None:
|
if ifindex is None:
|
||||||
ifindex = 0
|
ifindex = 0
|
||||||
|
if self.interface.net is not None:
|
||||||
if self.net is not None:
|
|
||||||
raise ValueError("RJ45 nodes support at most 1 network interface")
|
raise ValueError("RJ45 nodes support at most 1 network interface")
|
||||||
|
self._netif[ifindex] = self.interface
|
||||||
self._netif[ifindex] = self
|
|
||||||
# PyCoreNetIf.node is self
|
|
||||||
self.node = self
|
|
||||||
self.ifindex = ifindex
|
self.ifindex = ifindex
|
||||||
|
|
||||||
if net is not None:
|
if net is not None:
|
||||||
self.attachnet(net)
|
self.interface.attachnet(net)
|
||||||
|
|
||||||
if addrlist:
|
if addrlist:
|
||||||
for addr in utils.make_tuple(addrlist):
|
for addr in utils.make_tuple(addrlist):
|
||||||
self.addaddr(addr)
|
self.addaddr(addr)
|
||||||
|
|
||||||
return ifindex
|
return ifindex
|
||||||
|
|
||||||
def delnetif(self, ifindex: int) -> None:
|
def delnetif(self, ifindex: int) -> None:
|
||||||
|
@ -393,9 +364,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
"""
|
"""
|
||||||
if ifindex is None:
|
if ifindex is None:
|
||||||
ifindex = 0
|
ifindex = 0
|
||||||
|
|
||||||
self._netif.pop(ifindex)
|
self._netif.pop(ifindex)
|
||||||
|
|
||||||
if ifindex == self.ifindex:
|
if ifindex == self.ifindex:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
else:
|
else:
|
||||||
|
@ -413,15 +382,12 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:param net: network to retrieve
|
:param net: network to retrieve
|
||||||
:return: a network interface
|
:return: a network interface
|
||||||
"""
|
"""
|
||||||
if net is not None and net == self.net:
|
if net is not None and net == self.interface.net:
|
||||||
return self
|
return self.interface
|
||||||
|
|
||||||
if ifindex is None:
|
if ifindex is None:
|
||||||
ifindex = 0
|
ifindex = 0
|
||||||
|
|
||||||
if ifindex == self.ifindex:
|
if ifindex == self.ifindex:
|
||||||
return self
|
return self.interface
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getifindex(self, netif: CoreInterface) -> Optional[int]:
|
def getifindex(self, netif: CoreInterface) -> Optional[int]:
|
||||||
|
@ -432,7 +398,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
index for
|
index for
|
||||||
:return: interface index, None otherwise
|
:return: interface index, None otherwise
|
||||||
"""
|
"""
|
||||||
if netif != self:
|
if netif != self.interface:
|
||||||
return None
|
return None
|
||||||
return self.ifindex
|
return self.ifindex
|
||||||
|
|
||||||
|
@ -447,7 +413,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
addr = utils.validate_ip(addr)
|
addr = utils.validate_ip(addr)
|
||||||
if self.up:
|
if self.up:
|
||||||
self.net_client.create_address(self.name, addr)
|
self.net_client.create_address(self.name, addr)
|
||||||
CoreInterface.addaddr(self, addr)
|
self.interface.addaddr(addr)
|
||||||
|
|
||||||
def deladdr(self, addr: str) -> None:
|
def deladdr(self, addr: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -458,8 +424,8 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:raises CoreCommandError: when there is a command exception
|
:raises CoreCommandError: when there is a command exception
|
||||||
"""
|
"""
|
||||||
if self.up:
|
if self.up:
|
||||||
self.net_client.delete_address(self.name, str(addr))
|
self.net_client.delete_address(self.name, addr)
|
||||||
CoreInterface.deladdr(self, addr)
|
self.interface.deladdr(addr)
|
||||||
|
|
||||||
def savestate(self) -> None:
|
def savestate(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -470,14 +436,14 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:raises CoreCommandError: when there is a command exception
|
:raises CoreCommandError: when there is a command exception
|
||||||
"""
|
"""
|
||||||
self.old_up = False
|
self.old_up = False
|
||||||
self.old_addrs = []
|
self.old_addrs: List[Tuple[str, Optional[str]]] = []
|
||||||
output = self.net_client.device_show(self.localname)
|
localname = self.interface.localname
|
||||||
|
output = self.net_client.address_show(localname)
|
||||||
for line in output.split("\n"):
|
for line in output.split("\n"):
|
||||||
items = line.split()
|
items = line.split()
|
||||||
if len(items) < 2:
|
if len(items) < 2:
|
||||||
continue
|
continue
|
||||||
|
if items[1] == f"{localname}:":
|
||||||
if items[1] == f"{self.localname}:":
|
|
||||||
flags = items[2][1:-1].split(",")
|
flags = items[2][1:-1].split(",")
|
||||||
if "UP" in flags:
|
if "UP" in flags:
|
||||||
self.old_up = True
|
self.old_up = True
|
||||||
|
@ -487,6 +453,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
if items[1][:4] == "fe80":
|
if items[1][:4] == "fe80":
|
||||||
continue
|
continue
|
||||||
self.old_addrs.append((items[1], None))
|
self.old_addrs.append((items[1], None))
|
||||||
|
logging.info("saved rj45 state: addrs(%s) up(%s)", self.old_addrs, self.old_up)
|
||||||
|
|
||||||
def restorestate(self) -> None:
|
def restorestate(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -495,16 +462,12 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:return: nothing
|
:return: nothing
|
||||||
:raises CoreCommandError: when there is a command exception
|
:raises CoreCommandError: when there is a command exception
|
||||||
"""
|
"""
|
||||||
|
localname = self.interface.localname
|
||||||
|
logging.info("restoring rj45 state: %s", localname)
|
||||||
for addr in self.old_addrs:
|
for addr in self.old_addrs:
|
||||||
if addr[1] is None:
|
self.net_client.create_address(localname, addr[0], addr[1])
|
||||||
self.net_client.create_address(self.localname, addr[0])
|
|
||||||
else:
|
|
||||||
self.net_client.create_address(
|
|
||||||
self.localname, addr[0], broadcast=addr[1]
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.old_up:
|
if self.old_up:
|
||||||
self.net_client.device_up(self.localname)
|
self.net_client.device_up(localname)
|
||||||
|
|
||||||
def setposition(self, x: float = None, y: float = None, z: float = None) -> None:
|
def setposition(self, x: float = None, y: float = None, z: float = None) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -515,8 +478,8 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:param z: z position
|
:param z: z position
|
||||||
:return: True if position changed, False otherwise
|
:return: True if position changed, False otherwise
|
||||||
"""
|
"""
|
||||||
CoreNodeBase.setposition(self, x, y, z)
|
super().setposition(x, y, z)
|
||||||
CoreInterface.setposition(self)
|
self.interface.setposition()
|
||||||
|
|
||||||
def termcmdstring(self, sh: str) -> str:
|
def termcmdstring(self, sh: str) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -354,7 +354,7 @@ class FrrService(CoreService):
|
||||||
for peerifc in ifc.net.netifs():
|
for peerifc in ifc.net.netifs():
|
||||||
if peerifc == ifc:
|
if peerifc == ifc:
|
||||||
continue
|
continue
|
||||||
if isinstance(peerifc, Rj45Node):
|
if isinstance(peerifc.node, Rj45Node):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ class QuaggaService(CoreService):
|
||||||
for peerifc in ifc.net.netifs():
|
for peerifc in ifc.net.netifs():
|
||||||
if peerifc == ifc:
|
if peerifc == ifc:
|
||||||
continue
|
continue
|
||||||
if isinstance(peerifc, Rj45Node):
|
if isinstance(peerifc.node, Rj45Node):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue