def handlenodemsg(self, msg): ''' Determine and return the servers to which this node message should be forwarded. Also keep track of link-layer nodes and the mapping of nodes to servers. ''' serverlist = [] handle_locally = False serverfiletxt = None # snoop Node Message for emulation server TLV and record mapping n = msg.tlvdata[coreapi.CORE_TLV_NODE_NUMBER] # replicate link-layer nodes on all servers nodetype = msg.gettlv(coreapi.CORE_TLV_NODE_TYPE) if nodetype is not None: try: nodecls = coreapi.node_class(nodetype) except KeyError: self.session.warn("broker invalid node type %s" % nodetype) return (False, serverlist) if nodecls is None: self.session.warn("broker unimplemented node type %s" % nodetype) return (False, serverlist) if issubclass(nodecls, PyCoreNet) and \ nodetype != coreapi.CORE_NODE_WLAN: # network node replicated on all servers; could be optimized # don't replicate WLANs, because ebtables rules won't work serverlist = self.getserverlist() handle_locally = True self.addnet(n) for server in serverlist: self.addnodemap(server, n) # do not record server name for networks since network # nodes are replicated across all server return (handle_locally, serverlist) if issubclass(nodecls, PyCoreNet) and \ nodetype == coreapi.CORE_NODE_WLAN: # special case where remote WLANs not in session._objs, and no # node response message received, so they are counted here if msg.gettlv(coreapi.CORE_TLV_NODE_EMUSRV) is not None: self.incrbootcount() elif issubclass(nodecls, PyCoreNode): name = msg.gettlv(coreapi.CORE_TLV_NODE_NAME) if name: serverfiletxt = "%s %s %s" % (n, name, nodecls) if issubclass(nodecls, PhysicalNode): # remember physical nodes self.addphys(n) # emulation server TLV specifies server server = msg.gettlv(coreapi.CORE_TLV_NODE_EMUSRV) if server is not None: self.addnodemap(server, n) if server not in serverlist: serverlist.append(server) if serverfiletxt and self.session.master: self.writenodeserver(serverfiletxt, server) # hook to update coordinates of physical nodes if n in self.phys: self.session.mobility.physnodeupdateposition(msg) return (handle_locally, serverlist)
def handlenodemsg(self, msg): ''' Process a Node Message to add/delete or move a node on the SDT display. Node properties are found in session._objs or self.remotes for remote nodes (or those not yet instantiated). ''' # for distributed sessions to work properly, the SDT option should be # enabled prior to starting the session if not self.is_enabled(): return False # node.(objid, type, icon, name) are used. nodenum = msg.gettlv(coreapi.CORE_TLV_NODE_NUMBER) if not nodenum: return x = msg.gettlv(coreapi.CORE_TLV_NODE_XPOS) y = msg.gettlv(coreapi.CORE_TLV_NODE_YPOS) z = None name = msg.gettlv(coreapi.CORE_TLV_NODE_NAME) nodetype = msg.gettlv(coreapi.CORE_TLV_NODE_TYPE) model = msg.gettlv(coreapi.CORE_TLV_NODE_MODEL) icon = msg.gettlv(coreapi.CORE_TLV_NODE_ICON) net = False if nodetype == coreapi.CORE_NODE_DEF or \ nodetype == coreapi.CORE_NODE_PHYS or \ nodetype == coreapi.CORE_NODE_XEN: if model is None: model = "router" type = model elif nodetype != None: type = coreapi.node_class(nodetype).type net = True else: type = None try: node = self.session.obj(nodenum) except KeyError: node = None if node: self.updatenode(node.objid, msg.flags, x, y, z, node.name, node.type, node.icon) else: if nodenum in self.remotes: remote = self.remotes[nodenum] if name is None: name = remote.name if type is None: type = remote.type if icon is None: icon = remote.icon else: remote = self.Bunch(objid=nodenum, type=type, icon=icon, name=name, net=net, links=set()) self.remotes[nodenum] = remote remote.pos = (x, y, z) self.updatenode(nodenum, msg.flags, x, y, z, name, type, icon)