def shutdown(self): """ Control network shutdown. :return: nothing """ if self.serverintf is not None: try: utils.check_cmd([ constants.BRCTL_BIN, "delif", self.brname, self.serverintf ]) except CoreCommandError: logging.exception( "error deleting server interface %s from bridge %s", self.serverintf, self.brname) if self.updown_script is not None: try: logging.info("interface %s updown script (%s shutdown) called", self.brname, self.updown_script) utils.check_cmd([self.updown_script, self.brname, "shutdown"]) except CoreCommandError: logging.exception("error issuing shutdown script shutdown") LxBrNet.shutdown(self)
def test_link_update(self, session, ip_prefixes): # given node_one = session.add_node() node_two = session.add_node(_type=NodeTypes.SWITCH) interface_one = ip_prefixes.create_interface(node_one) session.add_link(node_one.objid, node_two.objid, interface_one) interface = node_one.netif(interface_one.id) output = utils.check_cmd( ["tc", "qdisc", "show", "dev", interface.localname]) assert "delay" not in output assert "rate" not in output assert "loss" not in output assert "duplicate" not in output # when link_options = LinkOptions() link_options.delay = 50 link_options.bandwidth = 5000000 link_options.per = 25 link_options.dup = 25 session.update_link(node_one.objid, node_two.objid, interface_one_id=interface_one.id, link_options=link_options) # then output = utils.check_cmd( ["tc", "qdisc", "show", "dev", interface.localname]) assert "delay" in output assert "rate" in output assert "loss" in output assert "duplicate" in output
def shutdown(self): if not self.up: logger.info("exiting shutdown, object is not up") return ebtables_queue.stopupdateloop(self) try: utils.check_cmd( [constants.IP_BIN, "link", "set", self.bridge_name, "down"]) utils.check_cmd([constants.OVS_BIN, "del-br", self.bridge_name]) ebtables_commands(utils.check_cmd, [[ constants.EBTABLES_BIN, "-D", "FORWARD", "--logical-in", self.bridge_name, "-j", self.bridge_name ], [constants.EBTABLES_BIN, "-X", self.bridge_name]]) except CoreCommandError: logger.exception("error bringing bridge down and removing it") # removes veth pairs used for bridge-to-bridge connections for interface in self.netifs(): interface.shutdown() self._netif.clear() self._linked.clear() del self.session self.up = False
def shutdown(self): """ Interface shutdown logic. :return: nothing """ if not self.up: return if self.node: try: self.node.check_cmd([ constants.IP_BIN, "-6", "addr", "flush", "dev", self.name ]) except CoreCommandError: logger.exception("error shutting down interface") if self.localname: try: utils.check_cmd( [constants.IP_BIN, "link", "delete", self.localname]) except CoreCommandError: logger.exception("error deleting link") self.up = False
def test_link_update(self, session, ip_prefixes): # given node_one = session.add_node() node_two = session.add_node(_type=NodeTypes.SWITCH) interface_one = ip_prefixes.create_interface(node_one) session.add_link(node_one.objid, node_two.objid, interface_one) interface = node_one.netif(interface_one.id) output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname]) assert "delay" not in output assert "rate" not in output assert "loss" not in output assert "duplicate" not in output # when link_options = LinkOptions() link_options.delay = 50 link_options.bandwidth = 5000000 link_options.per = 25 link_options.dup = 25 session.update_link(node_one.objid, node_two.objid, interface_one_id=interface_one.id, link_options=link_options) # then output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname]) assert "delay" in output assert "rate" in output assert "loss" in output assert "duplicate" in output
def startup(self): """ :return: :raises CoreCommandError: when there is a command exception """ utils.check_cmd([constants.OVS_BIN, "add-br", self.bridge_name]) # turn off spanning tree protocol and forwarding delay # TODO: appears stp and rstp are off by default, make sure this always holds true # TODO: apears ovs only supports rstp forward delay and again it's off by default utils.check_cmd( [constants.IP_BIN, "link", "set", self.bridge_name, "up"]) # create a new ebtables chain for this bridge ebtables_commands( utils.check_cmd, [[ constants.EBTABLES_BIN, "-N", self.bridge_name, "-P", self.policy ], [ constants.EBTABLES_BIN, "-A", "FORWARD", "--logical-in", self.bridge_name, "-j", self.bridge_name ]]) self.up = True
def shutdown(self): """ Linux bridge shutdown logic. :return: nothing """ if not self.up: return ebq.stopupdateloop(self) try: utils.check_cmd( [constants.IP_BIN, "link", "set", self.brname, "down"]) utils.check_cmd([constants.BRCTL_BIN, "delbr", self.brname]) ebtablescmds(utils.check_cmd, [[ constants.EBTABLES_BIN, "-D", "FORWARD", "--logical-in", self.brname, "-j", self.brname ], [constants.EBTABLES_BIN, "-X", self.brname]]) except CoreCommandError: logging.exception("error during shutdown") # removes veth pairs used for bridge-to-bridge connections for netif in self.netifs(): netif.shutdown() self._netif.clear() self._linked.clear() del self.session self.up = False
def shutdown(self): if not self.up: logger.info("exiting shutdown, object is not up") return ebtables_queue.stopupdateloop(self) try: utils.check_cmd([constants.IP_BIN, "link", "set", self.bridge_name, "down"]) utils.check_cmd([constants.OVS_BIN, "del-br", self.bridge_name]) ebtables_commands(utils.check_cmd, [ [constants.EBTABLES_BIN, "-D", "FORWARD", "--logical-in", self.bridge_name, "-j", self.bridge_name], [constants.EBTABLES_BIN, "-X", self.bridge_name] ]) except CoreCommandError: logger.exception("error bringing bridge down and removing it") # removes veth pairs used for bridge-to-bridge connections for interface in self.netifs(): interface.shutdown() self._netif.clear() self._linked.clear() del self.session self.up = False
def shutdown(self): """ Linux bridge shutdown logic. :return: nothing """ if not self.up: return ebq.stopupdateloop(self) try: utils.check_cmd([constants.IP_BIN, "link", "set", self.brname, "down"]) utils.check_cmd([constants.BRCTL_BIN, "delbr", self.brname]) ebtablescmds(utils.check_cmd, [ [constants.EBTABLES_BIN, "-D", "FORWARD", "--logical-in", self.brname, "-j", self.brname], [constants.EBTABLES_BIN, "-X", self.brname] ]) except CoreCommandError: logger.exception("error during shutdown") # removes veth pairs used for bridge-to-bridge connections for netif in self.netifs(): netif.shutdown() self._netif.clear() self._linked.clear() del self.session self.up = False
def detach(self, interface): if self.up: utils.check_cmd([ constants.OVS_BIN, "del-port", self.bridge_name, interface.localname ]) PyCoreNet.detach(self, interface)
def newveth(self, ifindex=None, ifname=None, net=None): """ Create a new interface. :param int ifindex: index for the new interface :param str ifname: name for the new interface :param net: network to associate interface with :return: nothing """ with self.lock: if ifindex is None: ifindex = self.newifindex() if ifname is None: ifname = "eth%d" % ifindex sessionid = self.session.short_session_id() try: suffix = "%x.%s.%s" % (self.objid, ifindex, sessionid) except TypeError: suffix = "%s.%s.%s" % (self.objid, ifindex, sessionid) localname = "veth" + suffix if len(localname) >= 16: raise ValueError("interface local name (%s) too long" % localname) name = localname + "p" if len(name) >= 16: raise ValueError("interface name (%s) too long" % name) veth = VEth(node=self, name=name, localname=localname, net=net, start=self.up) if self.up: utils.check_cmd([constants.IP_BIN, "link", "set", veth.name, "netns", str(self.pid)]) self.check_cmd([constants.IP_BIN, "link", "set", veth.name, "name", ifname]) veth.name = ifname if self.up: # TODO: potentially find better way to query interface ID # retrieve interface information output = self.check_cmd(["ip", "link", "show", veth.name]) logger.debug("interface command output: %s", output) output = output.split("\n") veth.flow_id = int(output[0].strip().split(":")[0]) + 1 logger.debug("interface flow index: %s - %s", veth.name, veth.flow_id) veth.hwaddr = MacAddress.from_string(output[1].strip().split()[1]) logger.debug("interface mac: %s - %s", veth.name, veth.hwaddr) try: self.addnetif(veth, ifindex) except ValueError as e: veth.shutdown() del veth raise e return ifindex
def __init__(self, node=None, name=None, session=None, mtu=1458, remoteip=None, objid=None, localip=None, ttl=255, key=None, start=True): """ Creates a GreTap instance. :param core.netns.vnode.SimpleLxcNode node: related core node :param str name: interface name :param core.session.Session session: core session instance :param mtu: interface mtu :param str remoteip: remote address :param int objid: object id :param str localip: local address :param ttl: ttl value :param key: gre tap key :param bool start: start flag :raises CoreCommandError: when there is a command exception """ PyCoreNetIf.__init__(self, node=node, name=name, mtu=mtu) self.session = session if objid is None: # from PyCoreObj objid = ((id(self) >> 16) ^ (id(self) & 0xffff)) & 0xffff self.objid = objid sessionid = self.session.short_session_id() # interface name on the local host machine self.localname = "gt.%s.%s" % (self.objid, sessionid) self.transport_type = "raw" if not start: self.up = False return 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.up = True
def addrconfig(self, addresses): """ Set addresses on the bridge. """ if not self.up: return for address in addresses: utils.check_cmd([constants.IP_BIN, "addr", "add", str(address), "dev", self.bridge_name])
def attach(self, interface): if self.up: utils.check_cmd([ constants.OVS_BIN, "add-port", self.bridge_name, interface.localname ]) utils.check_cmd( [constants.IP_BIN, "link", "set", interface.localname, "up"]) PyCoreNet.attach(self, interface)
def startup(self): """ Set the interface in the up state. :return: nothing :raises CoreCommandError: when there is a command exception """ # interface will also be marked up during net.attach() self.savestate() utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"]) self.up = True
def __init__(self, session, objid=None, name=None, start=True): """ the Hub node forwards packets to all bridge ports by turning off the MAC address learning """ OvsNet.__init__(self, session, objid, name, start) if start: # TODO: verify that the below flow accomplishes what is desired for a "HUB" # TODO: replace "brctl setageing 0" utils.check_cmd([constants.OVS_FLOW_BIN, "add-flow", self.bridge_name, "action=flood"])
def startup(self): """ Interface startup logic. :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.up = True
def linknet(self, network): """ Link this bridge with another by creating a veth pair and installing each device into each bridge. """ session_id = self.session.short_session_id() try: self_objid = "%x" % self.objid except TypeError: self_objid = "%s" % self.objid try: net_objid = "%x" % network.objid except TypeError: net_objid = "%s" % network.objid localname = "veth%s.%s.%s" % (self_objid, net_objid, session_id) if len(localname) >= 16: raise ValueError("interface local name %s too long" % localname) name = "veth%s.%s.%s" % (net_objid, self_objid, session_id) if len(name) >= 16: raise ValueError("interface name %s too long" % name) interface = VEth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up) self.attach(interface) if network.up: # this is similar to net.attach() but uses netif.name instead # of localname utils.check_cmd([ constants.OVS_BIN, "add-port", network.bridge_name, interface.name ]) utils.check_cmd( [constants.IP_BIN, "link", "set", interface.name, "up"]) # TODO: is there a native method for this? see if this causes issues # i = network.newifindex() # network._netif[i] = interface # with network._linked_lock: # network._linked[interface] = {} # this method call is equal to the above, with a interface.netifi = call network.attach(interface) interface.net = self interface.othernet = network return interface
def detach(self, netif): """ Detach a network interface. :param core.netns.vif.Veth netif: network interface to detach :return: nothing """ if self.up: utils.check_cmd([constants.BRCTL_BIN, "delif", self.brname, netif.localname]) PyCoreNet.detach(self, netif)
def addrconfig(self, addrlist): """ Set addresses on the bridge. :param list[str] addrlist: address list :return: nothing """ if not self.up: return for addr in addrlist: utils.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.brname])
def attach(self, netif): """ Attach a network interface. :param core.netns.vnode.VEth netif: network interface to attach :return: nothing """ if self.up: utils.check_cmd([constants.BRCTL_BIN, "addif", self.brname, netif.localname]) utils.check_cmd([constants.IP_BIN, "link", "set", netif.localname, "up"]) PyCoreNet.attach(self, netif)
def deladdr(self, addr): """ Delete address from network interface. :param str addr: address to delete :return: nothing :raises CoreCommandError: when there is a command exception """ if self.up: utils.check_cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.name]) PyCoreNetIf.deladdr(self, addr)
def startup(self): """ Linux bridge starup logic. :return: nothing :raises CoreCommandError: when there is a command exception """ utils.check_cmd([constants.BRCTL_BIN, "addbr", self.brname]) # turn off spanning tree protocol and forwarding delay utils.check_cmd([constants.BRCTL_BIN, "stp", self.brname, "off"]) utils.check_cmd([constants.BRCTL_BIN, "setfd", self.brname, "0"]) utils.check_cmd([constants.IP_BIN, "link", "set", self.brname, "up"]) # create a new ebtables chain for this bridge ebtablescmds(utils.check_cmd, [ [constants.EBTABLES_BIN, "-N", self.brname, "-P", self.policy], [constants.EBTABLES_BIN, "-A", "FORWARD", "--logical-in", self.brname, "-j", self.brname] ]) # turn off multicast snooping so mcast forwarding occurs w/o IGMP joins snoop = "/sys/devices/virtual/net/%s/bridge/multicast_snooping" % self.brname if os.path.exists(snoop): with open(snoop, "w") as snoop_file: snoop_file.write("0") self.up = True
def startup(self): """ Linux bridge starup logic. :return: nothing :raises CoreCommandError: when there is a command exception """ utils.check_cmd([constants.BRCTL_BIN, "addbr", self.brname]) # turn off spanning tree protocol and forwarding delay utils.check_cmd([constants.BRCTL_BIN, "stp", self.brname, "off"]) utils.check_cmd([constants.BRCTL_BIN, "setfd", self.brname, "0"]) utils.check_cmd([constants.IP_BIN, "link", "set", self.brname, "up"]) # create a new ebtables chain for this bridge ebtablescmds( utils.check_cmd, [[constants.EBTABLES_BIN, "-N", self.brname, "-P", self.policy], [ constants.EBTABLES_BIN, "-A", "FORWARD", "--logical-in", self.brname, "-j", self.brname ]]) # turn off multicast snooping so mcast forwarding occurs w/o IGMP joins snoop = "/sys/devices/virtual/net/%s/bridge/multicast_snooping" % self.brname if os.path.exists(snoop): with open(snoop, "w") as snoop_file: snoop_file.write("0") self.up = True
def linknet(self, net): """ Link this bridge with another by creating a veth pair and installing each device into each bridge. :param core.netns.vnet.LxBrNet net: network to link with :return: created interface :rtype: Veth """ sessionid = self.session.short_session_id() try: self_objid = "%x" % self.objid except TypeError: self_objid = "%s" % self.objid try: net_objid = "%x" % net.objid except TypeError: net_objid = "%s" % net.objid localname = "veth%s.%s.%s" % (self_objid, net_objid, sessionid) if len(localname) >= 16: raise ValueError("interface local name %s too long" % localname) name = "veth%s.%s.%s" % (net_objid, self_objid, sessionid) if len(name) >= 16: raise ValueError("interface name %s too long" % name) netif = VEth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up) self.attach(netif) if net.up: # this is similar to net.attach() but uses netif.name instead # of localname utils.check_cmd( [constants.BRCTL_BIN, "addif", net.brname, netif.name]) utils.check_cmd( [constants.IP_BIN, "link", "set", netif.name, "up"]) i = net.newifindex() net._netif[i] = netif with net._linked_lock: net._linked[netif] = {} netif.net = self netif.othernet = net return netif
def __init__(self, session, objid=None, name=None, start=True): """ Creates a HubNode instance. :param core.session.Session session: core session instance :param int objid: node id :param str name: node namee :param bool start: start flag :raises CoreCommandError: when there is a command exception """ LxBrNet.__init__(self, session, objid, name, start) # TODO: move to startup method if start: utils.check_cmd([constants.BRCTL_BIN, "setageing", self.brname, "0"])
def install(self): """ Install this TAP into its namespace. This is not done from the startup() method but called at a later time when a userspace program (running on the host) has had a chance to open the socket end of the TAP. :return: nothing :raises CoreCommandError: when there is a command exception """ self.waitfordevicelocal() netns = str(self.node.pid) utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "netns", netns]) self.node.check_cmd([constants.IP_BIN, "link", "set", self.localname, "name", self.name]) self.node.check_cmd([constants.IP_BIN, "link", "set", self.name, "up"])
def shutdown(self): if self.serverintf: try: utils.check_cmd([constants.OVS_BIN, "del-port", self.bridge_name, self.serverintf]) except CoreCommandError: logger.exception("error deleting server interface %s to controlnet bridge %s", self.serverintf, self.bridge_name) if self.updown_script: try: logger.info("interface %s updown script (%s shutdown) called", self.bridge_name, self.updown_script) utils.check_cmd([self.updown_script, self.bridge_name, "shutdown"]) except CoreCommandError: logger.exception("error during updown script shutdown") OvsNet.shutdown(self)
def shutdown(self): """ Shutdown logic for a GreTap. :return: nothing """ if self.localname: try: args = ["ip", "link", "set", self.localname, "down"] utils.check_cmd(args) args = ["ip", "link", "del", self.localname] utils.check_cmd(args) except CoreCommandError: logger.exception("error during shutdown") self.localname = None
def savestate(self): """ Save the addresses and other interface state before using the interface for emulation purposes. TODO: save/restore the PROMISC flag :return: nothing :raises CoreCommandError: when there is a command exception """ self.old_up = False self.old_addrs = [] args = [constants.IP_BIN, "addr", "show", "dev", self.localname] output = utils.check_cmd(args) for line in output.split("\n"): items = line.split() if len(items) < 2: continue if items[1] == "%s:" % self.localname: flags = items[2][1:-1].split(",") if "UP" in flags: self.old_up = True elif items[0] == "inet": self.old_addrs.append((items[1], items[3])) elif items[0] == "inet6": if items[1][:4] == "fe80": continue self.old_addrs.append((items[1], None))
def linknet(self, network): """ Link this bridge with another by creating a veth pair and installing each device into each bridge. """ session_id = self.session.short_session_id() try: self_objid = "%x" % self.objid except TypeError: self_objid = "%s" % self.objid try: net_objid = "%x" % network.objid except TypeError: net_objid = "%s" % network.objid localname = "veth%s.%s.%s" % (self_objid, net_objid, session_id) if len(localname) >= 16: raise ValueError("interface local name %s too long" % localname) name = "veth%s.%s.%s" % (net_objid, self_objid, session_id) if len(name) >= 16: raise ValueError("interface name %s too long" % name) interface = VEth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up) self.attach(interface) if network.up: # this is similar to net.attach() but uses netif.name instead # of localname utils.check_cmd([constants.OVS_BIN, "add-port", network.bridge_name, interface.name]) utils.check_cmd([constants.IP_BIN, "link", "set", interface.name, "up"]) # TODO: is there a native method for this? see if this causes issues # i = network.newifindex() # network._netif[i] = interface # with network._linked_lock: # network._linked[interface] = {} # this method call is equal to the above, with a interface.netifi = call network.attach(interface) interface.net = self interface.othernet = network return interface
def post_startup(self): """ Logic to execute after the emane manager is finished with startup. :return: nothing """ # get configured schedule config = self.session.emane.get_configs(node_id=self.object_id, config_type=self.name) if not config: return schedule = config[self.schedule_name] # get the set event device event_device = self.session.emane.event_device # initiate tdma schedule logger.info("setting up tdma schedule: schedule(%s) device(%s)", schedule, event_device) utils.check_cmd(["emaneevent-tdmaschedule", "-i", event_device, schedule])
def test_net(self, session, net_type): # given # when node = session.add_node(_type=net_type) # then assert node assert node.up assert utils.check_cmd(["brctl", "show", node.brname])
def statescript(self, typestr): """ State of the mobility script. :param str typestr: state type string :return: nothing """ filename = None if typestr == "run" or typestr == "unpause": filename = self.script_start elif typestr == "pause": filename = self.script_pause elif typestr == "stop": filename = self.script_stop if filename is None or filename == '': return filename = self.findfile(filename) args = ["/bin/sh", filename, typestr] utils.check_cmd(args, cwd=self.session.session_dir, env=self.session.get_environment())
def linknet(self, net): """ Link this bridge with another by creating a veth pair and installing each device into each bridge. :param core.netns.vnet.LxBrNet net: network to link with :return: created interface :rtype: Veth """ sessionid = self.session.short_session_id() try: self_objid = "%x" % self.objid except TypeError: self_objid = "%s" % self.objid try: net_objid = "%x" % net.objid except TypeError: net_objid = "%s" % net.objid localname = "veth%s.%s.%s" % (self_objid, net_objid, sessionid) if len(localname) >= 16: raise ValueError("interface local name %s too long" % localname) name = "veth%s.%s.%s" % (net_objid, self_objid, sessionid) if len(name) >= 16: raise ValueError("interface name %s too long" % name) netif = VEth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up) self.attach(netif) if net.up: # this is similar to net.attach() but uses netif.name instead # of localname utils.check_cmd([constants.BRCTL_BIN, "addif", net.brname, netif.name]) utils.check_cmd([constants.IP_BIN, "link", "set", netif.name, "up"]) i = net.newifindex() net._netif[i] = netif with net._linked_lock: net._linked[netif] = {} netif.net = self netif.othernet = net return netif
def startup(self): """ :return: :raises CoreCommandError: when there is a command exception """ utils.check_cmd([constants.OVS_BIN, "add-br", self.bridge_name]) # turn off spanning tree protocol and forwarding delay # TODO: appears stp and rstp are off by default, make sure this always holds true # TODO: apears ovs only supports rstp forward delay and again it's off by default utils.check_cmd([constants.IP_BIN, "link", "set", self.bridge_name, "up"]) # create a new ebtables chain for this bridge ebtables_commands(utils.check_cmd, [ [constants.EBTABLES_BIN, "-N", self.bridge_name, "-P", self.policy], [constants.EBTABLES_BIN, "-A", "FORWARD", "--logical-in", self.bridge_name, "-j", self.bridge_name] ]) self.up = True
def shutdown(self): """ Control network shutdown. :return: nothing """ if self.serverintf is not None: try: utils.check_cmd([constants.BRCTL_BIN, "delif", self.brname, self.serverintf]) except CoreCommandError: logger.exception("error deleting server interface %s from bridge %s", self.serverintf, self.brname) if self.updown_script is not None: try: logger.info("interface %s updown script (%s shutdown) called", self.brname, self.updown_script) utils.check_cmd([self.updown_script, self.brname, "shutdown"]) except CoreCommandError: logger.exception("error issuing shutdown script shutdown") LxBrNet.shutdown(self)
def post_startup(self, emane_manager): """ Logic to execute after the emane manager is finished with startup. :param core.emane.emanemanager.EmaneManager emane_manager: emane manager for the session :return: nothing """ # get configured schedule values = emane_manager.getconfig(self.object_id, self.name, self.getdefaultvalues())[1] if values is None: return schedule = self.valueof(self.schedule_name, values) event_device = emane_manager.event_device # initiate tdma schedule logger.info("setting up tdma schedule: schedule(%s) device(%s)", schedule, event_device) utils.check_cmd( ["emaneevent-tdmaschedule", "-i", event_device, schedule])
def startup(self): """ Startup functionality for the control network. :return: nothing :raises CoreCommandError: when there is a command exception """ if self.detectoldbridge(): return LxBrNet.startup(self) if self.hostid: addr = self.prefix.addr(self.hostid) else: addr = self.prefix.max_addr() logger.info("added control network bridge: %s %s", self.brname, self.prefix) if self.assign_address: addrlist = ["%s/%s" % (addr, self.prefix.prefixlen)] self.addrconfig(addrlist=addrlist) logger.info("address %s", addr) if self.updown_script: logger.info("interface %s updown script (%s startup) called", self.brname, self.updown_script) utils.check_cmd([self.updown_script, self.brname, "startup"]) if self.serverintf: # sets the interface as a port of the bridge utils.check_cmd([constants.BRCTL_BIN, "addif", self.brname, self.serverintf]) # bring interface up utils.check_cmd([constants.IP_BIN, "link", "set", self.serverintf, "up"])
def stopdaemons(self): """ Kill the appropriate EMANE daemons. """ # TODO: we may want to improve this if we had the PIDs from the specific EMANE daemons that we"ve started args = ["killall", "-q", "emane"] stop_emane_on_host = False for node in self.getnodes(): if hasattr(node, "transport_type") and node.transport_type == "raw": stop_emane_on_host = True continue if node.up: node.cmd(args, wait=False) # TODO: RJ45 node if stop_emane_on_host: try: utils.check_cmd(args) utils.check_cmd(["killall", "-q", "emanetransportd"]) except CoreCommandError: logger.exception("error shutting down emane daemons")
def get_ipv4_addresses(hostname): if hostname == 'localhost': addr_list = [] args = [constants.IP_BIN, '-o', '-f', 'inet', 'addr', 'show'] output = utils.check_cmd(args) for line in output.split(os.linesep): split = line.split() if not split: continue addr = split[3] if not addr.startswith('127.'): addr_list.append(addr) return addr_list else: # TODO: handle other hosts raise NotImplementedError
def detectoldbridge(self): """ Occasionally, control net bridges from previously closed sessions are not cleaned up. Check if there are old control net bridges and delete them """ output = utils.check_cmd([constants.OVS_BIN, "list-br"]) output = output.strip() if output: for line in output.split("\n"): bride_name = line.split(".") if bride_name[0] == "b" and bride_name[1] == self.objid: logger.error("older session may still be running with conflicting id for bridge: %s", line) return True return False
def get_ipv4_addresses(hostname): if hostname == "localhost": addresses = [] args = [constants.IP_BIN, "-o", "-f", "inet", "addr", "show"] output = utils.check_cmd(args) for line in output.split(os.linesep): split = line.split() if not split: continue interface_name = split[1] address = split[3] if not address.startswith("127."): addresses.append((interface_name, address)) return addresses else: # TODO: handle other hosts raise NotImplementedError
def restorestate(self): """ Restore the addresses and other interface state after using it. :return: nothing :raises CoreCommandError: when there is a command exception """ for addr in self.old_addrs: if addr[1] is None: utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "dev", self.localname]) else: utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "brd", addr[1], "dev", self.localname]) if self.old_up: utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
def startup(self): """ Start a new namespace node by invoking the vnoded process that allocates a new namespace. Bring up the loopback device and set the hostname. :return: nothing """ if self.up: raise ValueError("starting a node that is already up") # create a new namespace for this node using vnoded vnoded = [ constants.VNODED_BIN, "-v", "-c", self.ctrlchnlname, "-l", self.ctrlchnlname + ".log", "-p", self.ctrlchnlname + ".pid" ] if self.nodedir: vnoded += ["-C", self.nodedir] env = self.session.get_environment(state=False) env["NODE_NUMBER"] = str(self.objid) env["NODE_NAME"] = str(self.name) output = utils.check_cmd(vnoded, env=env) self.pid = int(output) # create vnode client self.client = vnodeclient.VnodeClient(self.name, self.ctrlchnlname) # bring up the loopback interface logger.debug("bringing up loopback interface") self.check_cmd([constants.IP_BIN, "link", "set", "lo", "up"]) # set hostname for node logger.debug("setting hostname: %s", self.name) self.check_cmd(["hostname", self.name]) # mark node as up self.up = True
def emane_check(self): """ Check if emane is installed and load models. :return: nothing """ try: # check for emane emane_version = utils.check_cmd(["emane", "--version"]) logger.info("using EMANE: %s", emane_version) # load default emane models self.load_models(EMANE_MODELS) # load custom models custom_models_path = self.session.options.get_config("emane_models_dir") if custom_models_path: emane_models = utils.load_classes(custom_models_path, EmaneModel) self.load_models(emane_models) except CoreCommandError: logger.info("emane is not installed")