initial sweeping changes to call all usages of various interface related variables and functions (netif, interface, if, ifc, etc) to use a consistent name iface
This commit is contained in:
parent
0462c1b084
commit
0725199d6d
93 changed files with 1955 additions and 2156 deletions
|
@ -68,8 +68,8 @@ class NodeBase(abc.ABC):
|
|||
self.server: "DistributedServer" = server
|
||||
self.type: Optional[str] = None
|
||||
self.services: CoreServices = []
|
||||
self._netif: Dict[int, CoreInterface] = {}
|
||||
self.ifindex: int = 0
|
||||
self.ifaces: Dict[int, CoreInterface] = {}
|
||||
self.iface_id: int = 0
|
||||
self.canvas: Optional[int] = None
|
||||
self.icon: Optional[str] = None
|
||||
self.opaque: Optional[str] = None
|
||||
|
@ -139,58 +139,50 @@ class NodeBase(abc.ABC):
|
|||
"""
|
||||
return self.position.get()
|
||||
|
||||
def ifname(self, ifindex: int) -> str:
|
||||
"""
|
||||
Retrieve interface name for index.
|
||||
def get_iface(self, iface_id: int) -> CoreInterface:
|
||||
if iface_id not in self.ifaces:
|
||||
raise CoreError(f"node({self.name}) does not have interface({iface_id})")
|
||||
return self.ifaces[iface_id]
|
||||
|
||||
:param ifindex: interface index
|
||||
:return: interface name
|
||||
def get_ifaces(self, control: bool = True) -> List[CoreInterface]:
|
||||
"""
|
||||
return self._netif[ifindex].name
|
||||
Retrieve sorted list of interfaces, optionally do not include control
|
||||
interfaces.
|
||||
|
||||
def netifs(self, sort: bool = False) -> List[CoreInterface]:
|
||||
:param control: False to exclude control interfaces, included otherwise
|
||||
:return: list of interfaces
|
||||
"""
|
||||
Retrieve network interfaces, sorted if desired.
|
||||
ifaces = []
|
||||
for iface_id in sorted(self.ifaces):
|
||||
iface = self.ifaces[iface_id]
|
||||
if not control and getattr(iface, "control", False):
|
||||
continue
|
||||
ifaces.append(iface)
|
||||
return ifaces
|
||||
|
||||
:param sort: boolean used to determine if interfaces should be sorted
|
||||
:return: network interfaces
|
||||
def get_iface_id(self, iface: CoreInterface) -> int:
|
||||
"""
|
||||
if sort:
|
||||
return [self._netif[x] for x in sorted(self._netif)]
|
||||
else:
|
||||
return list(self._netif.values())
|
||||
Retrieve id for an interface.
|
||||
|
||||
def numnetif(self) -> int:
|
||||
"""
|
||||
Return the attached interface count.
|
||||
|
||||
:return: number of network interfaces
|
||||
"""
|
||||
return len(self._netif)
|
||||
|
||||
def getifindex(self, netif: CoreInterface) -> int:
|
||||
"""
|
||||
Retrieve index for an interface.
|
||||
|
||||
:param netif: interface to get index for
|
||||
:param iface: interface to get id for
|
||||
:return: interface index if found, -1 otherwise
|
||||
"""
|
||||
for ifindex in self._netif:
|
||||
if self._netif[ifindex] is netif:
|
||||
return ifindex
|
||||
return -1
|
||||
for iface_id, local_iface in self.ifaces.items():
|
||||
if local_iface is iface:
|
||||
return iface_id
|
||||
raise CoreError(f"node({self.name}) does not have interface({iface.name})")
|
||||
|
||||
def newifindex(self) -> int:
|
||||
def next_iface_id(self) -> int:
|
||||
"""
|
||||
Create a new interface index.
|
||||
|
||||
:return: interface index
|
||||
"""
|
||||
while self.ifindex in self._netif:
|
||||
self.ifindex += 1
|
||||
ifindex = self.ifindex
|
||||
self.ifindex += 1
|
||||
return ifindex
|
||||
while self.iface_id in self.ifaces:
|
||||
self.iface_id += 1
|
||||
iface_id = self.iface_id
|
||||
self.iface_id += 1
|
||||
return iface_id
|
||||
|
||||
def data(
|
||||
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
|
||||
|
@ -325,14 +317,14 @@ class CoreNodeBase(NodeBase):
|
|||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def newnetif(
|
||||
self, net: "CoreNetworkBase", interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: "CoreNetworkBase", iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
"""
|
||||
Create a new network interface.
|
||||
Create a new interface.
|
||||
|
||||
:param net: network to associate with
|
||||
:param interface_data: interface data for new interface
|
||||
:param iface_data: interface data for new interface
|
||||
:return: interface index
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
@ -399,67 +391,53 @@ class CoreNodeBase(NodeBase):
|
|||
if self.tmpnodedir:
|
||||
self.host_cmd(f"rm -rf {self.nodedir}")
|
||||
|
||||
def addnetif(self, netif: CoreInterface, ifindex: int) -> None:
|
||||
def add_iface(self, iface: CoreInterface, iface_id: int) -> None:
|
||||
"""
|
||||
Add network interface to node and set the network interface index if successful.
|
||||
|
||||
:param netif: network interface to add
|
||||
:param ifindex: interface index
|
||||
:param iface: network interface to add
|
||||
:param iface_id: interface id
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex in self._netif:
|
||||
raise ValueError(f"ifindex {ifindex} already exists")
|
||||
self._netif[ifindex] = netif
|
||||
netif.netindex = ifindex
|
||||
if iface_id in self.ifaces:
|
||||
raise CoreError(f"interface({iface_id}) already exists")
|
||||
self.ifaces[iface_id] = iface
|
||||
iface.node_id = iface_id
|
||||
|
||||
def delnetif(self, ifindex: int) -> None:
|
||||
def delete_iface(self, iface_id: int) -> None:
|
||||
"""
|
||||
Delete a network interface
|
||||
|
||||
:param ifindex: interface index to delete
|
||||
:param iface_id: interface index to delete
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex not in self._netif:
|
||||
raise CoreError(f"node({self.name}) ifindex({ifindex}) does not exist")
|
||||
netif = self._netif.pop(ifindex)
|
||||
logging.info("node(%s) removing interface(%s)", self.name, netif.name)
|
||||
netif.detachnet()
|
||||
netif.shutdown()
|
||||
if iface_id not in self.ifaces:
|
||||
raise CoreError(f"node({self.name}) interface({iface_id}) does not exist")
|
||||
iface = self.ifaces.pop(iface_id)
|
||||
logging.info("node(%s) removing interface(%s)", self.name, iface.name)
|
||||
iface.detachnet()
|
||||
iface.shutdown()
|
||||
|
||||
def netif(self, ifindex: int) -> Optional[CoreInterface]:
|
||||
"""
|
||||
Retrieve network interface.
|
||||
|
||||
:param ifindex: index of interface to retrieve
|
||||
:return: network interface, or None if not found
|
||||
"""
|
||||
if ifindex in self._netif:
|
||||
return self._netif[ifindex]
|
||||
else:
|
||||
return None
|
||||
|
||||
def attachnet(self, ifindex: int, net: "CoreNetworkBase") -> None:
|
||||
def attachnet(self, iface_id: int, net: "CoreNetworkBase") -> None:
|
||||
"""
|
||||
Attach a network.
|
||||
|
||||
:param ifindex: interface of index to attach
|
||||
:param iface_id: interface of index to attach
|
||||
:param net: network to attach
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex not in self._netif:
|
||||
raise ValueError(f"ifindex {ifindex} does not exist")
|
||||
self._netif[ifindex].attachnet(net)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.attachnet(net)
|
||||
|
||||
def detachnet(self, ifindex: int) -> None:
|
||||
def detachnet(self, iface_id: int) -> None:
|
||||
"""
|
||||
Detach network interface.
|
||||
|
||||
:param ifindex: interface index to detach
|
||||
:param iface_id: interface id to detach
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex not in self._netif:
|
||||
raise ValueError(f"ifindex {ifindex} does not exist")
|
||||
self._netif[ifindex].detachnet()
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.detachnet()
|
||||
|
||||
def setposition(self, x: float = None, y: float = None, z: float = None) -> None:
|
||||
"""
|
||||
|
@ -472,8 +450,8 @@ class CoreNodeBase(NodeBase):
|
|||
"""
|
||||
changed = super().setposition(x, y, z)
|
||||
if changed:
|
||||
for netif in self.netifs(sort=True):
|
||||
netif.setposition()
|
||||
for iface in self.get_ifaces():
|
||||
iface.setposition()
|
||||
|
||||
def commonnets(
|
||||
self, node: "CoreNodeBase", want_ctrl: bool = False
|
||||
|
@ -488,12 +466,10 @@ class CoreNodeBase(NodeBase):
|
|||
:return: tuples of common networks
|
||||
"""
|
||||
common = []
|
||||
for netif1 in self.netifs():
|
||||
if not want_ctrl and hasattr(netif1, "control"):
|
||||
continue
|
||||
for netif2 in node.netifs():
|
||||
if netif1.net == netif2.net:
|
||||
common.append((netif1.net, netif1, netif2))
|
||||
for iface1 in self.get_ifaces(control=want_ctrl):
|
||||
for iface2 in node.get_ifaces():
|
||||
if iface1.net == iface2.net:
|
||||
common.append((iface1.net, iface1, iface2))
|
||||
return common
|
||||
|
||||
|
||||
|
@ -620,8 +596,8 @@ class CoreNode(CoreNodeBase):
|
|||
self._mounts = []
|
||||
|
||||
# shutdown all interfaces
|
||||
for netif in self.netifs():
|
||||
netif.shutdown()
|
||||
for iface in self.get_ifaces():
|
||||
iface.shutdown()
|
||||
|
||||
# kill node process if present
|
||||
try:
|
||||
|
@ -636,7 +612,7 @@ class CoreNode(CoreNodeBase):
|
|||
logging.exception("error removing node directory")
|
||||
|
||||
# clear interface data, close client, and mark self and not up
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self.client.close()
|
||||
self.up = False
|
||||
except OSError:
|
||||
|
@ -704,36 +680,36 @@ class CoreNode(CoreNodeBase):
|
|||
self.cmd(f"{MOUNT_BIN} -n --bind {source} {target}")
|
||||
self._mounts.append((source, target))
|
||||
|
||||
def newifindex(self) -> int:
|
||||
def next_iface_id(self) -> int:
|
||||
"""
|
||||
Retrieve a new interface index.
|
||||
|
||||
:return: new interface index
|
||||
"""
|
||||
with self.lock:
|
||||
return super().newifindex()
|
||||
return super().next_iface_id()
|
||||
|
||||
def newveth(self, ifindex: int = None, ifname: str = None) -> int:
|
||||
def newveth(self, iface_id: int = None, ifname: str = None) -> int:
|
||||
"""
|
||||
Create a new interface.
|
||||
|
||||
:param ifindex: index for the new interface
|
||||
:param iface_id: id for the new interface
|
||||
:param ifname: name for the new interface
|
||||
:return: nothing
|
||||
"""
|
||||
with self.lock:
|
||||
if ifindex is None:
|
||||
ifindex = self.newifindex()
|
||||
if iface_id is None:
|
||||
iface_id = self.next_iface_id()
|
||||
|
||||
if ifname is None:
|
||||
ifname = f"eth{ifindex}"
|
||||
ifname = f"eth{iface_id}"
|
||||
|
||||
sessionid = self.session.short_session_id()
|
||||
|
||||
try:
|
||||
suffix = f"{self.id:x}.{ifindex}.{sessionid}"
|
||||
suffix = f"{self.id:x}.{iface_id}.{sessionid}"
|
||||
except TypeError:
|
||||
suffix = f"{self.id}.{ifindex}.{sessionid}"
|
||||
suffix = f"{self.id}.{iface_id}.{sessionid}"
|
||||
|
||||
localname = f"veth{suffix}"
|
||||
if len(localname) >= 16:
|
||||
|
@ -765,140 +741,138 @@ class CoreNode(CoreNodeBase):
|
|||
try:
|
||||
# add network interface to the node. If unsuccessful, destroy the
|
||||
# network interface and raise exception.
|
||||
self.addnetif(veth, ifindex)
|
||||
self.add_iface(veth, iface_id)
|
||||
except ValueError as e:
|
||||
veth.shutdown()
|
||||
del veth
|
||||
raise e
|
||||
|
||||
return ifindex
|
||||
return iface_id
|
||||
|
||||
def newtuntap(self, ifindex: int = None, ifname: str = None) -> int:
|
||||
def newtuntap(self, iface_id: int = None, ifname: str = None) -> int:
|
||||
"""
|
||||
Create a new tunnel tap.
|
||||
|
||||
:param ifindex: interface index
|
||||
:param iface_id: interface id
|
||||
:param ifname: interface name
|
||||
:return: interface index
|
||||
"""
|
||||
with self.lock:
|
||||
if ifindex is None:
|
||||
ifindex = self.newifindex()
|
||||
if iface_id is None:
|
||||
iface_id = self.next_iface_id()
|
||||
|
||||
if ifname is None:
|
||||
ifname = f"eth{ifindex}"
|
||||
ifname = f"eth{iface_id}"
|
||||
|
||||
sessionid = self.session.short_session_id()
|
||||
localname = f"tap{self.id}.{ifindex}.{sessionid}"
|
||||
localname = f"tap{self.id}.{iface_id}.{sessionid}"
|
||||
name = ifname
|
||||
tuntap = TunTap(self.session, self, name, localname, start=self.up)
|
||||
|
||||
try:
|
||||
self.addnetif(tuntap, ifindex)
|
||||
self.add_iface(tuntap, iface_id)
|
||||
except ValueError as e:
|
||||
tuntap.shutdown()
|
||||
del tuntap
|
||||
raise e
|
||||
|
||||
return ifindex
|
||||
return iface_id
|
||||
|
||||
def sethwaddr(self, ifindex: int, addr: str) -> None:
|
||||
def sethwaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Set hardware addres for an interface.
|
||||
Set hardware address for an interface.
|
||||
|
||||
:param ifindex: index of interface to set hardware address for
|
||||
:param iface_id: id of interface to set hardware address for
|
||||
:param addr: hardware address to set
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
addr = utils.validate_mac(addr)
|
||||
interface = self._netif[ifindex]
|
||||
interface.sethwaddr(addr)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.sethwaddr(addr)
|
||||
if self.up:
|
||||
self.node_net_client.device_mac(interface.name, addr)
|
||||
self.node_net_client.device_mac(iface.name, addr)
|
||||
|
||||
def addaddr(self, ifindex: int, addr: str) -> None:
|
||||
def addaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Add interface address.
|
||||
|
||||
:param ifindex: index of interface to add address to
|
||||
:param iface_id: id of interface to add address to
|
||||
:param addr: address to add to interface
|
||||
:return: nothing
|
||||
"""
|
||||
addr = utils.validate_ip(addr)
|
||||
interface = self._netif[ifindex]
|
||||
interface.addaddr(addr)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.addaddr(addr)
|
||||
if self.up:
|
||||
# ipv4 check
|
||||
broadcast = None
|
||||
if netaddr.valid_ipv4(addr):
|
||||
broadcast = "+"
|
||||
self.node_net_client.create_address(interface.name, addr, broadcast)
|
||||
self.node_net_client.create_address(iface.name, addr, broadcast)
|
||||
|
||||
def deladdr(self, ifindex: int, addr: str) -> None:
|
||||
def deladdr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Delete address from an interface.
|
||||
|
||||
:param ifindex: index of interface to delete address from
|
||||
:param iface_id: id of interface to delete address from
|
||||
:param addr: address to delete from interface
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
interface = self._netif[ifindex]
|
||||
|
||||
iface = self.get_iface(iface_id)
|
||||
try:
|
||||
interface.deladdr(addr)
|
||||
iface.deladdr(addr)
|
||||
except ValueError:
|
||||
logging.exception("trying to delete unknown address: %s", addr)
|
||||
|
||||
if self.up:
|
||||
self.node_net_client.delete_address(interface.name, addr)
|
||||
self.node_net_client.delete_address(iface.name, addr)
|
||||
|
||||
def ifup(self, ifindex: int) -> None:
|
||||
def ifup(self, iface_id: int) -> None:
|
||||
"""
|
||||
Bring an interface up.
|
||||
|
||||
:param ifindex: index of interface to bring up
|
||||
:param iface_id: index of interface to bring up
|
||||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
interface_name = self.ifname(ifindex)
|
||||
self.node_net_client.device_up(interface_name)
|
||||
iface = self.get_iface(iface_id)
|
||||
self.node_net_client.device_up(iface.name)
|
||||
|
||||
def newnetif(
|
||||
self, net: "CoreNetworkBase", interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: "CoreNetworkBase", iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
"""
|
||||
Create a new network interface.
|
||||
|
||||
:param net: network to associate with
|
||||
:param interface_data: interface data for new interface
|
||||
:param iface_data: interface data for new interface
|
||||
:return: interface index
|
||||
"""
|
||||
addresses = interface_data.get_addresses()
|
||||
addresses = iface_data.get_addresses()
|
||||
with self.lock:
|
||||
# TODO: emane specific code
|
||||
if net.is_emane is True:
|
||||
ifindex = self.newtuntap(interface_data.id, interface_data.name)
|
||||
iface_id = self.newtuntap(iface_data.id, iface_data.name)
|
||||
# TUN/TAP is not ready for addressing yet; the device may
|
||||
# take some time to appear, and installing it into a
|
||||
# namespace after it has been bound removes addressing;
|
||||
# save addresses with the interface now
|
||||
self.attachnet(ifindex, net)
|
||||
netif = self.netif(ifindex)
|
||||
netif.sethwaddr(interface_data.mac)
|
||||
self.attachnet(iface_id, net)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.sethwaddr(iface_data.mac)
|
||||
for address in addresses:
|
||||
netif.addaddr(address)
|
||||
iface.addaddr(address)
|
||||
else:
|
||||
ifindex = self.newveth(interface_data.id, interface_data.name)
|
||||
self.attachnet(ifindex, net)
|
||||
if interface_data.mac:
|
||||
self.sethwaddr(ifindex, interface_data.mac)
|
||||
iface_id = self.newveth(iface_data.id, iface_data.name)
|
||||
self.attachnet(iface_id, net)
|
||||
if iface_data.mac:
|
||||
self.sethwaddr(iface_id, iface_data.mac)
|
||||
for address in addresses:
|
||||
self.addaddr(ifindex, address)
|
||||
self.ifup(ifindex)
|
||||
netif = self.netif(ifindex)
|
||||
return netif
|
||||
self.addaddr(iface_id, address)
|
||||
self.ifup(iface_id)
|
||||
iface = self.get_iface(iface_id)
|
||||
return iface
|
||||
|
||||
def addfile(self, srcname: str, filename: str) -> None:
|
||||
"""
|
||||
|
@ -1041,54 +1015,54 @@ class CoreNetworkBase(NodeBase):
|
|||
|
||||
@abc.abstractmethod
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Configure link parameters by applying tc queuing disciplines on the interface.
|
||||
|
||||
:param netif: interface one
|
||||
:param iface: interface one
|
||||
:param options: options for configuring link
|
||||
:param netif2: interface two
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def getlinknetif(self, net: "CoreNetworkBase") -> Optional[CoreInterface]:
|
||||
def get_linked_iface(self, net: "CoreNetworkBase") -> Optional[CoreInterface]:
|
||||
"""
|
||||
Return the interface of that links this net with another net.
|
||||
Return the interface that links this net with another net.
|
||||
|
||||
:param net: interface to get link for
|
||||
:return: interface the provided network is linked to
|
||||
"""
|
||||
for netif in self.netifs():
|
||||
if netif.othernet == net:
|
||||
return netif
|
||||
for iface in self.get_ifaces():
|
||||
if iface.othernet == net:
|
||||
return iface
|
||||
return None
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach network interface.
|
||||
|
||||
:param netif: network interface to attach
|
||||
:param iface: network interface to attach
|
||||
:return: nothing
|
||||
"""
|
||||
i = self.newifindex()
|
||||
self._netif[i] = netif
|
||||
netif.netifi = i
|
||||
i = self.next_iface_id()
|
||||
self.ifaces[i] = iface
|
||||
iface.net_id = i
|
||||
with self._linked_lock:
|
||||
self._linked[netif] = {}
|
||||
self._linked[iface] = {}
|
||||
|
||||
def detach(self, netif: CoreInterface) -> None:
|
||||
def detach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Detach network interface.
|
||||
|
||||
:param netif: network interface to detach
|
||||
:param iface: network interface to detach
|
||||
:return: nothing
|
||||
"""
|
||||
del self._netif[netif.netifi]
|
||||
netif.netifi = None
|
||||
del self.ifaces[iface.net_id]
|
||||
iface.net_id = None
|
||||
with self._linked_lock:
|
||||
del self._linked[netif]
|
||||
del self._linked[iface]
|
||||
|
||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||
"""
|
||||
|
@ -1102,41 +1076,39 @@ class CoreNetworkBase(NodeBase):
|
|||
|
||||
# build a link message from this network node to each node having a
|
||||
# connected interface
|
||||
for netif in self.netifs(sort=True):
|
||||
if not hasattr(netif, "node"):
|
||||
continue
|
||||
for iface in self.get_ifaces():
|
||||
uni = False
|
||||
linked_node = netif.node
|
||||
linked_node = iface.node
|
||||
if linked_node is None:
|
||||
# two layer-2 switches/hubs linked together via linknet()
|
||||
if not netif.othernet:
|
||||
if not iface.othernet:
|
||||
continue
|
||||
linked_node = netif.othernet
|
||||
linked_node = iface.othernet
|
||||
if linked_node.id == self.id:
|
||||
continue
|
||||
netif.swapparams("_params_up")
|
||||
upstream_params = netif.getparams()
|
||||
netif.swapparams("_params_up")
|
||||
if netif.getparams() != upstream_params:
|
||||
iface.swapparams("_params_up")
|
||||
upstream_params = iface.getparams()
|
||||
iface.swapparams("_params_up")
|
||||
if iface.getparams() != upstream_params:
|
||||
uni = True
|
||||
|
||||
unidirectional = 0
|
||||
if uni:
|
||||
unidirectional = 1
|
||||
|
||||
interface2_ip4 = None
|
||||
interface2_ip4_mask = None
|
||||
interface2_ip6 = None
|
||||
interface2_ip6_mask = None
|
||||
for address in netif.addrlist:
|
||||
iface2_ip4 = None
|
||||
iface2_ip4_mask = None
|
||||
iface2_ip6 = None
|
||||
iface2_ip6_mask = None
|
||||
for address in iface.addrlist:
|
||||
ip, _sep, mask = address.partition("/")
|
||||
mask = int(mask)
|
||||
if netaddr.valid_ipv4(ip):
|
||||
interface2_ip4 = ip
|
||||
interface2_ip4_mask = mask
|
||||
iface2_ip4 = ip
|
||||
iface2_ip4_mask = mask
|
||||
else:
|
||||
interface2_ip6 = ip
|
||||
interface2_ip6_mask = mask
|
||||
iface2_ip6 = ip
|
||||
iface2_ip6_mask = mask
|
||||
|
||||
link_data = LinkData(
|
||||
message_type=flags,
|
||||
|
@ -1144,42 +1116,38 @@ class CoreNetworkBase(NodeBase):
|
|||
node2_id=linked_node.id,
|
||||
link_type=self.linktype,
|
||||
unidirectional=unidirectional,
|
||||
interface2_id=linked_node.getifindex(netif),
|
||||
interface2_name=netif.name,
|
||||
interface2_mac=netif.hwaddr,
|
||||
interface2_ip4=interface2_ip4,
|
||||
interface2_ip4_mask=interface2_ip4_mask,
|
||||
interface2_ip6=interface2_ip6,
|
||||
interface2_ip6_mask=interface2_ip6_mask,
|
||||
delay=netif.getparam("delay"),
|
||||
bandwidth=netif.getparam("bw"),
|
||||
dup=netif.getparam("duplicate"),
|
||||
jitter=netif.getparam("jitter"),
|
||||
loss=netif.getparam("loss"),
|
||||
iface2_id=linked_node.get_iface_id(iface),
|
||||
iface2_name=iface.name,
|
||||
iface2_mac=iface.hwaddr,
|
||||
iface2_ip4=iface2_ip4,
|
||||
iface2_ip4_mask=iface2_ip4_mask,
|
||||
iface2_ip6=iface2_ip6,
|
||||
iface2_ip6_mask=iface2_ip6_mask,
|
||||
delay=iface.getparam("delay"),
|
||||
bandwidth=iface.getparam("bw"),
|
||||
dup=iface.getparam("duplicate"),
|
||||
jitter=iface.getparam("jitter"),
|
||||
loss=iface.getparam("loss"),
|
||||
)
|
||||
|
||||
all_links.append(link_data)
|
||||
|
||||
if not uni:
|
||||
continue
|
||||
|
||||
netif.swapparams("_params_up")
|
||||
iface.swapparams("_params_up")
|
||||
link_data = LinkData(
|
||||
message_type=MessageFlags.NONE,
|
||||
node1_id=linked_node.id,
|
||||
node2_id=self.id,
|
||||
link_type=self.linktype,
|
||||
unidirectional=1,
|
||||
delay=netif.getparam("delay"),
|
||||
bandwidth=netif.getparam("bw"),
|
||||
dup=netif.getparam("duplicate"),
|
||||
jitter=netif.getparam("jitter"),
|
||||
loss=netif.getparam("loss"),
|
||||
delay=iface.getparam("delay"),
|
||||
bandwidth=iface.getparam("bw"),
|
||||
dup=iface.getparam("duplicate"),
|
||||
jitter=iface.getparam("jitter"),
|
||||
loss=iface.getparam("loss"),
|
||||
)
|
||||
netif.swapparams("_params_up")
|
||||
|
||||
iface.swapparams("_params_up")
|
||||
all_links.append(link_data)
|
||||
|
||||
return all_links
|
||||
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ class DockerNode(CoreNode):
|
|||
return
|
||||
|
||||
with self.lock:
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self.client.stop_container()
|
||||
self.up = False
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@ class CoreInterface:
|
|||
self.poshook: Callable[[CoreInterface], None] = lambda x: None
|
||||
# used with EMANE
|
||||
self.transport_type: Optional[TransportType] = None
|
||||
# node interface index
|
||||
self.netindex: Optional[int] = None
|
||||
# net interface index
|
||||
self.netifi: Optional[int] = None
|
||||
# index used to find flow data
|
||||
# id of interface for node
|
||||
self.node_id: Optional[int] = None
|
||||
# id of interface for network
|
||||
self.net_id: Optional[int] = None
|
||||
# id used to find flow data
|
||||
self.flow_id: Optional[int] = None
|
||||
self.server: Optional["DistributedServer"] = server
|
||||
use_ovs = session.options.get_config("ovs") == "True"
|
||||
|
@ -284,19 +284,16 @@ class Veth(CoreInterface):
|
|||
"""
|
||||
if not self.up:
|
||||
return
|
||||
|
||||
if self.node:
|
||||
try:
|
||||
self.node.node_net_client.device_flush(self.name)
|
||||
except CoreCommandError:
|
||||
logging.exception("error shutting down interface")
|
||||
|
||||
if self.localname:
|
||||
try:
|
||||
self.net_client.delete_device(self.localname)
|
||||
except CoreCommandError:
|
||||
logging.info("link already removed: %s", self.localname)
|
||||
|
||||
self.up = False
|
||||
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ class LxcNode(CoreNode):
|
|||
return
|
||||
|
||||
with self.lock:
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self.client.stop_container()
|
||||
self.up = False
|
||||
|
||||
|
@ -215,7 +215,7 @@ class LxcNode(CoreNode):
|
|||
self.client.copy_file(source, filename)
|
||||
self.cmd(f"chmod {mode:o} {filename}")
|
||||
|
||||
def addnetif(self, netif: CoreInterface, ifindex: int) -> None:
|
||||
super().addnetif(netif, ifindex)
|
||||
def add_iface(self, iface: CoreInterface, iface_id: int) -> None:
|
||||
super().add_iface(iface, iface_id)
|
||||
# adding small delay to allow time for adding addresses to work correctly
|
||||
time.sleep(0.5)
|
||||
|
|
|
@ -155,14 +155,14 @@ class LinuxNetClient:
|
|||
"""
|
||||
self.run(f"{TC_BIN} qdisc delete dev {device} root")
|
||||
|
||||
def checksums_off(self, interface_name: str) -> None:
|
||||
def checksums_off(self, iface_name: str) -> None:
|
||||
"""
|
||||
Turns interface checksums off.
|
||||
|
||||
:param interface_name: interface to update
|
||||
:param iface_name: interface to update
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{ETHTOOL_BIN} -K {interface_name} rx off tx off")
|
||||
self.run(f"{ETHTOOL_BIN} -K {iface_name} rx off tx off")
|
||||
|
||||
def create_address(self, device: str, address: str, broadcast: str = None) -> None:
|
||||
"""
|
||||
|
@ -250,26 +250,26 @@ class LinuxNetClient:
|
|||
self.device_down(name)
|
||||
self.run(f"{IP_BIN} link delete {name} type bridge")
|
||||
|
||||
def set_interface_master(self, bridge_name: str, interface_name: str) -> None:
|
||||
def set_iface_master(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Assign interface master to a Linux bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{IP_BIN} link set dev {interface_name} master {bridge_name}")
|
||||
self.device_up(interface_name)
|
||||
self.run(f"{IP_BIN} link set dev {iface_name} master {bridge_name}")
|
||||
self.device_up(iface_name)
|
||||
|
||||
def delete_interface(self, bridge_name: str, interface_name: str) -> None:
|
||||
def delete_iface(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Delete an interface associated with a Linux bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{IP_BIN} link set dev {interface_name} nomaster")
|
||||
self.run(f"{IP_BIN} link set dev {iface_name} nomaster")
|
||||
|
||||
def existing_bridges(self, _id: int) -> bool:
|
||||
"""
|
||||
|
@ -330,26 +330,26 @@ class OvsNetClient(LinuxNetClient):
|
|||
self.device_down(name)
|
||||
self.run(f"{OVS_BIN} del-br {name}")
|
||||
|
||||
def set_interface_master(self, bridge_name: str, interface_name: str) -> None:
|
||||
def set_iface_master(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Create an interface associated with a network bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{OVS_BIN} add-port {bridge_name} {interface_name}")
|
||||
self.device_up(interface_name)
|
||||
self.run(f"{OVS_BIN} add-port {bridge_name} {iface_name}")
|
||||
self.device_up(iface_name)
|
||||
|
||||
def delete_interface(self, bridge_name: str, interface_name: str) -> None:
|
||||
def delete_iface(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Delete an interface associated with a OVS bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{OVS_BIN} del-port {bridge_name} {interface_name}")
|
||||
self.run(f"{OVS_BIN} del-port {bridge_name} {iface_name}")
|
||||
|
||||
def existing_bridges(self, _id: int) -> bool:
|
||||
"""
|
||||
|
|
|
@ -216,20 +216,20 @@ class EbtablesQueue:
|
|||
]
|
||||
)
|
||||
# rebuild the chain
|
||||
for netif1, v in wlan._linked.items():
|
||||
for netif2, linked in v.items():
|
||||
for iface1, v in wlan._linked.items():
|
||||
for oface2, linked in v.items():
|
||||
if wlan.policy == NetworkPolicy.DROP and linked:
|
||||
self.cmds.extend(
|
||||
[
|
||||
f"-A {wlan.brname} -i {netif1.localname} -o {netif2.localname} -j ACCEPT",
|
||||
f"-A {wlan.brname} -o {netif1.localname} -i {netif2.localname} -j ACCEPT",
|
||||
f"-A {wlan.brname} -i {iface1.localname} -o {oface2.localname} -j ACCEPT",
|
||||
f"-A {wlan.brname} -o {iface1.localname} -i {oface2.localname} -j ACCEPT",
|
||||
]
|
||||
)
|
||||
elif wlan.policy == NetworkPolicy.ACCEPT and not linked:
|
||||
self.cmds.extend(
|
||||
[
|
||||
f"-A {wlan.brname} -i {netif1.localname} -o {netif2.localname} -j DROP",
|
||||
f"-A {wlan.brname} -o {netif1.localname} -i {netif2.localname} -j DROP",
|
||||
f"-A {wlan.brname} -i {iface1.localname} -o {oface2.localname} -j DROP",
|
||||
f"-A {wlan.brname} -o {iface1.localname} -i {oface2.localname} -j DROP",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -347,53 +347,53 @@ class CoreNetwork(CoreNetworkBase):
|
|||
logging.exception("error during shutdown")
|
||||
|
||||
# removes veth pairs used for bridge-to-bridge connections
|
||||
for netif in self.netifs():
|
||||
netif.shutdown()
|
||||
for iface in self.get_ifaces():
|
||||
iface.shutdown()
|
||||
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self._linked.clear()
|
||||
del self.session
|
||||
self.up = False
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach a network interface.
|
||||
|
||||
:param netif: network interface to attach
|
||||
:param iface: network interface to attach
|
||||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
netif.net_client.set_interface_master(self.brname, netif.localname)
|
||||
super().attach(netif)
|
||||
iface.net_client.set_iface_master(self.brname, iface.localname)
|
||||
super().attach(iface)
|
||||
|
||||
def detach(self, netif: CoreInterface) -> None:
|
||||
def detach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Detach a network interface.
|
||||
|
||||
:param netif: network interface to detach
|
||||
:param iface: network interface to detach
|
||||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
netif.net_client.delete_interface(self.brname, netif.localname)
|
||||
super().detach(netif)
|
||||
iface.net_client.delete_iface(self.brname, iface.localname)
|
||||
super().detach(iface)
|
||||
|
||||
def linked(self, netif1: CoreInterface, netif2: CoreInterface) -> bool:
|
||||
def linked(self, iface1: CoreInterface, iface2: CoreInterface) -> bool:
|
||||
"""
|
||||
Determine if the provided network interfaces are linked.
|
||||
|
||||
:param netif1: interface one
|
||||
:param netif2: interface two
|
||||
:param iface1: interface one
|
||||
:param iface2: interface two
|
||||
:return: True if interfaces are linked, False otherwise
|
||||
"""
|
||||
# check if the network interfaces are attached to this network
|
||||
if self._netif[netif1.netifi] != netif1:
|
||||
raise ValueError(f"inconsistency for netif {netif1.name}")
|
||||
if self.ifaces[iface1.net_id] != iface1:
|
||||
raise ValueError(f"inconsistency for interface {iface1.name}")
|
||||
|
||||
if self._netif[netif2.netifi] != netif2:
|
||||
raise ValueError(f"inconsistency for netif {netif2.name}")
|
||||
if self.ifaces[iface2.net_id] != iface2:
|
||||
raise ValueError(f"inconsistency for interface {iface2.name}")
|
||||
|
||||
try:
|
||||
linked = self._linked[netif1][netif2]
|
||||
linked = self._linked[iface1][iface2]
|
||||
except KeyError:
|
||||
if self.policy == NetworkPolicy.ACCEPT:
|
||||
linked = True
|
||||
|
@ -401,93 +401,93 @@ class CoreNetwork(CoreNetworkBase):
|
|||
linked = False
|
||||
else:
|
||||
raise Exception(f"unknown policy: {self.policy.value}")
|
||||
self._linked[netif1][netif2] = linked
|
||||
self._linked[iface1][iface2] = linked
|
||||
|
||||
return linked
|
||||
|
||||
def unlink(self, netif1: CoreInterface, netif2: CoreInterface) -> None:
|
||||
def unlink(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
|
||||
"""
|
||||
Unlink two interfaces, resulting in adding or removing ebtables
|
||||
filtering rules.
|
||||
|
||||
:param netif1: interface one
|
||||
:param netif2: interface two
|
||||
:param iface1: interface one
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
with self._linked_lock:
|
||||
if not self.linked(netif1, netif2):
|
||||
if not self.linked(iface1, iface2):
|
||||
return
|
||||
self._linked[netif1][netif2] = False
|
||||
self._linked[iface1][iface2] = False
|
||||
|
||||
ebq.ebchange(self)
|
||||
|
||||
def link(self, netif1: CoreInterface, netif2: CoreInterface) -> None:
|
||||
def link(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
|
||||
"""
|
||||
Link two interfaces together, resulting in adding or removing
|
||||
ebtables filtering rules.
|
||||
|
||||
:param netif1: interface one
|
||||
:param netif2: interface two
|
||||
:param iface1: interface one
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
with self._linked_lock:
|
||||
if self.linked(netif1, netif2):
|
||||
if self.linked(iface1, iface2):
|
||||
return
|
||||
self._linked[netif1][netif2] = True
|
||||
self._linked[iface1][iface2] = True
|
||||
|
||||
ebq.ebchange(self)
|
||||
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Configure link parameters by applying tc queuing disciplines on the interface.
|
||||
|
||||
:param netif: interface one
|
||||
:param iface: interface one
|
||||
:param options: options for configuring link
|
||||
:param netif2: interface two
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
devname = netif.localname
|
||||
devname = iface.localname
|
||||
tc = f"{TC_BIN} qdisc replace dev {devname}"
|
||||
parent = "root"
|
||||
changed = False
|
||||
bw = options.bandwidth
|
||||
if netif.setparam("bw", bw):
|
||||
if iface.setparam("bw", bw):
|
||||
# from tc-tbf(8): minimum value for burst is rate / kernel_hz
|
||||
burst = max(2 * netif.mtu, int(bw / 1000))
|
||||
burst = max(2 * iface.mtu, int(bw / 1000))
|
||||
# max IP payload
|
||||
limit = 0xFFFF
|
||||
tbf = f"tbf rate {bw} burst {burst} limit {limit}"
|
||||
if bw > 0:
|
||||
if self.up:
|
||||
cmd = f"{tc} {parent} handle 1: {tbf}"
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_tbf", True)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_tbf", True)
|
||||
changed = True
|
||||
elif netif.getparam("has_tbf") and bw <= 0:
|
||||
elif iface.getparam("has_tbf") and bw <= 0:
|
||||
if self.up:
|
||||
cmd = f"{TC_BIN} qdisc delete dev {devname} {parent}"
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_tbf", False)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_tbf", False)
|
||||
# removing the parent removes the child
|
||||
netif.setparam("has_netem", False)
|
||||
iface.setparam("has_netem", False)
|
||||
changed = True
|
||||
if netif.getparam("has_tbf"):
|
||||
if iface.getparam("has_tbf"):
|
||||
parent = "parent 1:1"
|
||||
netem = "netem"
|
||||
delay = options.delay
|
||||
changed = max(changed, netif.setparam("delay", delay))
|
||||
changed = max(changed, iface.setparam("delay", delay))
|
||||
loss = options.loss
|
||||
if loss is not None:
|
||||
loss = float(loss)
|
||||
changed = max(changed, netif.setparam("loss", loss))
|
||||
changed = max(changed, iface.setparam("loss", loss))
|
||||
duplicate = options.dup
|
||||
if duplicate is not None:
|
||||
duplicate = int(duplicate)
|
||||
changed = max(changed, netif.setparam("duplicate", duplicate))
|
||||
changed = max(changed, iface.setparam("duplicate", duplicate))
|
||||
jitter = options.jitter
|
||||
changed = max(changed, netif.setparam("jitter", jitter))
|
||||
changed = max(changed, iface.setparam("jitter", jitter))
|
||||
if not changed:
|
||||
return
|
||||
# jitter and delay use the same delay statement
|
||||
|
@ -510,19 +510,19 @@ class CoreNetwork(CoreNetworkBase):
|
|||
duplicate_check = duplicate is None or duplicate <= 0
|
||||
if all([delay_check, jitter_check, loss_check, duplicate_check]):
|
||||
# possibly remove netem if it exists and parent queue wasn't removed
|
||||
if not netif.getparam("has_netem"):
|
||||
if not iface.getparam("has_netem"):
|
||||
return
|
||||
if self.up:
|
||||
cmd = f"{TC_BIN} qdisc delete dev {devname} {parent} handle 10:"
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_netem", False)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_netem", False)
|
||||
elif len(netem) > 1:
|
||||
if self.up:
|
||||
cmd = (
|
||||
f"{TC_BIN} qdisc replace dev {devname} {parent} handle 10: {netem}"
|
||||
)
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_netem", True)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_netem", True)
|
||||
|
||||
def linknet(self, net: CoreNetworkBase) -> CoreInterface:
|
||||
"""
|
||||
|
@ -551,19 +551,19 @@ class CoreNetwork(CoreNetworkBase):
|
|||
if len(name) >= 16:
|
||||
raise ValueError(f"interface name {name} too long")
|
||||
|
||||
netif = Veth(self.session, None, name, localname, start=self.up)
|
||||
self.attach(netif)
|
||||
iface = Veth(self.session, None, name, localname, start=self.up)
|
||||
self.attach(iface)
|
||||
if net.up and net.brname:
|
||||
netif.net_client.set_interface_master(net.brname, netif.name)
|
||||
i = net.newifindex()
|
||||
net._netif[i] = netif
|
||||
iface.net_client.set_iface_master(net.brname, iface.name)
|
||||
i = net.next_iface_id()
|
||||
net.ifaces[i] = iface
|
||||
with net._linked_lock:
|
||||
net._linked[netif] = {}
|
||||
netif.net = self
|
||||
netif.othernet = net
|
||||
return netif
|
||||
net._linked[iface] = {}
|
||||
iface.net = self
|
||||
iface.othernet = net
|
||||
return iface
|
||||
|
||||
def getlinknetif(self, net: CoreNetworkBase) -> Optional[CoreInterface]:
|
||||
def get_linked_iface(self, net: CoreNetworkBase) -> Optional[CoreInterface]:
|
||||
"""
|
||||
Return the interface of that links this net with another net
|
||||
(that were linked using linknet()).
|
||||
|
@ -571,9 +571,9 @@ class CoreNetwork(CoreNetworkBase):
|
|||
:param net: interface to get link for
|
||||
:return: interface the provided network is linked to
|
||||
"""
|
||||
for netif in self.netifs():
|
||||
if netif.othernet == net:
|
||||
return netif
|
||||
for iface in self.get_ifaces():
|
||||
if iface.othernet == net:
|
||||
return iface
|
||||
return None
|
||||
|
||||
def addrconfig(self, addrlist: List[str]) -> None:
|
||||
|
@ -690,17 +690,17 @@ class GreTapBridge(CoreNetwork):
|
|||
)
|
||||
self.attach(self.gretap)
|
||||
|
||||
def setkey(self, key: int, interface_data: InterfaceData) -> None:
|
||||
def setkey(self, key: int, iface_data: InterfaceData) -> None:
|
||||
"""
|
||||
Set the GRE key used for the GreTap device. This needs to be set
|
||||
prior to instantiating the GreTap device (before addrconfig).
|
||||
|
||||
:param key: gre key
|
||||
:param interface_data: interface data for setting up tunnel key
|
||||
:param iface_data: interface data for setting up tunnel key
|
||||
:return: nothing
|
||||
"""
|
||||
self.grekey = key
|
||||
addresses = interface_data.get_addresses()
|
||||
addresses = iface_data.get_addresses()
|
||||
if addresses:
|
||||
self.addrconfig(addresses)
|
||||
|
||||
|
@ -802,7 +802,7 @@ class CtrlNet(CoreNetwork):
|
|||
self.host_cmd(f"{self.updown_script} {self.brname} startup")
|
||||
|
||||
if self.serverintf:
|
||||
self.net_client.set_interface_master(self.brname, self.serverintf)
|
||||
self.net_client.set_iface_master(self.brname, self.serverintf)
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""
|
||||
|
@ -812,7 +812,7 @@ class CtrlNet(CoreNetwork):
|
|||
"""
|
||||
if self.serverintf is not None:
|
||||
try:
|
||||
self.net_client.delete_interface(self.brname, self.serverintf)
|
||||
self.net_client.delete_iface(self.brname, self.serverintf)
|
||||
except CoreCommandError:
|
||||
logging.exception(
|
||||
"error deleting server interface %s from bridge %s",
|
||||
|
@ -850,18 +850,18 @@ class PtpNet(CoreNetwork):
|
|||
|
||||
policy: NetworkPolicy = NetworkPolicy.ACCEPT
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach a network interface, but limit attachment to two interfaces.
|
||||
|
||||
:param netif: network interface
|
||||
:param iface: network interface
|
||||
:return: nothing
|
||||
"""
|
||||
if len(self._netif) >= 2:
|
||||
if len(self.ifaces) >= 2:
|
||||
raise ValueError(
|
||||
"Point-to-point links support at most 2 network interfaces"
|
||||
)
|
||||
super().attach(netif)
|
||||
super().attach(iface)
|
||||
|
||||
def data(
|
||||
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
|
||||
|
@ -886,67 +886,67 @@ class PtpNet(CoreNetwork):
|
|||
"""
|
||||
all_links = []
|
||||
|
||||
if len(self._netif) != 2:
|
||||
if len(self.ifaces) != 2:
|
||||
return all_links
|
||||
|
||||
interface1, interface2 = self._netif.values()
|
||||
iface1, iface2 = self.get_ifaces()
|
||||
unidirectional = 0
|
||||
if interface1.getparams() != interface2.getparams():
|
||||
if iface1.getparams() != iface2.getparams():
|
||||
unidirectional = 1
|
||||
|
||||
interface1_ip4 = None
|
||||
interface1_ip4_mask = None
|
||||
interface1_ip6 = None
|
||||
interface1_ip6_mask = None
|
||||
for address in interface1.addrlist:
|
||||
iface1_ip4 = None
|
||||
iface1_ip4_mask = None
|
||||
iface1_ip6 = None
|
||||
iface1_ip6_mask = None
|
||||
for address in iface1.addrlist:
|
||||
ip, _sep, mask = address.partition("/")
|
||||
mask = int(mask)
|
||||
if netaddr.valid_ipv4(ip):
|
||||
interface1_ip4 = ip
|
||||
interface1_ip4_mask = mask
|
||||
iface1_ip4 = ip
|
||||
iface1_ip4_mask = mask
|
||||
else:
|
||||
interface1_ip6 = ip
|
||||
interface1_ip6_mask = mask
|
||||
iface1_ip6 = ip
|
||||
iface1_ip6_mask = mask
|
||||
|
||||
interface2_ip4 = None
|
||||
interface2_ip4_mask = None
|
||||
interface2_ip6 = None
|
||||
interface2_ip6_mask = None
|
||||
for address in interface2.addrlist:
|
||||
iface2_ip4 = None
|
||||
iface2_ip4_mask = None
|
||||
iface2_ip6 = None
|
||||
iface2_ip6_mask = None
|
||||
for address in iface2.addrlist:
|
||||
ip, _sep, mask = address.partition("/")
|
||||
mask = int(mask)
|
||||
if netaddr.valid_ipv4(ip):
|
||||
interface2_ip4 = ip
|
||||
interface2_ip4_mask = mask
|
||||
iface2_ip4 = ip
|
||||
iface2_ip4_mask = mask
|
||||
else:
|
||||
interface2_ip6 = ip
|
||||
interface2_ip6_mask = mask
|
||||
iface2_ip6 = ip
|
||||
iface2_ip6_mask = mask
|
||||
|
||||
link_data = LinkData(
|
||||
message_type=flags,
|
||||
node1_id=interface1.node.id,
|
||||
node2_id=interface2.node.id,
|
||||
node1_id=iface1.node.id,
|
||||
node2_id=iface2.node.id,
|
||||
link_type=self.linktype,
|
||||
unidirectional=unidirectional,
|
||||
delay=interface1.getparam("delay"),
|
||||
bandwidth=interface1.getparam("bw"),
|
||||
loss=interface1.getparam("loss"),
|
||||
dup=interface1.getparam("duplicate"),
|
||||
jitter=interface1.getparam("jitter"),
|
||||
interface1_id=interface1.node.getifindex(interface1),
|
||||
interface1_name=interface1.name,
|
||||
interface1_mac=interface1.hwaddr,
|
||||
interface1_ip4=interface1_ip4,
|
||||
interface1_ip4_mask=interface1_ip4_mask,
|
||||
interface1_ip6=interface1_ip6,
|
||||
interface1_ip6_mask=interface1_ip6_mask,
|
||||
interface2_id=interface2.node.getifindex(interface2),
|
||||
interface2_name=interface2.name,
|
||||
interface2_mac=interface2.hwaddr,
|
||||
interface2_ip4=interface2_ip4,
|
||||
interface2_ip4_mask=interface2_ip4_mask,
|
||||
interface2_ip6=interface2_ip6,
|
||||
interface2_ip6_mask=interface2_ip6_mask,
|
||||
delay=iface1.getparam("delay"),
|
||||
bandwidth=iface1.getparam("bw"),
|
||||
loss=iface1.getparam("loss"),
|
||||
dup=iface1.getparam("duplicate"),
|
||||
jitter=iface1.getparam("jitter"),
|
||||
iface1_id=iface1.node.get_iface_id(iface1),
|
||||
iface1_name=iface1.name,
|
||||
iface1_mac=iface1.hwaddr,
|
||||
iface1_ip4=iface1_ip4,
|
||||
iface1_ip4_mask=iface1_ip4_mask,
|
||||
iface1_ip6=iface1_ip6,
|
||||
iface1_ip6_mask=iface1_ip6_mask,
|
||||
iface2_id=iface2.node.get_iface_id(iface2),
|
||||
iface2_name=iface2.name,
|
||||
iface2_mac=iface2.hwaddr,
|
||||
iface2_ip4=iface2_ip4,
|
||||
iface2_ip4_mask=iface2_ip4_mask,
|
||||
iface2_ip6=iface2_ip6,
|
||||
iface2_ip6_mask=iface2_ip6_mask,
|
||||
)
|
||||
all_links.append(link_data)
|
||||
|
||||
|
@ -956,16 +956,16 @@ class PtpNet(CoreNetwork):
|
|||
link_data = LinkData(
|
||||
message_type=MessageFlags.NONE,
|
||||
link_type=self.linktype,
|
||||
node1_id=interface2.node.id,
|
||||
node2_id=interface1.node.id,
|
||||
delay=interface2.getparam("delay"),
|
||||
bandwidth=interface2.getparam("bw"),
|
||||
loss=interface2.getparam("loss"),
|
||||
dup=interface2.getparam("duplicate"),
|
||||
jitter=interface2.getparam("jitter"),
|
||||
node1_id=iface2.node.id,
|
||||
node2_id=iface1.node.id,
|
||||
delay=iface2.getparam("delay"),
|
||||
bandwidth=iface2.getparam("bw"),
|
||||
loss=iface2.getparam("loss"),
|
||||
dup=iface2.getparam("duplicate"),
|
||||
jitter=iface2.getparam("jitter"),
|
||||
unidirectional=1,
|
||||
interface1_id=interface2.node.getifindex(interface2),
|
||||
interface2_id=interface1.node.getifindex(interface1),
|
||||
iface1_id=iface2.node.get_iface_id(iface2),
|
||||
iface2_id=iface1.node.get_iface_id(iface1),
|
||||
)
|
||||
all_links.append(link_data)
|
||||
return all_links
|
||||
|
@ -1045,17 +1045,17 @@ class WlanNode(CoreNetwork):
|
|||
self.net_client.disable_mac_learning(self.brname)
|
||||
ebq.ebchange(self)
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach a network interface.
|
||||
|
||||
:param netif: network interface
|
||||
:param iface: network interface
|
||||
:return: nothing
|
||||
"""
|
||||
super().attach(netif)
|
||||
super().attach(iface)
|
||||
if self.model:
|
||||
netif.poshook = self.model.position_callback
|
||||
netif.setposition()
|
||||
iface.poshook = self.model.position_callback
|
||||
iface.setposition()
|
||||
|
||||
def setmodel(self, model: "WirelessModelType", config: Dict[str, str]):
|
||||
"""
|
||||
|
@ -1068,9 +1068,9 @@ class WlanNode(CoreNetwork):
|
|||
logging.debug("node(%s) setting model: %s", self.name, model.name)
|
||||
if model.config_type == RegisterTlvs.WIRELESS:
|
||||
self.model = model(session=self.session, _id=self.id)
|
||||
for netif in self.netifs():
|
||||
netif.poshook = self.model.position_callback
|
||||
netif.setposition()
|
||||
for iface in self.get_ifaces():
|
||||
iface.poshook = self.model.position_callback
|
||||
iface.setposition()
|
||||
self.updatemodel(config)
|
||||
elif model.config_type == RegisterTlvs.MOBILITY:
|
||||
self.mobility = model(session=self.session, _id=self.id)
|
||||
|
@ -1088,8 +1088,8 @@ class WlanNode(CoreNetwork):
|
|||
"node(%s) updating model(%s): %s", self.id, self.model.name, config
|
||||
)
|
||||
self.model.update_config(config)
|
||||
for netif in self.netifs():
|
||||
netif.setposition()
|
||||
for iface in self.get_ifaces():
|
||||
iface.setposition()
|
||||
|
||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||
"""
|
||||
|
|
|
@ -51,8 +51,8 @@ class PhysicalNode(CoreNodeBase):
|
|||
_source, target = self._mounts.pop(-1)
|
||||
self.umount(target)
|
||||
|
||||
for netif in self.netifs():
|
||||
netif.shutdown()
|
||||
for iface in self.get_ifaces():
|
||||
iface.shutdown()
|
||||
|
||||
self.rmnodedir()
|
||||
|
||||
|
@ -65,117 +65,115 @@ class PhysicalNode(CoreNodeBase):
|
|||
"""
|
||||
return sh
|
||||
|
||||
def sethwaddr(self, ifindex: int, addr: str) -> None:
|
||||
def sethwaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Set hardware address for an interface.
|
||||
|
||||
:param ifindex: index of interface to set hardware address for
|
||||
:param iface_id: index of interface to set hardware address for
|
||||
:param addr: hardware address to set
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
addr = utils.validate_mac(addr)
|
||||
interface = self._netif[ifindex]
|
||||
interface.sethwaddr(addr)
|
||||
iface = self.ifaces[iface_id]
|
||||
iface.sethwaddr(addr)
|
||||
if self.up:
|
||||
self.net_client.device_mac(interface.name, addr)
|
||||
self.net_client.device_mac(iface.name, addr)
|
||||
|
||||
def addaddr(self, ifindex: int, addr: str) -> None:
|
||||
def addaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Add an address to an interface.
|
||||
|
||||
:param ifindex: index of interface to add address to
|
||||
:param iface_id: index of interface to add address to
|
||||
:param addr: address to add
|
||||
:return: nothing
|
||||
"""
|
||||
addr = utils.validate_ip(addr)
|
||||
interface = self._netif[ifindex]
|
||||
iface = self.get_iface(iface_id)
|
||||
if self.up:
|
||||
self.net_client.create_address(interface.name, addr)
|
||||
interface.addaddr(addr)
|
||||
self.net_client.create_address(iface.name, addr)
|
||||
iface.addaddr(addr)
|
||||
|
||||
def deladdr(self, ifindex: int, addr: str) -> None:
|
||||
def deladdr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Delete an address from an interface.
|
||||
|
||||
:param ifindex: index of interface to delete
|
||||
:param iface_id: index of interface to delete
|
||||
:param addr: address to delete
|
||||
:return: nothing
|
||||
"""
|
||||
interface = self._netif[ifindex]
|
||||
|
||||
iface = self.ifaces[iface_id]
|
||||
try:
|
||||
interface.deladdr(addr)
|
||||
iface.deladdr(addr)
|
||||
except ValueError:
|
||||
logging.exception("trying to delete unknown address: %s", addr)
|
||||
|
||||
if self.up:
|
||||
self.net_client.delete_address(interface.name, addr)
|
||||
self.net_client.delete_address(iface.name, addr)
|
||||
|
||||
def adoptnetif(
|
||||
self, netif: CoreInterface, ifindex: int, hwaddr: str, addrlist: List[str]
|
||||
def adopt_iface(
|
||||
self, iface: CoreInterface, iface_id: int, hwaddr: str, addrlist: List[str]
|
||||
) -> None:
|
||||
"""
|
||||
When a link message is received linking this node to another part of
|
||||
the emulation, no new interface is created; instead, adopt the
|
||||
GreTap netif as the node interface.
|
||||
GreTap interface as the node interface.
|
||||
"""
|
||||
netif.name = f"gt{ifindex}"
|
||||
netif.node = self
|
||||
self.addnetif(netif, ifindex)
|
||||
iface.name = f"gt{iface_id}"
|
||||
iface.node = self
|
||||
self.add_iface(iface, iface_id)
|
||||
# use a more reasonable name, e.g. "gt0" instead of "gt.56286.150"
|
||||
if self.up:
|
||||
self.net_client.device_down(netif.localname)
|
||||
self.net_client.device_name(netif.localname, netif.name)
|
||||
netif.localname = netif.name
|
||||
self.net_client.device_down(iface.localname)
|
||||
self.net_client.device_name(iface.localname, iface.name)
|
||||
iface.localname = iface.name
|
||||
if hwaddr:
|
||||
self.sethwaddr(ifindex, hwaddr)
|
||||
self.sethwaddr(iface_id, hwaddr)
|
||||
for addr in addrlist:
|
||||
self.addaddr(ifindex, addr)
|
||||
self.addaddr(iface_id, addr)
|
||||
if self.up:
|
||||
self.net_client.device_up(netif.localname)
|
||||
self.net_client.device_up(iface.localname)
|
||||
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Apply tc queing disciplines using linkconfig.
|
||||
"""
|
||||
linux_bridge = CoreNetwork(self.session)
|
||||
linux_bridge.up = True
|
||||
linux_bridge.linkconfig(netif, options, netif2)
|
||||
linux_bridge.linkconfig(iface, options, iface2)
|
||||
del linux_bridge
|
||||
|
||||
def newifindex(self) -> int:
|
||||
def next_iface_id(self) -> int:
|
||||
with self.lock:
|
||||
while self.ifindex in self._netif:
|
||||
self.ifindex += 1
|
||||
ifindex = self.ifindex
|
||||
self.ifindex += 1
|
||||
return ifindex
|
||||
while self.iface_id in self.ifaces:
|
||||
self.iface_id += 1
|
||||
iface_id = self.iface_id
|
||||
self.iface_id += 1
|
||||
return iface_id
|
||||
|
||||
def newnetif(
|
||||
self, net: CoreNetworkBase, interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: CoreNetworkBase, iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
logging.info("creating interface")
|
||||
addresses = interface_data.get_addresses()
|
||||
ifindex = interface_data.id
|
||||
if ifindex is None:
|
||||
ifindex = self.newifindex()
|
||||
name = interface_data.name
|
||||
addresses = iface_data.get_addresses()
|
||||
iface_id = iface_data.id
|
||||
if iface_id is None:
|
||||
iface_id = self.next_iface_id()
|
||||
name = iface_data.name
|
||||
if name is None:
|
||||
name = f"gt{ifindex}"
|
||||
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)
|
||||
self.adoptnetif(remote_tap, ifindex, interface_data.mac, addresses)
|
||||
self.adopt_iface(remote_tap, iface_id, iface_data.mac, addresses)
|
||||
return remote_tap
|
||||
else:
|
||||
# this is reached when configuring services (self.up=False)
|
||||
netif = GreTap(node=self, name=name, session=self.session, start=False)
|
||||
self.adoptnetif(netif, ifindex, interface_data.mac, addresses)
|
||||
return netif
|
||||
iface = GreTap(node=self, name=name, session=self.session, start=False)
|
||||
self.adopt_iface(iface, iface_id, iface_data.mac, addresses)
|
||||
return iface
|
||||
|
||||
def privatedir(self, path: str) -> None:
|
||||
if path[0] != "/":
|
||||
|
@ -257,10 +255,10 @@ class Rj45Node(CoreNodeBase):
|
|||
will run on, default is None for localhost
|
||||
"""
|
||||
super().__init__(session, _id, name, server)
|
||||
self.interface = CoreInterface(session, self, name, name, mtu, server)
|
||||
self.interface.transport_type = TransportType.RAW
|
||||
self.iface = CoreInterface(session, self, name, name, mtu, server)
|
||||
self.iface.transport_type = TransportType.RAW
|
||||
self.lock: threading.RLock = threading.RLock()
|
||||
self.ifindex: Optional[int] = None
|
||||
self.iface_id: Optional[int] = None
|
||||
self.old_up: bool = False
|
||||
self.old_addrs: List[Tuple[str, Optional[str]]] = []
|
||||
|
||||
|
@ -273,7 +271,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
# interface will also be marked up during net.attach()
|
||||
self.savestate()
|
||||
self.net_client.device_up(self.interface.localname)
|
||||
self.net_client.device_up(self.iface.localname)
|
||||
self.up = True
|
||||
|
||||
def shutdown(self) -> None:
|
||||
|
@ -285,7 +283,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
if not self.up:
|
||||
return
|
||||
localname = self.interface.localname
|
||||
localname = self.iface.localname
|
||||
self.net_client.device_down(localname)
|
||||
self.net_client.device_flush(localname)
|
||||
try:
|
||||
|
@ -295,8 +293,8 @@ class Rj45Node(CoreNodeBase):
|
|||
self.up = False
|
||||
self.restorestate()
|
||||
|
||||
def newnetif(
|
||||
self, net: CoreNetworkBase, interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: CoreNetworkBase, iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
"""
|
||||
This is called when linking with another node. Since this node
|
||||
|
@ -304,70 +302,51 @@ class Rj45Node(CoreNodeBase):
|
|||
but attach ourselves to the given network.
|
||||
|
||||
:param net: new network instance
|
||||
:param interface_data: interface data for new interface
|
||||
:param iface_data: interface data for new interface
|
||||
:return: interface index
|
||||
:raises ValueError: when an interface has already been created, one max
|
||||
"""
|
||||
with self.lock:
|
||||
ifindex = interface_data.id
|
||||
if ifindex is None:
|
||||
ifindex = 0
|
||||
if self.interface.net is not None:
|
||||
raise ValueError("RJ45 nodes support at most 1 network interface")
|
||||
self._netif[ifindex] = self.interface
|
||||
self.ifindex = ifindex
|
||||
iface_id = iface_data.id
|
||||
if iface_id is None:
|
||||
iface_id = 0
|
||||
if self.iface.net is not None:
|
||||
raise CoreError("RJ45 nodes support at most 1 network interface")
|
||||
self.ifaces[iface_id] = self.iface
|
||||
self.iface_id = iface_id
|
||||
if net is not None:
|
||||
self.interface.attachnet(net)
|
||||
for addr in interface_data.get_addresses():
|
||||
self.iface.attachnet(net)
|
||||
for addr in iface_data.get_addresses():
|
||||
self.addaddr(addr)
|
||||
return self.interface
|
||||
return self.iface
|
||||
|
||||
def delnetif(self, ifindex: int) -> None:
|
||||
def delete_iface(self, iface_id: int) -> None:
|
||||
"""
|
||||
Delete a network interface.
|
||||
|
||||
:param ifindex: interface index to delete
|
||||
:param iface_id: interface index to delete
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex is None:
|
||||
ifindex = 0
|
||||
self._netif.pop(ifindex)
|
||||
if ifindex == self.ifindex:
|
||||
self.shutdown()
|
||||
else:
|
||||
raise ValueError(f"ifindex {ifindex} does not exist")
|
||||
self.get_iface(iface_id)
|
||||
self.ifaces.pop(iface_id)
|
||||
self.shutdown()
|
||||
|
||||
def netif(
|
||||
self, ifindex: int, net: CoreNetworkBase = None
|
||||
) -> Optional[CoreInterface]:
|
||||
"""
|
||||
This object is considered the network interface, so we only
|
||||
return self here. This keeps the RJ45Node compatible with
|
||||
real nodes.
|
||||
def get_iface(self, iface_id: int) -> CoreInterface:
|
||||
if iface_id != self.iface_id or iface_id not in self.ifaces:
|
||||
raise CoreError(f"node({self.name}) interface({iface_id}) does not exist")
|
||||
return self.iface
|
||||
|
||||
:param ifindex: interface index to retrieve
|
||||
:param net: network to retrieve
|
||||
:return: a network interface
|
||||
"""
|
||||
if net is not None and net == self.interface.net:
|
||||
return self.interface
|
||||
if ifindex is None:
|
||||
ifindex = 0
|
||||
if ifindex == self.ifindex:
|
||||
return self.interface
|
||||
return None
|
||||
|
||||
def getifindex(self, netif: CoreInterface) -> Optional[int]:
|
||||
def get_iface_id(self, iface: CoreInterface) -> Optional[int]:
|
||||
"""
|
||||
Retrieve network interface index.
|
||||
|
||||
:param netif: network interface to retrieve
|
||||
:param iface: network interface to retrieve
|
||||
index for
|
||||
:return: interface index, None otherwise
|
||||
"""
|
||||
if netif != self.interface:
|
||||
return None
|
||||
return self.ifindex
|
||||
if iface is not self.iface:
|
||||
raise CoreError(f"node({self.name}) does not have interface({iface.name})")
|
||||
return self.iface_id
|
||||
|
||||
def addaddr(self, addr: str) -> None:
|
||||
"""
|
||||
|
@ -380,7 +359,7 @@ class Rj45Node(CoreNodeBase):
|
|||
addr = utils.validate_ip(addr)
|
||||
if self.up:
|
||||
self.net_client.create_address(self.name, addr)
|
||||
self.interface.addaddr(addr)
|
||||
self.iface.addaddr(addr)
|
||||
|
||||
def deladdr(self, addr: str) -> None:
|
||||
"""
|
||||
|
@ -392,7 +371,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
if self.up:
|
||||
self.net_client.delete_address(self.name, addr)
|
||||
self.interface.deladdr(addr)
|
||||
self.iface.deladdr(addr)
|
||||
|
||||
def savestate(self) -> None:
|
||||
"""
|
||||
|
@ -404,7 +383,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
self.old_up = False
|
||||
self.old_addrs: List[Tuple[str, Optional[str]]] = []
|
||||
localname = self.interface.localname
|
||||
localname = self.iface.localname
|
||||
output = self.net_client.address_show(localname)
|
||||
for line in output.split("\n"):
|
||||
items = line.split()
|
||||
|
@ -429,7 +408,7 @@ class Rj45Node(CoreNodeBase):
|
|||
:return: nothing
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
"""
|
||||
localname = self.interface.localname
|
||||
localname = self.iface.localname
|
||||
logging.info("restoring rj45 state: %s", localname)
|
||||
for addr in self.old_addrs:
|
||||
self.net_client.create_address(localname, addr[0], addr[1])
|
||||
|
@ -446,7 +425,7 @@ class Rj45Node(CoreNodeBase):
|
|||
:return: True if position changed, False otherwise
|
||||
"""
|
||||
super().setposition(x, y, z)
|
||||
self.interface.setposition()
|
||||
self.iface.setposition()
|
||||
|
||||
def termcmdstring(self, sh: str) -> str:
|
||||
raise CoreError("rj45 does not support terminal commands")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue