changes to make rj45 maintain the interface information, instead of trying to be 2 classes at once

This commit is contained in:
Blake Harnden 2020-05-25 23:18:20 -07:00
parent 8fed201fd8
commit 7e4ef0b280
5 changed files with 47 additions and 74 deletions

View file

@ -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:

View file

@ -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,
) )

View file

@ -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:
""" """

View file

@ -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

View file

@ -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