Beispiel #1
0
	def _handle_FlowStatsReceived(self, event):
		#stats = flow_stats_to_list(event.stats)
		#log.debug("Received Flow Stats from %s: %s", util.dpid_to_str(event.connection.dpid), stats)
		
		dpid = event.connection.dpid
		for stat in event.stats:
			
			match = ofp_match_withHash.from_ofp_match_Superclass(stat.match)
			if match.dl_type != pkt.ethernet.LLDP_TYPE and not (match.dl_type == pkt.ethernet.IP_TYPE and match.nw_proto == 253 and match.nw_dst == IPAddr("224.0.0.255")):
				if match not in prev_stats or dpid not in prev_stats[match]:
					prev_stats[match][dpid] = 0, 0, 0, 0, -1.0
				prev_packet_count, prev_byte_count, prev_duration_sec, prev_duration_nsec, prev_throughput = prev_stats[match][dpid]
				
				delta_packet_count = stat.packet_count - prev_packet_count
				delta_byte_count = stat.byte_count - prev_byte_count
				delta_duration_sec = stat.duration_sec - prev_duration_sec
				delta_duration_nsec = stat.duration_nsec - prev_duration_nsec
				
				cur_throughput = delta_byte_count / (delta_duration_sec + (delta_duration_nsec / 1000000000.0))
				
				log.debug("Stat switch: %s\tnw_src: %s\tnw_dst: %s\tnw_proto: %s\tpacketcount: %d\t bytecount: %d\t duration: %d s + %d ns\t, delta_packetcount: %d, delta_bytecount: %d, delta_duration: %d s + %d ns, throughput: %f", util.dpid_to_str(dpid), match.nw_src, match.nw_dst, match.nw_proto, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec, delta_packet_count, delta_byte_count, delta_duration_sec, delta_duration_nsec, cur_throughput)
				self.f.write("%s,%s,%s,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d,%f\n"%(self.experiment, util.dpid_to_str(dpid), match.nw_src, match.nw_dst, match.nw_proto, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec, delta_packet_count, delta_byte_count, delta_duration_sec, delta_duration_nsec, cur_throughput))
			
				#influence the timer by inspecting the change in throughput 
				if abs(cur_throughput - prev_throughput) > .05 * prev_throughput:
					self.decreaseTimer = False
				if abs(cur_throughput - prev_throughput) > .20 * prev_throughput:
					self.increaseTimer = True
				
				#log.debug("Stat switch: %s\tdl_type: %d\tnw_src: %s\tnw_dst: %s\tproto: %s\tsrc_port: %s\t dst_port: %s\tpacketcount: %d\t bytecount: %d\t duration: %d s + %d ns, delta_packetcount: %d, delta_bytecount: %d, delta_duration: %d s + %d ns", util.dpid_to_str(dpid), match.dl_type, match.nw_src, match.nw_dst, match.nw_proto, match.tp_src, match.tp_dst, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec, delta_packet_count, delta_byte_count, delta_duration_sec, delta_duration_nsec)
				#self.f.write("%s,%s,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n"%(self.experiment, util.dpid_to_str(dpid), match.nw_src, match.nw_dst, match.tp_src, match.tp_dst, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec, delta_packet_count, delta_byte_count, delta_duration_sec, delta_duration_nsec))
				
				self.f.flush()
				prev_stats[match][dpid] = stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec, cur_throughput
Beispiel #2
0
	def _handle_FlowRemoved(self, event):
		match = ofp_match_withHash.from_ofp_match_Superclass(event.ofp.match)
		path = monitored_pathsByMatch.pop(match, None)
		if path is not None:
			log.debug("Removing flow")
			monitored_paths[path].remove(match)
			if not monitored_paths[path]:
				del monitored_paths[path]
				del monitored_pathsById[id(path)]
				sw = path.dst
				
				while sw is not None: 
					monitored_pathsBySwitch[sw].remove(path)
					if not monitored_pathsBySwitch[sw]:
						del monitored_pathsBySwitch[sw]
					#pprint(monitored_pathsBySwitch[sw])
			
					sw = path.prev[sw]
Beispiel #3
0
 def _handle_FlowRemoved(self, event):
     match = ofp_match_withHash.from_ofp_match_Superclass(event.ofp.match)
     '''
Beispiel #4
0
class Monitoring(object):
    def _timer_MonitorPaths(self):
        #log.debug("Monitoring paths %s", str(datetime.now()))

        def AdaptiveTimer():
            changed = False
            #Increase or decrease the timers based on the throughput results measured based on the flowstats reply
            if (self.increaseTimer == True):
                self.t._interval /= 2
                changed = True
            elif (self.decreaseTimer == True):
                self.t._interval *= 1.125
                changed = True

            #maximize the interval
            if self.t._interval > 60:
                self.t._interval = 60

            #minimize the interval
            if self.t._interval < 1:
                self.t._interval = 1

            #update next timer if, and only if, the timer has changed
            if changed == True:
                self.t._next = time.time() + self.t._interval

            #Reset input from received flowstats
            self.increaseTimer = False
            self.decreaseTimer = True

        def RoundRobin():
            pathRead = {}
            for p in monitored_paths:
                pathRead[p] = False

            for p in monitored_paths:  #Walk through all distinct paths, not even flows
                if pathRead[p] != True:

                    if p not in pathIterator or pathIterator[
                            p] == p.src:  # Round Robin switch selection
                        pathIterator[p] = p.dst
                    else:
                        pathIterator[p] = p.prev[pathIterator[p]]

                    curSwitch = pathIterator[p]

                    #log.debug("Sending message to switch %s", util.dpid_to_str(curSwitch))
                    msg = of.ofp_stats_request(
                        body=of.ofp_flow_stats_request())
                    switches[curSwitch].connection.send(msg)
                    msg2 = of.ofp_stats_request(
                        body=of.ofp_port_stats_request())
                    switches[curSwitch].connection.send(msg2)
                    for pPrime in monitored_pathsBySwitch[
                            curSwitch]:  #Circumvent polling multiple switches for paths from whom the stats have already been requested
                        pathRead[pPrime] = True

        def LastSwitch():
            switchRead = {}
            for dpid in switches:
                switchRead[dpid] = False

            for p in monitored_paths:  #Walk through all distinct paths and select both last and first switch to calculate throughput and packet loss.
                if switchRead[p.dst] == False:
                    switchRead[p.dst] = True
                    msg = of.ofp_stats_request(
                        body=of.ofp_flow_stats_request())
                    switches[p.dst].connection.send(msg)
                    msg2 = of.ofp_stats_request(
                        body=of.ofp_port_stats_request())
                    switches[p.dst].connection.send(msg2)

                if switchRead[p.src] == False:
                    switchRead[p.src] = True
                    msg = of.ofp_stats_request(
                        body=of.ofp_flow_stats_request())
                    switches[p.src].connection.send(msg)
                    msg2 = of.ofp_stats_request(
                        body=of.ofp_port_stats_request())
                    switches[p.src].connection.send(msg2)

        def MonitorAll():
            #log.debug("Port Stats Sending to Switch\n")

            for con in core.openflow.connections:  # make this _connections.keys() for pre-betta
                con.send(
                    of.ofp_stats_request(body=of.ofp_port_stats_request()))

        def MeasureDelay():
            for p in monitored_paths:  #Walk through all distinct paths

                ip_pck = pkt.ipv4(
                    protocol=253,  #use for experiment and testing
                    srcip=IPAddr(p.__hash__()),
                    dstip=IPAddr("224.0.0.255"))

                pl = Payload(id(p), time.time())

                ip_pck.set_payload(repr(pl))

                eth_packet = pkt.ethernet(
                    type=pkt.ethernet.IP_TYPE
                )  #use something that does not interfer with regular traffic
                eth_packet.src = struct.pack(
                    "!Q", p.src)[2:]  #convert dpid to EthAddr
                eth_packet.dst = struct.pack("!Q", p.dst)[2:]
                eth_packet.set_payload(ip_pck)

                msg = of.ofp_packet_out()
                msg.actions.append(of.ofp_action_output(port=p.first_port))
                msg.data = eth_packet.pack()
                switches[p.src].connection.send(msg)

                #msg2 = of.ofp_barrier_request()
                #switches[p.src].connection.send(msg2)
                #barrier[msg2.xid] = (p.src, time.time())

                #msg3 = of.ofp_barrier_request()
                #switches[p.dst].connection.send(msg3)
                #barrier[msg3.xid] = (p.src, time.time())

                eth_packet = pkt.ethernet(type=pkt.ethernet.IP_TYPE)
                eth_packet.src = struct.pack("!Q", p.src)[2:]
                eth_packet.dst = struct.pack("!Q", p.src)[2:]
                eth_packet.set_payload(ip_pck)

                msg = of.ofp_packet_out()
                msg.actions.append(
                    of.ofp_action_output(port=of.OFPP_CONTROLLER))
                msg.data = eth_packet.pack()
                switches[p.src].connection.send(msg)

        #AdaptiveTimer() #use to experiment with the adaptive timer)

        #RoundRobin() #use to experiment with roundrobin switch selection
        #LastSwitch() #use to experiment with lastswitch switch selection
        MonitorAll()
        #MeasureDelay() #sends packets for delay measurement

    def __init__(self, postfix):
        #log.debug("Monitoring coming up")

        def startup():

            core.openflow.addListeners(
                self, priority=0xfffffffe
            )  #took 1 priority lower as the discovery module, although it should not matter

            core.opennetmon_forwarding.addListeners(self)  #("NewPath")

            self.decreaseTimer = False
            self.increaseTimer = False
            self.t = Timer(1, self._timer_MonitorPaths, recurring=True)

            self.f = open("output.%s.csv" % postfix, "w")
            #self.f.write("Experiment,Switch,SRC_IP,DST_IP,SRC_PORT,DST_PORT,Packet_Count,Byte_Count,Duration_Sec,Duration_Nsec,Delta_Packet_Count,Delta_Byte_Count,Delta_Duration_Sec,Delta_Duration_Nsec\n")
            #self.f.flush()
            #self.f3 = open("/groups/ch-geni-net/GIMITesting/ports.%s.csv"%postfix, "w")
            #self.f2 = open("delay.%s.csv"%postfix, "w")
            #self.f2.write("MeasurementType,Src/Initiator,Dst/Switch,Delay\n")
            #self.f2.flush()

            self.experiment = postfix

            #log.debug("Monitoring started")

        core.call_when_ready(startup,
                             ('opennetmon_forwarding'
                              ))  #Wait for opennetmon-forwarding to be started

    def __del__(self):

        self.f.close()

    def _handle_NewSwitch(self, event):
        switch = event.switch
        #log.debug("New switch to Monitor %s", switch.connection)
        switches[switch.connection.dpid] = switch
        switch.addListeners(self)
        #msg = of.ofp_stats_request(body=of.ofp_port_stats_request())
        #switch.connection.send(msg)

    def _handle_NewFlow(self, event):
        match = event.match
        '''
		path = event.prev_path
		adj = event.adj
		##log.debug("New flow to monitor %s", str(match))
		##log.debug(path._tuple_me())
		
		_install_monitoring_path(path, adj)
		
		if path not in monitored_paths:
			monitored_paths[path] = set([match])
			monitored_pathsById[id(path)] = path
			sw = path.dst
			while sw is not None:
				if sw not in monitored_pathsBySwitch:
					monitored_pathsBySwitch[sw] = set([path])
				else:
					monitored_pathsBySwitch[sw].add(path)
				#pprint(monitored_pathsBySwitch[sw])
				sw = path.prev[sw]
		else:
			monitored_paths[path].add(match)
		#pprint(monitored_paths[path])
			
		monitored_pathsByMatch[match] = path
	'''

    def _handle_FlowRemoved(self, event):
        match = ofp_match_withHash.from_ofp_match_Superclass(event.ofp.match)
        '''
		path = monitored_pathsByMatch.pop(match, None)
		if path is not None:
			#log.debug("Removing flow")
			monitored_paths[path].remove(match)
			if not monitored_paths[path]:
				del monitored_paths[path]
				del monitored_pathsById[id(path)]
				sw = path.dst
				
				while sw is not None: 
					monitored_pathsBySwitch[sw].remove(path)
					if not monitored_pathsBySwitch[sw]:
						del monitored_pathsBySwitch[sw]
					#pprint(monitored_pathsBySwitch[sw])
			
					sw = path.prev[sw]
			#pprint(monitored_paths[path])
		'''

    def _handle_FlowStatsReceived(self, event):
        #stats = flow_stats_to_list(event.stats)
        ##log.debug("Received Flow Stats from %s: %s", util.dpid_to_str(event.connection.dpid), stats)
        try:
            client = pymongo.MongoClient("205.172.170.30")
            print "Connected successfully!!!"
        except pymongo.errors.ConnectionFailure, e:
            print "Could not connect to MongoDB: %s" % e
        #client
        db = client.opencdn
        table = db.netmonitor
        dpid = event.connection.dpid
        for stat in event.stats:
            match = ofp_match_withHash.from_ofp_match_Superclass(stat.match)
            if match.dl_type != pkt.ethernet.LLDP_TYPE and not (
                    match.dl_type == pkt.ethernet.IP_TYPE and match.nw_proto
                    == 253 and match.nw_dst == IPAddr("224.0.0.255")):
                if match not in prev_stats or dpid not in prev_stats[match]:
                    prev_stats[match][dpid] = 0, 0, 0, 0, -1.0
                prev_packet_count, prev_byte_count, prev_duration_sec, prev_duration_nsec, prev_throughput = prev_stats[
                    match][dpid]

                delta_packet_count = stat.packet_count - prev_packet_count
                delta_byte_count = stat.byte_count - prev_byte_count
                delta_duration_sec = stat.duration_sec - prev_duration_sec
                delta_duration_nsec = stat.duration_nsec - prev_duration_nsec
                if delta_duration_nsec > 0:
                    cur_throughput = delta_byte_count / (
                        delta_duration_sec +
                        (delta_duration_nsec / 1000000000.0))

                    ##log.debug("Stat switch: %s\tnw_src: %s\tnw_dst: %s\tnw_proto: %s\tpacketcount: %d\t bytecount: %d\t duration: %d s + %d ns\t, delta_packetcount: %d, delta_bytecount: %d, delta_duration: %d s + %d ns, throughput: %f", util.dpid_to_str(dpid), match.nw_src, match.nw_dst, match.nw_proto, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec, delta_packet_count, delta_byte_count, delta_duration_sec, delta_duration_nsec, cur_throughput)
                    self.f.write(
                        "%s,%s,%s,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d,%f\n" %
                        (self.experiment, util.dpid_to_str(dpid), match.nw_src,
                         match.nw_dst, match.nw_proto, stat.packet_count,
                         stat.byte_count, stat.duration_sec,
                         stat.duration_nsec, delta_packet_count,
                         delta_byte_count, delta_duration_sec,
                         delta_duration_nsec, cur_throughput))
                    post = {
                        "exp_id": self.experiment,
                        "dpid": util.dpid_to_str(dpid),
                        "srcip": str(match.nw_src),
                        "dstip": str(match.nw_dst),
                        "pkttype": str(match.nw_proto),
                        "pktcount": stat.packet_count,
                        "bytecount": stat.byte_count,
                        "duration": stat.duration_sec,
                        "delpkt": delta_packet_count,
                        "delbytecount": delta_byte_count,
                        "delduration": delta_duration_sec,
                        "throughput": cur_throughput,
                        "date": datetime.utcnow()
                    }
                    #posts = table
                    post_id = table.insert_one(post).inserted_id
                    self.f.flush()
                    prev_stats[match][
                        dpid] = stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec, cur_throughput
                #influence the timer by inspecting the change in throughput
                if abs(cur_throughput -
                       prev_throughput) > .05 * prev_throughput:
                    self.decreaseTimer = False
                if abs(cur_throughput -
                       prev_throughput) > .20 * prev_throughput:
                    self.increaseTimer = True