def __init__(self, timeToWake, callback, absoluteTime=False, recurring=False, args=(), kw={}, scheduler=None, started=True, selfStoppable=True): if absoluteTime and recurring: raise RuntimeError( "Can't have a recurring timer for an absolute time!") if absoluteTime: raise RuntimeError("Can't have an absolute time in FakePoxTimer") self._self_stoppable = selfStoppable self._timeToWake = timeToWake self.id = "poxtimer{}".format(FakePoxTimer.timerid) FakePoxTimer.timerid += 1 self._recurring = recurring self._callback = callback self._args = args self._kw = kw get_logger().debug("Setting fake pox timer callback {} {}".format( self._timeToWake, self._callback)) fscore().after(self._timeToWake, self.id, self.docallback, None)
def __configure_edge_reliability(self, a, b, relistr, edict): relidict = fsutil.mkdict(relistr) ttf = ttr = None for k, v in relidict.iteritems(): if k == 'failureafter': ttf = eval(v) if isinstance(ttf, (int, float)): ttf = modulation_generator([ttf]) elif k == 'downfor': ttr = eval(v) if isinstance(ttr, (int, float)): ttr = modulation_generator([ttr]) elif k == 'mttf': ttf = eval(v) elif k == 'mttr': ttr = eval(v) if ttf or ttr: assert (ttf and ttr) xttf = next(ttf) fscore().after(xttf, 'link-failure-' + a + '-' + b, self.__linkdown, a, b, edict, ttf, ttr)
def start(self): '''Load POX controller components''' Node.start(self) # remove self from networkx graph (topology) fscore().topology.remove_node(self.name) for component in self.components: self.logger.debug("Starting OF Controller Component {}".format(component)) load_pox_component(component)
def controller_to_switch(self, switchname, mesg): '''Ferry an OF message from controller to switch''' if not self.started: # self.logger.debug("OF controller-to-switch deferred message {}".format(mesg)) evid = 'deferred controller->switch send' fscore().after(0, evid, self.controller_to_switch, switchname, mesg) else: # self.logger.debug("OF controller-to-switch {}->{}: {}".format(self.name, switchname, mesg)) link = self.switch_links[switchname][1] link.flowlet_arrival(OpenflowMessage(FlowIdent(), mesg), self.name, switchname)
def callback(self): # pass oneself from srcnode to dstnode, performing action at each router # at end, set done to True f = SubtractiveFlowlet(FlowIdent(self.ipsrcfilt, self.ipdstfilt, ipproto=self.ipprotofilt), action=self.action) self.logger.info('Subtractive generator callback') fscore().topology.node(self.srcnode).flowlet_arrival( f, 'subtractor', self.dstnode)
def update_table(self, ofmessage): # print ofmessage.message.pox_ofp_message.actions rv = self.flow_table.process_flow_mod(ofmessage.message.pox_ofp_message) # JS: because of limitation in being able to explicitly set current timestamp # through process_flow_mod (it doesn't correctly return the new table entry created), # find matches in the table (which should be exactly what we just added), and explicitly # set created and last_touched timestamps to "now" in simulation time. for m in self.flow_table.matching_entries(ofmessage.message.pox_ofp_message.match): m.counters["created"] = fscore().now m.counters["last_touched"] = fscore().now return rv
def send(self, ofmessage): '''Callback function for POX SoftwareSwitch to send an outgoing OF message to controller.''' if not self.started: # self.logger.debug("OF switch-to-controller deferred message {}".format(ofmessage)) evid = 'deferred switch->controller send' fscore().after(0.0, evid, self.send, ofmessage) else: # self.logger.debug("OF switch-to-controller {} - {}".format(str(self.controller_links[self.controller_name]), ofmessage)) clink = self.controller_links[self.controller_name] self.controller_links[self.controller_name].flowlet_arrival(OpenflowMessage(FlowIdent(), ofmessage), self.name, self.controller_name)
def table_ager(self): entries = self.flow_table.remove_expired_entries(fscore().now) # print "in table ager, evicting {} entries.".format(len(entries)) for entry in entries: msg = OpenflowMessage(flowident_from_ofp_match(entry.match), 'ofp_flow_removed', match=entry.match, cookie=entry.cookie, priority=entry.priority, reason=0, duration_sec=0, duration_nsec=0, idle_timeout=entry.idle_timeout, packet_count=entry.counters['packets'], byte_count=entry.counters['bytes']) # FIXME: controller name is hard-coded. need a general way to identify # the link to/name of the controller node self.forward(self.controller, msg, self.controller) fscore().after(1, "openflow-switch-table-ager"+str(self.name), self.table_ager) return len(entries)
def controller_to_switch(self, switchname, mesg): """Ferry an OF message from controller proxy to switch""" if not self.started: # self.logger.info("OF controller-to-switch deferred message {}".format(mesg)) evid = "deferred controller->switch send" fscore().after(0, evid, self.controller_to_switch, switchname, mesg) else: # self.logger.info("OF controller-to-switch {}->{}: {}".format(self.name, switchname, mesg)) # print("OF controller-to-switch {}->{}: {}".format(self.name, switchname, mesg)) link = self.switch_links[switchname][1] # print "seq 1" link.flowlet_arrival(OpenflowMessage(FlowIdent(), mesg), self.name, switchname)
def update_table(self, ofmessage): # print ofmessage.message.pox_ofp_message.actions rv = self.flow_table.process_flow_mod( ofmessage.message.pox_ofp_message) # JS: because of limitation in being able to explicitly set current timestamp # through process_flow_mod (it doesn't correctly return the new table entry created), # find matches in the table (which should be exactly what we just added), and explicitly # set created and last_touched timestamps to "now" in simulation time. for m in self.flow_table.matching_entries( ofmessage.message.pox_ofp_message.match): m.counters['created'] = fscore().now m.counters['last_touched'] = fscore().now return rv
def withdraw_phase(self): self.reap_generators() nexttime,sources = 0,0 try: nexttime,sources = next(self.withdraw) except: self.logger.info('finished with withdraw phase') fscore().after(0, 'modulator: kill_all', self.kill_all_generator) else: assert(sources>=0) self.__modulate(sources) self.logger.info('withdraw: %f %d' % (nexttime,sources)) fscore().after(nexttime, 'modulator: withdraw', self.withdraw_phase)
def sustain_phase(self): self.reap_generators() nexttime,sources = 0,0 try: nexttime,sources = next(self.sustain) except: self.logger.info('scheduling transition from sustain to withdraw') fscore().after(0.0, 'modulator transition: sustain->withdraw', self.withdraw_phase) else: assert(sources>=0) self.__modulate(sources) self.logger.info('sustain: %f %d' % (nexttime,sources)) fscore().after(nexttime, 'modulator: sustain', self.sustain_phase)
def emerge_phase(self): self.reap_generators() nexttime,sources = 0,0 try: nexttime,sources = next(self.emerge) except: self.logger.info('scheduling transition from emerge to sustain') fscore().after(0.0, 'modulator transition: emerge->sustain', self.sustain_phase) else: assert(sources>=0) self.__modulate(sources) self.logger.info('emerge: %f %d' % (nexttime,sources)) fscore().after(nexttime, 'modulator: emerge', self.emerge_phase)
def __linkdown(self, a, b, edict, ttf, ttr): '''kill a link & recompute routing ''' self.logger.info('Link failed %s - %s' % (a,b)) self.graph.remove_edge(a,b) self.__configure_routing() uptime = None try: uptime = next(ttr) except: self.logger.info('Link %s-%s permanently taken down (no recovery time remains in generator)' % (a, b)) return else: fscore().after(uptime, 'link-recovery-'+a+'-'+b, self.__linkup, a, b, edict, ttf, ttr)
def __linkup(self, a, b, edict, ttf, ttr): '''revive a link & recompute routing ''' self.logger.info('Link recovered %s - %s' % (a,b)) self.graph.add_edge(a,b,weight=edict.get('weight',1),delay=edict.get('delay',0),capacity=edict.get('capacity',1000000)) self.__configure_routing() downtime = None try: downtime = next(ttf) except: self.logger.info('Link %s-%s permanently going into service (no failure time remains in generator)' % (a, b)) return else: fscore().after(downtime, 'link-failure-'+a+'-'+b, self.__linkdown, a, b, edict, ttf, ttr)
def send_ack_flow(self, flowlet, input_intf): # print "constructing ack flow:", self.name, flowlet, prevnode, destnode, input_intf revident = flowlet.ident.mkreverse() revflet = Flowlet(revident) revflet.srcmac,revflet.dstmac = flowlet.dstmac,flowlet.srcmac revflet.ackflow = True revflet.pkts = flowlet.pkts/2 revflet.bytes = revflet.pkts * 40 revflet.iptos = flowlet.iptos revflet.tcpflags = flowlet.tcpflags revflet.ingress_intf = input_intf revflet.flowstart = fscore().now revflet.flowend = revflet.flowstart destnode = fscore().topology.destnode(self.name, revflet.dstaddr) # self.logger.debug("Injecting reverse flow: {}->{}".format(revflet.srcmac, revflet.dstmac)) self.flowlet_arrival(revflet, self.name, destnode)
def apply_actions(self, flowlet, actions): nh = None # FIXME: actions don't actually do anything (yet); just enqueue/output are implemented actionmap = { type(ofp_action_strip_vlan()): lambda f: None, type(ofp_action_vlan_vid()): lambda f: None, # .vlan_vid type(ofp_action_vlan_pcp()): lambda f: None, # .vlan_pcp type(ofp_action_dl_addr()): lambda f: None, # .type OFPAT_SET_DL_SRC/DST, .dl_addr type(ofp_action_nw_addr()): lambda f: None, # .type OFPAT_SET_NW_SRC/DST, .nw_addr type(ofp_action_nw_tos()): lambda f: None, # .nw_tos type(ofp_action_tp_port()): lambda f: None, # .type OFPAT_SET_TP_SRC/DST, .tp_addr type(ofp_action_output()): lambda f: None, } for act in actions: if isinstance(act, ofp_action_enqueue) or isinstance(act, ofp_action_output): if act.port == 65532 or act.port == 65531: # output port OFPP_FLOOD nh = [] for node in fscore().graph.node.keys(): if node != self.name and node != "controller": nh.append(node) return nh else: nh = act.port # also .queue_id for enqueue action else: # apply ofp actions nh = actionmap[type(act)](flowlet) return nh
def apply_actions(self, flowlet, actions): nh = None # FIXME: actions don't actually do anything (yet); just enqueue/output are implemented actionmap = { type(ofp_action_strip_vlan()): lambda f: None, type(ofp_action_vlan_vid()): lambda f: None, # .vlan_vid type(ofp_action_vlan_pcp()): lambda f: None, # .vlan_pcp type(ofp_action_dl_addr()): lambda f: None, # .type OFPAT_SET_DL_SRC/DST, .dl_addr type(ofp_action_nw_addr()): lambda f: None, # .type OFPAT_SET_NW_SRC/DST, .nw_addr type(ofp_action_nw_tos()): lambda f: None, # .nw_tos type(ofp_action_tp_port()): lambda f: None, # .type OFPAT_SET_TP_SRC/DST, .tp_addr type(ofp_action_output()): lambda f: None, } for act in actions: if isinstance(act, ofp_action_enqueue) or isinstance( act, ofp_action_output): if act.port == 65532 or act.port == 65531: # output port OFPP_FLOOD nh = [] for node in fscore().graph.node.keys(): if node != self.name and node != 'controller': nh.append(node) return nh else: nh = act.port # also .queue_id for enqueue action else: # apply ofp actions nh = actionmap[type(act)](flowlet) return nh
def flowemit(self, flowlet, destnode, xinterval, ticks): assert(xinterval > 0.0) f = copy.copy(flowlet) f.bytes = next(self.bytes) if self.pktsize: psize = next(self.pktsize) f.pkts = f.bytes / psize if f.bytes % psize > 0: f.pkts += 1 else: f.pkts = next(self.pkts) fscore().topology.node(self.srcnode).flowlet_arrival(f, 'simple', destnode) ticks -= 1 fscore().after(xinterval, 'rawflow-flowemit-'+str(self.srcnode), self.flowemit, flowlet, destnode, xinterval, ticks)
def match_table(self, flowlet, prevnode): # delegate to POX flowtable entry = self.flow_table.entry_for_packet(flowlet, prevnode) if not entry: return None entry.touch_packet(flowlet.bytes, now=fscore().now) nh = self.apply_actions(flowlet, entry.actions) return nh
def handlePacketIn(self, flet, prevnode): if not self.graph: self.graph = deepcopy(fscore().topology.graph) self.graph.remove_node(self.node.name) # FIXME: ignores weights! self.shortest_paths = networkx.shortest_path(self.graph) origin, dest, prev = flet.get_context() destnode = fscore().topology.destnode(origin, flet.dstaddr) path = self.shortest_paths[origin][dest] nh = path[1] # self.logger.info("ShortestPath received: {} from: {} prev: {} dest: {} path: {} nexthop: {}".format(str(flet), origin, prev, dest, str(path), nh)) match = ofp_match_from_flowlet(flet) ofm = OpenflowMessage(flet.flowident, "ofp_flow_mod", match=match, idle_timeout=60, action=nh) ofm.data = flet return ofm
def __makeflow(self): if haveIPAddrGen: srcip = str(IPv4Address(ipaddrgen.generate_addressv4(self.ipsrcgen))) dstip = str(IPv4Address(ipaddrgen.generate_addressv4(self.ipdstgen))) else: srcip = str(IPAddress(int(self.ipsrc) + random.randint(0,self.ipsrc.numhosts-1))) dstip = str(IPAddress(int(self.ipdst) + random.randint(0,self.ipdst.numhosts-1))) ipproto = self.ipproto sport = dport = 0 if ipproto == IPPROTO_ICMP: # std way that netflow encodes icmp type/code: # type in high-order byte of dport, # code in low-order byte t = next(self.icmptype) c = next(self.icmpcode) dport = t << 8 | c # print 'icmp t,c,dport',hex(t),hex(c),hex(dport) else: if self.sport: sport = next(self.sport) if self.dport: dport = next(self.dport) flet = Flowlet(FlowIdent(srcip, dstip, ipproto, sport, dport)) flet.iptos = next(self.iptos) flet.flowstart = flet.flowend = fscore().now if flet.ipproto == IPPROTO_TCP: flet.ackflow = not self.autoack tcpflags = next(self.tcpflags) flaglist = tcpflags.split('|') xtcpflags = 0x0 for f in flaglist: if f == 'FIN': xtcpflags |= 0x01 elif f == 'SYN': xtcpflags |= 0x02 elif f == 'RST': xtcpflags |= 0x04 elif f == 'PUSH' or f == 'PSH': xtcpflags |= 0x08 elif f == 'ACK': xtcpflags |= 0x10 elif f == 'URG': xtcpflags |= 0x20 elif f == 'ECE': xtcpflags |= 0x40 elif f == 'CWR': xtcpflags |= 0x80 else: raise InvalidFlowConfiguration('Invalid TCP flags mnemonic ' + f) flet.tcpflags = xtcpflags return flet
def start(self): """Load POX controller components""" Node.start(self) # remove self from networkx graph (topology) fscore().topology.remove_node(self.name) # FIXME: Check the type of controller and patch based on that... # Eventhought it works for pox, it will be difficult for ODL if self.conType == "POX" or self.conType == "RYU": self.logger.info("Patching {} integration with fs".format(self.conType)) for component in self.components: self.logger.debug("Starting OF Controller Component {}".format(component)) load_pox_component(component) elif self.conType == "ODL": self.logger.info("Patching ODL integration with fs") for component in self.components: self.logger.debug("Starting OF Controller Component {}".format(component)) load_odl_component(component) else: raise Exception("Other controller types not supported as of now.")
def flowlet_arrival(self, flowlet, prevnode, destnode): """ Handler for when a flowlet arrives on a link. Compute how long the flowlet should be delayed before arriving at next node, and optionally handle computing queueing delay (backlog) on the link. """ wait = self.delay + flowlet.size / self.capacity if self.doqdelay: queuedelay = max(0, (self.backlog - self.bdp) / self.capacity) wait += queuedelay self.backlog += flowlet.size if queuedelay > self.queuealarm and fscore().now - self.lastalarm > self.alarminterval: self.lastalarm = fscore().now self.logger.warn( "Excessive backlog on link {}-{}({:3.2f} sec ({} bytes))".format( self.ingress_name, self.egress_name, queuedelay, self.backlog ) ) fscore().after(wait, "link-decrbacklog-{}".format(self.egress_node.name), self.decrbacklog, flowlet.size) fscore().after( wait, "link-flowarrival-{}".format(self.egress_name, self.egress_ip), self.egress_node.flowlet_arrival, flowlet, prevnode, destnode, self.egress_ip, )
def flowlet_arrival(self, flowlet, prevnode, destnode): ''' Handler for when a flowlet arrives on a link. Compute how long the flowlet should be delayed before arriving at next node, and optionally handle computing queueing delay (backlog) on the link. ''' wait = self.delay + flowlet.size / self.capacity if self.doqdelay: queuedelay = max(0, (self.backlog - self.bdp) / self.capacity) wait += queuedelay self.backlog += flowlet.size if queuedelay > self.queuealarm and fscore( ).now - self.lastalarm > self.alarminterval: self.lastalarm = fscore().now self.logger.warn( "Excessive backlog on link {}-{}({:3.2f} sec ({} bytes))". format(self.ingress_name, self.egress_name, queuedelay, self.backlog)) fscore().after(wait, "link-decrbacklog-{}".format(self.egress_node.name), self.decrbacklog, flowlet.size) fscore().after( wait, "link-flowarrival-{}".format(self.egress_name, self.egress_ip), self.egress_node.flowlet_arrival, flowlet, prevnode, destnode, self.egress_ip)
def __init__ (self, timeToWake, callback, absoluteTime = False, recurring = False, args = (), kw = {}, scheduler = None, started = True, selfStoppable = True): if absoluteTime and recurring: raise RuntimeError("Can't have a recurring timer for an absolute time!") if absoluteTime: raise RuntimeError("Can't have an absolute time in FakePoxTimer") self._self_stoppable = selfStoppable self._timeToWake = timeToWake self.id = "poxtimer{}".format(FakePoxTimer.timerid) FakePoxTimer.timerid += 1 self._recurring = recurring self._callback = callback self._args = args self._kw = kw get_logger().debug("Setting fake pox timer callback {} {}".format(self._timeToWake, self._callback)) fscore().after(self._timeToWake, self.id, self.docallback, None)
def handlePacketIn(self, flet, prevnode): if not self.graph: self.graph = deepcopy(fscore().topology.graph) self.graph.remove_node(self.node.name) # FIXME: ignores weights! self.shortest_paths = networkx.shortest_path(self.graph) origin, dest, prev = flet.get_context() destnode = fscore().topology.destnode(origin, flet.dstaddr) path = self.shortest_paths[origin][dest] nh = path[1] # self.logger.info("ShortestPath received: {} from: {} prev: {} dest: {} path: {} nexthop: {}".format(str(flet), origin, prev, dest, str(path), nh)) match = ofp_match_from_flowlet(flet) ofm = OpenflowMessage(flet.flowident, 'ofp_flow_mod', match=match, idle_timeout=60, action=nh) ofm.data = flet return ofm
def table_ager(self): entries = self.flow_table.remove_expired_entries(fscore().now) # print "in table ager, evicting {} entries.".format(len(entries)) for entry in entries: msg = OpenflowMessage(flowident_from_ofp_match(entry.match), 'ofp_flow_removed', match=entry.match, cookie=entry.cookie, priority=entry.priority, reason=0, duration_sec=0, duration_nsec=0, idle_timeout=entry.idle_timeout, packet_count=entry.counters['packets'], byte_count=entry.counters['bytes']) # FIXME: controller name is hard-coded. need a general way to identify # the link to/name of the controller node self.forward(self.controller, msg, self.controller) fscore().after(1, "openflow-switch-table-ager" + str(self.name), self.table_ager) return len(entries)
def flowemit(self, flowlet, numsent, emitrv, destnode): fsend = copy(flowlet) fsend.bytes = int(min(next(emitrv), flowlet.bytes)) flowlet.bytes -= fsend.bytes psize = min(next(self.pktsizerv), flowlet.mss) psize = int(max(40, psize)) fsend.pkts = fsend.bytes / psize if fsend.pkts * psize < fsend.bytes: fsend.pkts += 1 fsend.bytes += fsend.pkts * 40 if flowlet.ipproto == socket.IPPROTO_TCP: flags = 0x0 if numsent == 0: # start of flow # set SYN flag flags |= 0x02 # if first flowlet, add 1 3-way handshake pkt. # simplifying assumption: 3-way handshake takes place in one # simulator tick interval with final ack piggybacked with data. fsend.pkts += 1 fsend.bytes += 40 if flowlet.bytes == 0: # end of flow # set FIN flag flags |= 0x01 fsend.pkts += 1 fsend.bytes += 40 # set ACK flag regardless flags |= 0x10 # ack fsend.tcpflags = flags numsent += 1 self.logger.debug("sending %d bytes %d pkts %s flags; flowlet has %d bytes remaining" % (fsend.bytes, fsend.pkts, fsend.tcpflagsstr, flowlet.size)) fscore().topology.node(self.srcnode).flowlet_arrival(fsend, 'harpoon', destnode) # if there are more flowlets, schedule the next one if flowlet.bytes > 0: fscore().after(fscore().interval, "flowemit-{}".format(self.srcnode), self.flowemit, flowlet, numsent, emitrv, destnode) else: # if there's nothing more to send, remove from active flows del self.activeflows[flowlet.key] # if we're operating in closed-loop mode, schedule beginning of next flow now that # we've completed the current one. if not self.xopen: fscore().after(next(self.flowstartrv), "newflow-{}".format(self.srcnode), self.newflow)
def __configure_edge_reliability(self, a, b, relistr, edict): relidict = fsutil.mkdict(relistr) ttf = ttr = None for k,v in relidict.iteritems(): if k == 'failureafter': ttf = eval(v) if isinstance(ttf, (int, float)): ttf = modulation_generator([ttf]) elif k == 'downfor': ttr = eval(v) if isinstance(ttr, (int, float)): ttr = modulation_generator([ttr]) elif k == 'mttf': ttf = eval(v) elif k == 'mttr': ttr = eval(v) if ttf or ttr: assert(ttf and ttr) xttf = next(ttf) fscore().after(xttf, 'link-failure-'+a+'-'+b, self.__linkdown, a, b, edict, ttf, ttr)
def newflow(self, xint=1.0): if self.done: print 'harpoon generator done' return flet = self.__makeflow() self.activeflows[flet.key] = 1 destnode = fscore().topology.destnode(self.srcnode, flet.dstaddr) owd = fscore().topology.owd(self.srcnode, destnode) # owd may be None if routing is temporarily broken because of # a link being down and no reachability if not owd: owd = 1.0 flet.mss = next(self.mssrv) # added by zafar #print "flow mss", flet.mss #print "owd", owd #print "flet.size", flet.size p = next(self.lossraterv) basertt = owd * 2.0 flowduration, byteemit = self.tcpmodel.model(flet.size, flet.mss, basertt, fscore().interval, p) #print "flowduration", flowduration #print "flet.bytes",flet.bytes # FIXME: add an end timestamp onto flow to indicate its estimated # duration; routers along path can add that end to arrival time to get # better flow duration in record. # unclear what to do with raw flows. flet.flowstart = 0.0 flet.flowend = flowduration self.logger.debug("Flow duration: %f" % flowduration) fscore().after(0.0, 'flowemit-'+str(self.srcnode), self.flowemit, flet, 0, byteemit, destnode) # if operating in an 'open-loop' fashion, schedule next # incoming flow now (otherwise schedule it when this flow ends; # see code in flowemit()) if self.xopen: nextst = next(self.flowstartrv) # print >>sys.stderr, 'scheduling next new harpoon flow at',nextst fscore().after(nextst, 'newflow-'+str(self.srcnode), self.newflow) self.logger.debug("I am in the open-loop") self.logger.debug("scheduling next harpoon flow at: ") print "Scheduling next harpoon flow at: ", nextst print "Flow is : ", str(self.srcnode) print "Flow dst port is ", str(flet.flowident)
def callback(self): f = self.__makeflow() f.bytes = next(self.bytes) if self.pktsize: psize = next(self.pktsize) f.pkts = f.bytes / psize if f.bytes % psize > 0: f.pkts += 1 else: f.pkts = next(self.pkts) destnode = fscore().topology.destnode(self.srcnode, f.dstaddr) # print 'rawflow:',f # print 'destnode:',destnode xinterval = None if self.interval: xinterval = next(self.interval) xinterval = max(0, xinterval) else: fps = next(self.fps) xinterval = 1.0 / fps ticks = None if not self.continuous: ticks = next(self.nflowlets) else: if self.nflowlets: ticks = next(self.nflowlets) else: ticks = 1 # print 'ticks',ticks # print 'xinterval',xinterval if not ticks or ticks == 1: fscore().topology.node(self.srcnode).flowlet_arrival( f, 'simple', destnode) else: fscore().after(0, "rawflow-flowemit-{}".format(self.srcnode), self.flowemit, f, destnode, xinterval, ticks) if self.continuous and not self.done: fscore().after(xinterval, "rawflow-cb-".format(self.srcnode), self.callback) else: self.done = True
def callback(self): f = self.__makeflow() f.bytes = next(self.bytes) if self.pktsize: psize = next(self.pktsize) f.pkts = f.bytes / psize if f.bytes % psize > 0: f.pkts += 1 else: f.pkts = next(self.pkts) destnode = fscore().topology.destnode(self.srcnode, f.dstaddr) # print 'rawflow:',f # print 'destnode:',destnode xinterval = None if self.interval: xinterval = next(self.interval) xinterval = max(0, xinterval) else: fps = next(self.fps) xinterval = 1.0/fps ticks = None if not self.continuous: ticks = next(self.nflowlets) else: if self.nflowlets: ticks = next(self.nflowlets) else: ticks = 1 # print 'ticks',ticks # print 'xinterval',xinterval if not ticks or ticks == 1: fscore().topology.node(self.srcnode).flowlet_arrival(f, 'simple', destnode) else: fscore().after(0, "rawflow-flowemit-{}".format(self.srcnode), self.flowemit, f, destnode, xinterval, ticks) if self.continuous and not self.done: fscore().after(xinterval, "rawflow-cb-".format(self.srcnode), self.callback) else: self.done = True
def newflow(self, xint=1.0): if self.done: print 'harpoon generator done' return flet = self.__makeflow() self.activeflows[flet.key] = 1 destnode = fscore().topology.destnode(self.srcnode, flet.dstaddr) owd = fscore().topology.owd(self.srcnode, destnode) # owd may be None if routing is temporarily broken because of # a link being down and no reachability if not owd: owd = 1.0 flet.mss = next(self.mssrv) p = next(self.lossraterv) basertt = owd * 2.0 flowduration, byteemit = self.tcpmodel.model(flet.size, flet.mss, basertt, fscore().interval, p) # FIXME: add an end timestamp onto flow to indicate its estimated # duration; routers along path can add that end to arrival time to get # better flow duration in record. # unclear what to do with raw flows. flet.flowstart = 0.0 flet.flowend = flowduration self.logger.debug("Flow duration: %f" % flowduration) fscore().after(0.0, 'flowemit-'+str(self.srcnode), self.flowemit, flet, 0, byteemit, destnode) # if operating in an 'open-loop' fashion, schedule next # incoming flow now (otherwise schedule it when this flow ends; # see code in flowemit()) if self.xopen: nextst = next(self.flowstartrv) # print >>sys.stderr, 'scheduling next new harpoon flow at',nextst fscore().after(nextst, 'newflow-'+str(self.srcnode), self.newflow)
def start(self): Node.start(self) fscore().after(1, "openflow-switch-table-ager" + str(self.name), self.table_ager)
def start(self): startt = next(self.flowstartrv) fscore().after(startt, 'harpoon-start'+str(self.srcnode), self.newflow)
def testNewSimulatorSingleton(self): self.assertIs(fscore(), SimTests.sim)
def start(self): fscore().after(0.0, 'subtractive-gen-callback', self.callback)
def docallback(self, *args): get_logger().debug("In fake pox timer callback {} {}".format( self._timeToWake, self._callback)) rv = self._callback(*self._args, **self._kw) if rv and self._recurring: fscore().after(self._timeToWake, self.id, self.docallback, None)
def start(self): Node.start(self) fscore().after(0.010, "arp {}".format(self.name), self.send_gratuitous_arps) self.logger.debug("OF Switch Startup: {}".format(dpid_to_str(self.pox_switch.dpid))) for p in self.ports: self.logger.debug("\tSwitch port {}: {}, {}".format(p, self.ports[p], self.pox_switch.ports[p].show()))
def cancel(self): get_logger().debug("Attempting to cancel fake POX timer {}".format( self.id)) fscore().cancel(self.id)
def start(self): fscore().after(next(self.starttime), 'flowev modulator startup', self.emerge_phase)
def callback(self): # pass oneself from srcnode to dstnode, performing action at each router # at end, set done to True f = SubtractiveFlowlet(FlowIdent(self.ipsrcfilt, self.ipdstfilt, ipproto=self.ipprotofilt), action=self.action) self.logger.info('Subtractive generator callback') fscore().node(self.srcnode).flowlet_arrival(f, 'subtractor', self.dstnode)