updates to netclient, providing commonly used network commands in more convenient functions

This commit is contained in:
bharnden 2019-10-01 12:14:37 -07:00
parent a798774f18
commit e4bb315c14
6 changed files with 203 additions and 324 deletions

View file

@ -7,7 +7,7 @@ import logging
import os
import threading
from core import constants, utils
from core import utils
from core.api.tlv import coreapi, dataconversion
from core.config import ConfigGroup, ConfigShim, Configuration, ModelManager
from core.emane import emanemanifest
@ -733,13 +733,11 @@ class EmaneManager(ModelManager):
)
# multicast route is needed for OTA data
args = [constants.IP_BIN, "route", "add", otagroup, "dev", otadev]
node.network_cmd(args)
node.node_net_client.add_route(otagroup, otadev)
# multicast route is also needed for event data if on control network
if eventservicenetidx >= 0 and eventgroup != otagroup:
args = [constants.IP_BIN, "route", "add", eventgroup, "dev", eventdev]
node.network_cmd(args)
node.node_net_client.add_route(eventgroup, eventdev)
# start emane
args = emanecmd + [

View file

@ -62,6 +62,11 @@ class NodeBase(object):
self.opaque = None
self.position = Position()
if session.options.get_config("ovs") == "True":
self.net_client = OvsNetClient(utils.check_cmd)
else:
self.net_client = LinuxNetClient(utils.check_cmd)
def startup(self):
"""
Each object implements its own startup method.
@ -434,6 +439,12 @@ class CoreNode(CoreNodeBase):
self.lock = threading.RLock()
self._mounts = []
self.bootsh = bootsh
if session.options.get_config("ovs") == "True":
self.node_net_client = OvsNetClient(self.network_cmd)
else:
self.node_net_client = LinuxNetClient(self.network_cmd)
if start:
self.startup()
@ -489,11 +500,11 @@ class CoreNode(CoreNodeBase):
# bring up the loopback interface
logging.debug("bringing up loopback interface")
self.network_cmd([constants.IP_BIN, "link", "set", "lo", "up"])
self.node_net_client.device_up("lo")
# set hostname for node
logging.debug("setting hostname: %s", self.name)
self.network_cmd(["hostname", self.name])
self.node_net_client.set_hostname(self.name)
# mark node as up
self.up = True
@ -682,22 +693,16 @@ class CoreNode(CoreNodeBase):
)
if self.up:
utils.check_cmd(
[constants.IP_BIN, "link", "set", veth.name, "netns", str(self.pid)]
)
self.network_cmd(
[constants.IP_BIN, "link", "set", veth.name, "name", ifname]
)
self.network_cmd(
[constants.ETHTOOL_BIN, "-K", ifname, "rx", "off", "tx", "off"]
)
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:
# TODO: potentially find better way to query interface ID
# retrieve interface information
output = self.network_cmd([constants.IP_BIN, "link", "show", veth.name])
output = self.node_net_client.device_show(veth.name)
logging.debug("interface command output: %s", output)
output = output.split("\n")
veth.flow_id = int(output[0].strip().split(":")[0]) + 1
@ -707,7 +712,8 @@ class CoreNode(CoreNodeBase):
logging.debug("interface mac: %s - %s", veth.name, veth.hwaddr)
try:
# add network interface to the node. If unsuccessful, destroy the network interface and raise exception.
# add network interface to the node. If unsuccessful, destroy the
# network interface and raise exception.
self.addnetif(veth, ifindex)
except ValueError as e:
veth.shutdown()
@ -758,79 +764,47 @@ class CoreNode(CoreNodeBase):
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
self._netif[ifindex].sethwaddr(addr)
interface = self._netif[ifindex]
interface.sethwaddr(addr)
if self.up:
args = [
constants.IP_BIN,
"link",
"set",
"dev",
self.ifname(ifindex),
"address",
str(addr),
]
self.network_cmd(args)
self.node_net_client.device_mac(interface.name, str(addr))
def addaddr(self, ifindex, addr):
"""
Add interface address.
:param int ifindex: index of interface to add address to
:param str addr: address to add to interface
:param core.nodes.ipaddress.IpAddress addr: address to add to interface
:return: nothing
"""
interface = self._netif[ifindex]
interface.addaddr(addr)
if self.up:
# check if addr is ipv6
if ":" in str(addr):
args = [
constants.IP_BIN,
"addr",
"add",
str(addr),
"dev",
self.ifname(ifindex),
]
self.network_cmd(args)
else:
args = [
constants.IP_BIN,
"addr",
"add",
str(addr),
"broadcast",
"+",
"dev",
self.ifname(ifindex),
]
self.network_cmd(args)
self._netif[ifindex].addaddr(addr)
address = str(addr)
# ipv6 check
broadcast = None
if ":" not in address:
broadcast = "+"
self.node_net_client.create_address(interface.name, address, broadcast)
def deladdr(self, ifindex, addr):
"""
Delete address from an interface.
:param int ifindex: index of interface to delete address from
:param str addr: address to delete from interface
:param core.nodes.ipaddress.IpAddress addr: address to delete from interface
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
interface = self._netif[ifindex]
try:
self._netif[ifindex].deladdr(addr)
interface.deladdr(addr)
except ValueError:
logging.exception("trying to delete unknown address: %s" % addr)
if self.up:
self.network_cmd(
[
constants.IP_BIN,
"addr",
"del",
str(addr),
"dev",
self.ifname(ifindex),
]
)
self.node_net_client.delete_address(interface.name, str(addr))
def delalladdr(self, ifindex, address_types=None):
"""
@ -866,9 +840,8 @@ class CoreNode(CoreNodeBase):
:return: nothing
"""
if self.up:
self.network_cmd(
[constants.IP_BIN, "link", "set", self.ifname(ifindex), "up"]
)
interface_name = self.ifname(ifindex)
self.node_net_client.device_up(interface_name)
def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None):
"""
@ -919,7 +892,7 @@ class CoreNode(CoreNodeBase):
Connect a node.
:param str ifname: name of interface to connect
:param core.nodes.CoreNodeBase othernode: node to connect to
:param core.nodes.base.CoreNode othernode: node to connect to
:param str otherifname: interface name to connect to
:return: nothing
"""
@ -930,32 +903,14 @@ class CoreNode(CoreNodeBase):
tmp2 = "tmp." + "".join(
[random.choice(string.ascii_lowercase) for _ in range(tmplen)]
)
utils.check_cmd(
[
constants.IP_BIN,
"link",
"add",
"name",
tmp1,
"type",
"veth",
"peer",
"name",
tmp2,
]
)
utils.check_cmd([constants.IP_BIN, "link", "set", tmp1, "netns", str(self.pid)])
self.network_cmd([constants.IP_BIN, "link", "set", tmp1, "name", ifname])
self.net_client.create_veth(tmp1, tmp2)
self.net_client.device_ns(tmp1, str(self.pid))
self.node_net_client.device_name(tmp1, ifname)
interface = CoreInterface(node=self, name=ifname, mtu=_DEFAULT_MTU)
self.addnetif(interface, self.newifindex())
utils.check_cmd(
[constants.IP_BIN, "link", "set", tmp2, "netns", str(othernode.pid)]
)
othernode.network_cmd(
[constants.IP_BIN, "link", "set", tmp2, "name", otherifname]
)
self.net_client.device_ns(tmp2, str(othernode.pid))
othernode.node_net_client.device_name(tmp2, otherifname)
other_interface = CoreInterface(
node=othernode, name=otherifname, mtu=_DEFAULT_MTU
)
@ -1064,10 +1019,6 @@ class CoreNetworkBase(NodeBase):
super(CoreNetworkBase, self).__init__(session, _id, name, start=start)
self._linked = {}
self._linked_lock = threading.Lock()
if session.options.get_config("ovs") == "True":
self.net_client = OvsNetClient()
else:
self.net_client = LinuxNetClient()
def startup(self):
"""

View file

@ -6,8 +6,9 @@ import logging
import time
from builtins import int, range
from core import constants, utils
from core import utils
from core.errors import CoreCommandError
from core.nodes.netclient import LinuxNetClient
class CoreInterface(object):
@ -41,6 +42,7 @@ class CoreInterface(object):
self.netindex = None
# index used to find flow data
self.flow_id = None
self.net_client = LinuxNetClient(utils.check_cmd)
def startup(self):
"""
@ -216,21 +218,8 @@ class Veth(CoreInterface):
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
utils.check_cmd(
[
constants.IP_BIN,
"link",
"add",
"name",
self.localname,
"type",
"veth",
"peer",
"name",
self.name,
]
)
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
self.net_client.create_veth(self.localname, self.name)
self.net_client.device_up(self.localname)
self.up = True
def shutdown(self):
@ -244,15 +233,13 @@ class Veth(CoreInterface):
if self.node:
try:
self.node.network_cmd(
[constants.IP_BIN, "-6", "addr", "flush", "dev", self.name]
)
self.node.node_net_client.device_flush(self.name)
except CoreCommandError:
logging.exception("error shutting down interface")
if self.localname:
try:
utils.check_cmd([constants.IP_BIN, "link", "delete", self.localname])
self.net_client.delete_device(self.localname)
except CoreCommandError:
logging.info("link already removed: %s", self.localname)
@ -307,9 +294,7 @@ class TunTap(CoreInterface):
return
try:
self.node.network_cmd(
[constants.IP_BIN, "-6", "addr", "flush", "dev", self.name]
)
self.node.node_net_client.device_flush(self.name)
except CoreCommandError:
logging.exception("error shutting down tunnel tap")
@ -357,8 +342,11 @@ class TunTap(CoreInterface):
logging.debug("waiting for device local: %s", self.localname)
def localdevexists():
args = [constants.IP_BIN, "link", "show", self.localname]
return utils.cmd(args)
try:
self.net_client.device_show(self.localname)
return 0
except CoreCommandError:
return 1
self.waitfor(localdevexists)
@ -371,9 +359,8 @@ class TunTap(CoreInterface):
logging.debug("waiting for device node: %s", self.name)
def nodedevexists():
args = [constants.IP_BIN, "link", "show", self.name]
try:
self.node.network_cmd(args)
self.node.node_net_client.device_show(self.name)
return 0
except CoreCommandError:
return 1
@ -406,13 +393,9 @@ class TunTap(CoreInterface):
"""
self.waitfordevicelocal()
netns = str(self.node.pid)
utils.check_cmd(
[constants.IP_BIN, "link", "set", self.localname, "netns", netns]
)
self.node.network_cmd(
[constants.IP_BIN, "link", "set", self.localname, "name", self.name]
)
self.node.network_cmd([constants.IP_BIN, "link", "set", self.name, "up"])
self.net_client.device_ns(self.localname, netns)
self.node.node_net_client.device_name(self.localname, self.name)
self.node.node_net_client.device_up(self.name)
def setaddrs(self):
"""
@ -422,9 +405,7 @@ class TunTap(CoreInterface):
"""
self.waitfordevicenode()
for addr in self.addrlist:
self.node.network_cmd(
[constants.IP_BIN, "addr", "add", str(addr), "dev", self.name]
)
self.node.node_net_client.create_address(self.name, str(addr))
class GreTap(CoreInterface):
@ -478,25 +459,11 @@ class GreTap(CoreInterface):
if remoteip is None:
raise ValueError("missing remote IP required for GRE TAP device")
args = [
constants.IP_BIN,
"link",
"add",
self.localname,
"type",
"gretap",
"remote",
str(remoteip),
]
if localip:
args += ["local", str(localip)]
if ttl:
args += ["ttl", str(ttl)]
if key:
args += ["key", str(key)]
utils.check_cmd(args)
args = [constants.IP_BIN, "link", "set", self.localname, "up"]
utils.check_cmd(args)
self.net_client.create_gretap(
self.localname, str(remoteip), str(localip), str(ttl), str(key)
)
self.net_client.device_up(self.localname)
self.up = True
def shutdown(self):
@ -507,10 +474,8 @@ class GreTap(CoreInterface):
"""
if self.localname:
try:
args = [constants.IP_BIN, "link", "set", self.localname, "down"]
utils.check_cmd(args)
args = [constants.IP_BIN, "link", "del", self.localname]
utils.check_cmd(args)
self.net_client.device_down(self.localname)
self.net_client.delete_device(self.localname)
except CoreCommandError:
logging.exception("error during shutdown")

View file

@ -2,87 +2,94 @@
Clients for dealing with bridge/interface commands.
"""
import abc
import os
from future.utils import with_metaclass
from core.constants import BRCTL_BIN, IP_BIN, OVS_BIN
from core.constants import BRCTL_BIN, ETHTOOL_BIN, IP_BIN, OVS_BIN, TC_BIN
from core.utils import check_cmd
class NetClientBase(with_metaclass(abc.ABCMeta)):
"""
Base client for running command line bridge/interface commands.
"""
@abc.abstractmethod
def create_bridge(self, name):
"""
Create a network bridge to connect interfaces to.
:param str name: bridge name
:return: nothing
"""
pass
@abc.abstractmethod
def delete_bridge(self, name):
"""
Delete a network bridge.
:param str name: bridge name
:return: nothing
"""
pass
@abc.abstractmethod
def create_interface(self, bridge_name, interface_name):
"""
Create an interface associated with a network bridge.
:param str bridge_name: bridge name
:param str interface_name: interface name
:return: nothing
"""
pass
@abc.abstractmethod
def delete_interface(self, bridge_name, interface_name):
"""
Delete an interface associated with a network bridge.
:param str bridge_name: bridge name
:param str interface_name: interface name
:return: nothing
"""
pass
@abc.abstractmethod
def existing_bridges(self, _id):
"""
Checks if there are any existing bridges for a node.
:param _id: node id to check bridges for
"""
pass
@abc.abstractmethod
def disable_mac_learning(self, name):
"""
Disable mac learning for a bridge.
:param str name: bridge name
:return: nothing
"""
pass
class LinuxNetClient(NetClientBase):
class LinuxNetClient(object):
"""
Client for creating Linux bridges and ip interfaces for nodes.
"""
def __init__(self, run_func):
self.run_func = run_func
def run(self, cmd):
return self.run_func(cmd)
def set_hostname(self, name):
self.run(["hostname", name])
def add_route(self, route, device):
self.run([IP_BIN, "route", "add", route, "dev", device])
def device_up(self, device):
self.run([IP_BIN, "link", "set", device, "up"])
def device_down(self, device):
self.run([IP_BIN, "link", "set", device, "down"])
def device_name(self, device, name):
self.run([IP_BIN, "link", "set", device, "name", name])
def device_show(self, device):
return self.run([IP_BIN, "link", "show", device])
def device_ns(self, device, namespace):
self.run([IP_BIN, "link", "set", device, "netns", namespace])
def device_flush(self, device):
self.run([IP_BIN, "-6", "address", "flush", "dev", device])
def device_mac(self, device, mac):
self.run([IP_BIN, "link", "set", "dev", device, "address", mac])
def delete_device(self, device):
self.run([IP_BIN, "link", "delete", device])
def delete_tc(self, device):
self.run([TC_BIN, "qdisc", "del", "dev", device, "root"])
def checksums_off(self, interface_name):
self.run([ETHTOOL_BIN, "-K", interface_name, "rx", "off", "tx", "off"])
def delete_address(self, device, address):
self.run([IP_BIN, "address", "delete", address, "dev", device])
def create_veth(self, name, peer):
self.run(
[IP_BIN, "link", "add", "name", name, "type", "veth", "peer", "name", peer]
)
def create_gretap(self, device, address, local, ttl, key):
cmd = [IP_BIN, "link", "add", device, "type", "gretap", "remote", address]
if local is not None:
cmd.extend(["local", local])
if ttl is not None:
cmd.extend(["ttl", ttl])
if key is not None:
cmd.extend(["key", key])
self.run(cmd)
def create_address(self, device, address, broadcast=None):
if broadcast is not None:
self.run(
[
IP_BIN,
"address",
"add",
address,
"broadcast",
broadcast,
"dev",
device,
]
)
else:
self.run([IP_BIN, "address", "add", address, "dev", device])
def create_bridge(self, name):
"""
Create a Linux bridge and bring it up.
@ -90,10 +97,10 @@ class LinuxNetClient(NetClientBase):
:param str name: bridge name
:return: nothing
"""
check_cmd([BRCTL_BIN, "addbr", name])
check_cmd([BRCTL_BIN, "stp", name, "off"])
check_cmd([BRCTL_BIN, "setfd", name, "0"])
check_cmd([IP_BIN, "link", "set", name, "up"])
self.run([BRCTL_BIN, "addbr", name])
self.run([BRCTL_BIN, "stp", name, "off"])
self.run([BRCTL_BIN, "setfd", name, "0"])
self.device_up(name)
# turn off multicast snooping so forwarding occurs w/o IGMP joins
snoop = "/sys/devices/virtual/net/%s/bridge/multicast_snooping" % name
@ -108,8 +115,8 @@ class LinuxNetClient(NetClientBase):
:param str name: bridge name
:return: nothing
"""
check_cmd([IP_BIN, "link", "set", name, "down"])
check_cmd([BRCTL_BIN, "delbr", name])
self.device_down(name)
self.run([BRCTL_BIN, "delbr", name])
def create_interface(self, bridge_name, interface_name):
"""
@ -119,8 +126,8 @@ class LinuxNetClient(NetClientBase):
:param str interface_name: interface name
:return: nothing
"""
check_cmd([BRCTL_BIN, "addif", bridge_name, interface_name])
check_cmd([IP_BIN, "link", "set", interface_name, "up"])
self.run([BRCTL_BIN, "addif", bridge_name, interface_name])
self.device_up(interface_name)
def delete_interface(self, bridge_name, interface_name):
"""
@ -130,7 +137,7 @@ class LinuxNetClient(NetClientBase):
:param str interface_name: interface name
:return: nothing
"""
check_cmd([BRCTL_BIN, "delif", bridge_name, interface_name])
self.run([BRCTL_BIN, "delif", bridge_name, interface_name])
def existing_bridges(self, _id):
"""
@ -138,7 +145,7 @@ class LinuxNetClient(NetClientBase):
:param _id: node id to check bridges for
"""
output = check_cmd([BRCTL_BIN, "show"])
output = self.run([BRCTL_BIN, "show"])
lines = output.split("\n")
for line in lines[1:]:
columns = line.split()
@ -160,7 +167,7 @@ class LinuxNetClient(NetClientBase):
check_cmd([BRCTL_BIN, "setageing", name, "0"])
class OvsNetClient(NetClientBase):
class OvsNetClient(LinuxNetClient):
"""
Client for creating OVS bridges and ip interfaces for nodes.
"""
@ -172,11 +179,11 @@ class OvsNetClient(NetClientBase):
:param str name: bridge name
:return: nothing
"""
check_cmd([OVS_BIN, "add-br", name])
check_cmd([OVS_BIN, "set", "bridge", name, "stp_enable=false"])
check_cmd([OVS_BIN, "set", "bridge", name, "other_config:stp-max-age=6"])
check_cmd([OVS_BIN, "set", "bridge", name, "other_config:stp-forward-delay=4"])
check_cmd([IP_BIN, "link", "set", name, "up"])
self.run([OVS_BIN, "add-br", name])
self.run([OVS_BIN, "set", "bridge", name, "stp_enable=false"])
self.run([OVS_BIN, "set", "bridge", name, "other_config:stp-max-age=6"])
self.run([OVS_BIN, "set", "bridge", name, "other_config:stp-forward-delay=4"])
self.device_up(name)
def delete_bridge(self, name):
"""
@ -185,8 +192,8 @@ class OvsNetClient(NetClientBase):
:param str name: bridge name
:return: nothing
"""
check_cmd([IP_BIN, "link", "set", name, "down"])
check_cmd([OVS_BIN, "del-br", name])
self.device_down(name)
self.run([OVS_BIN, "del-br", name])
def create_interface(self, bridge_name, interface_name):
"""
@ -196,8 +203,8 @@ class OvsNetClient(NetClientBase):
:param str interface_name: interface name
:return: nothing
"""
check_cmd([OVS_BIN, "add-port", bridge_name, interface_name])
check_cmd([IP_BIN, "link", "set", interface_name, "up"])
self.run([OVS_BIN, "add-port", bridge_name, interface_name])
self.device_up(interface_name)
def delete_interface(self, bridge_name, interface_name):
"""
@ -207,7 +214,7 @@ class OvsNetClient(NetClientBase):
:param str interface_name: interface name
:return: nothing
"""
check_cmd([OVS_BIN, "del-port", bridge_name, interface_name])
self.run([OVS_BIN, "del-port", bridge_name, interface_name])
def existing_bridges(self, _id):
"""
@ -215,7 +222,7 @@ class OvsNetClient(NetClientBase):
:param _id: node id to check bridges for
"""
output = check_cmd([OVS_BIN, "list-br"])
output = self.run([OVS_BIN, "list-br"])
if output:
for line in output.split("\n"):
fields = line.split(".")
@ -230,4 +237,4 @@ class OvsNetClient(NetClientBase):
:param str name: bridge name
:return: nothing
"""
check_cmd([OVS_BIN, "set", "bridge", name, "other_config:mac-aging-time=0"])
self.run([OVS_BIN, "set", "bridge", name, "other_config:mac-aging-time=0"])

View file

@ -629,9 +629,7 @@ class CoreNetwork(CoreNetworkBase):
return
for addr in addrlist:
utils.check_cmd(
[constants.IP_BIN, "addr", "add", str(addr), "dev", self.brname]
)
self.net_client.create_address(self.brname, str(addr))
class GreTapBridge(CoreNetwork):

View file

@ -100,51 +100,33 @@ class PhysicalNode(CoreNodeBase):
"""
Set hardware address for an interface.
"""
self._netif[ifindex].sethwaddr(addr)
ifname = self.ifname(ifindex)
interface = self._netif[ifindex]
interface.sethwaddr(addr)
if self.up:
self.check_cmd(
[constants.IP_BIN, "link", "set", "dev", ifname, "address", str(addr)]
)
self.net_client.device_mac(interface.name, str(addr))
def addaddr(self, ifindex, addr):
"""
Add an address to an interface.
"""
interface = self._netif[ifindex]
if self.up:
self.check_cmd(
[
constants.IP_BIN,
"addr",
"add",
str(addr),
"dev",
self.ifname(ifindex),
]
)
self._netif[ifindex].addaddr(addr)
self.net_client.create_address(interface.name, str(addr))
interface.addaddr(addr)
def deladdr(self, ifindex, addr):
"""
Delete an address from an interface.
"""
interface = self._netif[ifindex]
try:
self._netif[ifindex].deladdr(addr)
interface.deladdr(addr)
except ValueError:
logging.exception("trying to delete unknown address: %s", addr)
if self.up:
self.check_cmd(
[
constants.IP_BIN,
"addr",
"del",
str(addr),
"dev",
self.ifname(ifindex),
]
)
self.net_client.delete_address(interface.name, str(addr))
def adoptnetif(self, netif, ifindex, hwaddr, addrlist):
"""
@ -159,12 +141,8 @@ class PhysicalNode(CoreNodeBase):
# use a more reasonable name, e.g. "gt0" instead of "gt.56286.150"
if self.up:
self.check_cmd(
[constants.IP_BIN, "link", "set", "dev", netif.localname, "down"]
)
self.check_cmd(
[constants.IP_BIN, "link", "set", netif.localname, "name", netif.name]
)
self.net_client.device_down(netif.localname)
self.net_client.device_name(netif.localname, netif.name)
netif.localname = netif.name
@ -175,9 +153,7 @@ class PhysicalNode(CoreNodeBase):
self.addaddr(ifindex, addr)
if self.up:
self.check_cmd(
[constants.IP_BIN, "link", "set", "dev", netif.localname, "up"]
)
self.net_client.device_up(netif.localname)
def linkconfig(
self,
@ -335,7 +311,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
"""
# interface will also be marked up during net.attach()
self.savestate()
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
self.net_client.device_up(self.localname)
self.up = True
def shutdown(self):
@ -349,18 +325,17 @@ class Rj45Node(CoreNodeBase, CoreInterface):
return
try:
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "down"])
utils.check_cmd([constants.IP_BIN, "addr", "flush", "dev", self.localname])
utils.check_cmd(
[constants.TC_BIN, "qdisc", "del", "dev", self.localname, "root"]
)
self.net_client.device_down(self.localname)
self.net_client.device_flush(self.localname)
self.net_client.delete_tc(self.localname)
except CoreCommandError:
logging.exception("error shutting down")
self.up = False
self.restorestate()
# TODO: issue in that both classes inherited from provide the same method with different signatures
# TODO: issue in that both classes inherited from provide the same method with
# different signatures
def attachnet(self, net):
"""
Attach a network.
@ -370,7 +345,8 @@ class Rj45Node(CoreNodeBase, CoreInterface):
"""
CoreInterface.attachnet(self, net)
# TODO: issue in that both classes inherited from provide the same method with different signatures
# TODO: issue in that both classes inherited from provide the same method with
# different signatures
def detachnet(self):
"""
Detach a network.
@ -476,9 +452,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
:raises CoreCommandError: when there is a command exception
"""
if self.up:
utils.check_cmd(
[constants.IP_BIN, "addr", "add", str(addr), "dev", self.name]
)
self.net_client.create_address(self.name, str(addr))
CoreInterface.addaddr(self, addr)
@ -491,9 +465,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
:raises CoreCommandError: when there is a command exception
"""
if self.up:
utils.check_cmd(
[constants.IP_BIN, "addr", "del", str(addr), "dev", self.name]
)
self.net_client.delete_address(self.name, str(addr))
CoreInterface.deladdr(self, addr)
@ -507,8 +479,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
"""
self.old_up = False
self.old_addrs = []
args = [constants.IP_BIN, "addr", "show", "dev", self.localname]
output = utils.check_cmd(args)
output = self.net_client.device_show(self.localname)
for line in output.split("\n"):
items = line.split()
if len(items) < 2:
@ -534,25 +505,14 @@ class Rj45Node(CoreNodeBase, CoreInterface):
"""
for addr in self.old_addrs:
if addr[1] is None:
utils.check_cmd(
[constants.IP_BIN, "addr", "add", addr[0], "dev", self.localname]
)
self.net_client.create_address(self.localname, addr[0])
else:
utils.check_cmd(
[
constants.IP_BIN,
"addr",
"add",
addr[0],
"brd",
addr[1],
"dev",
self.localname,
]
self.net_client.create_address(
self.localname, addr[0], broadcast=addr[1]
)
if self.old_up:
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
self.net_client.device_up(self.localname)
def setposition(self, x=None, y=None, z=None):
"""