def learn_and_forward(self, dpid, inport, packet, buf, bufid):
		
		# learn mac on incoming port from src
		src_mac = mac_to_str(packet.src)
		dst_mac = mac_to_str(packet.dst)
		if self.mac_to_port.has_key(src_mac):
			# print update msg
			old_outport = self.mac_to_port[src_mac]
			if old_outport != inport:
				logger.info('MAC ' + src_mac + ' has moved from %d to %d', old_outport, inport)
			else:
				logger.info('MAC ' + src_mac + ' remained on %d', old_outport)
		else:
			logger.info('learned MAC ' + src_mac + ' on %d port %d', dpid, inport)
		
		self.mac_to_port[src_mac] = inport

		# try find a outport for dst
		if self.mac_to_port.has_key(dst_mac):

			outport = self.mac_to_port[dst_mac]
			if outport == inport:
				self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
				logger.error('*** warning *** learned port == inport, flood packet')
			else:
				logger.info('install flow for ' + str(packet))
				flow = extract_flow(packet)
				flow[core.IN_PORT] = inport
				actions = [[openflow.OFPAT_OUTPUT, [0, outport]]]
				self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions, bufid, openflow.OFP_DEFAULT_PRIORITY, inport, buf)
		else:
			logger.info('*** warning *** no learned, flood packet')
			self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
Example #2
0
	def learn_and_forward(self, dpid, inport, packet, buf, bufid):
		"""Learn MAC src port mapping, then flood or send unicast."""
		
		print inport
		print mac_to_str(packet.src)
		print mac_to_str(packet.dst)
		
		# Initial hub behavior: flood packet out everything but input port.
		# Comment out the line below when starting the exercise.
		# self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)

		# Starter psuedocode for learning switch exercise below: you'll need to
		# replace each pseudocode line with more specific Python code.

		# Learn the port for the source MAC
		#self.mac_to_port = <fill in>
		src_mac = mac_to_int(packet.src)
		self.mac_to_port[src_mac] = inport
		dst_mac = mac_to_int(packet.dst)
		if ( dst_mac in self.mac_to_port ):
			print 'find a match'
			# Send unicast packet to known output port
			outport = self.mac_to_port[dst_mac]
			actions = [[openflow.OFPAT_OUTPUT, [0, outport]]]
			self.send_openflow(dpid, bufid, buf, actions, inport)
		else:
			print 'no match, flood to all ports'
			#flood packet out everything but the input port
			self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
Example #3
0
def delete_flow(flow, replicaNum):
    switchNum = findReplicasSwitch(replicaNum)
    deleteMultipaths = getMultipaths(switchNum)
    for currNode in deleteMultipaths:
        currSwitchNum = currNode['no']
        currMac = currNode['mac']
        flowList = getMultiFlow(flow, len(currNode['nexthops']))
        for i, miniFlow in enumerate(flowList):
            Globals.COMPONENT.delete_strict_datapath_flow(currMac, miniFlow)
            if not flow.has_key(NW_SRC_N_WILD):
                Globals.RULESLOG.write(
                    mac_to_str(currMac) + " Delete Multipath @ " +
                    str(currSwitchNum) + " to dest " + str(switchNum) + ' ' +
                    ip_to_str(flow[NW_SRC]) + '\n')
            else:
                Globals.RULESLOG.write(
                    mac_to_str(currMac) + " Delete Multipath @ " +
                    str(currSwitchNum) + " to dest " + str(switchNum) + ' ' +
                    ip_to_str(flow[NW_SRC]) + '/' + str(flow[NW_SRC_N_WILD]) +
                    '\n')


#    orderDelete = getAllPaths(switchNum)
#    for switch in orderDelete:
#        currMac = getMac(switch)
#        Globals.log.info('Delete Flow: ' + str(flow) + ' at ' + str(switch))
#        Globals.COMPONENT.delete_strict_datapath_flow(currMac, flow)
    Globals.RULESLOG.write('Delete: ' + ip_to_str(flow[NW_SRC]) + '/' +
                           str(flow[NW_SRC_N_WILD]) + '\n')
Example #4
0
    def packet_in_callback(self, dpid, inport, reason, len, bufid, packet):
        if packet.type == Globals.ARP_TYPE:
	    # ARP Response from replicas for our ARP Requests
            if packet.dst == octstr_to_array(Globals.VMAC):
                self.foundMac(dpid, mac_to_str(packet.src), ip_to_str(packet.next.protosrc), inport)
	    # Request for VIP, respond with ARP Response
            elif packet.next.protodst == ipstr_to_int(Globals.VIP):
		Globals.STATSLOG.write(mac_to_str(dpid) + ' received ' + ip_to_str(packet.next.protosrc) + '\n')
                srcIP = ip_to_str(packet.next.protosrc)
		# Install Rewrite Rules
                (flow, defaultActions, rewriteActions) = IPs.get_forwarding_srcrule(srcIP, mac_to_str(packet.src), Globals.VMAC, Globals.VIP, inport)
                Multipath.install_microflow_flow(flow, openflow.OFP_FLOW_PERMANENT, openflow.OFP_FLOW_PERMANENT, defaultActions, None, openflow.OFP_DEFAULT_PRIORITY + 20, 0, None, dpid, inport, rewriteActions)
		# Response
                arpResponse = Arps.create_virtual_arp_response(packet, octstr_to_array(Globals.VMAC), ipstr_to_int(Globals.VIP))
                Multipath.send(dpid, None, arpResponse, [[openflow.OFPAT_OUTPUT, [0, inport]]], openflow.OFPP_CONTROLLER)
                ip = ip_to_str(packet.next.protosrc)
                for i, switchJ in enumerate(Globals.SWITCHES):
                    if switchJ['mac'] == dpid:
                        found = False
			for i, client in enumerate(switchJ['clients']):
			    if client['ip'] == ip:
 				found = True
			if not found:
   			    Globals.STATSLOG.write(mac_to_str(dpid) + ' found ' + ip + '\n')
                            switchJ['clients'].append({'port': inport, 'ip': ip, 'oldCount': 0L, 'newCount': 0L, 'avg': 0L})
            elif packet.src != octstr_to_array(Globals.VMAC):
		Globals.STATSLOG.write(mac_to_str(dpid) + ' received REQ ' + ip_to_str(packet.next.protosrc) + '\n')
                arpResponse = Arps.create_arp_response(packet)
                Multipath.send(dpid, None, arpResponse, [[openflow.OFPAT_OUTPUT, [0, inport]]], openflow.OFPP_CONTROLLER)
	elif packet.type == Globals.IP_TYPE:
            if reason == openflow.OFPR_ACTION:
                IPTransition.handleControllerAction(packet)
Example #5
0
def install_replica_flow(flow, idle_timeout, hard_timeout, actions, bufid, priority, inport, packet, replicaNum, rewriteActions):
    switchNum = findReplicasSwitch(replicaNum)
    orderMultipaths = getMultipaths(switchNum)
    Globals.log.info("Order Multipaths")
    Globals.log.info(str(orderMultipaths))
    for currNode in orderMultipaths:
        currSwitchNum = currNode['no']
	currMac = currNode['mac']
	if flow.has_key(NW_SRC_N_WILD):
	    flowList = getMultiFlow(flow, len(currNode['nexthops']))
            for i, miniFlow in enumerate(flowList):
                if switchNum == currSwitchNum:
		    nextHop = 0
      	            actions = setReplicaOutPort(rewriteActions, switchNum, currSwitchNum, nextHop, replicaNum)
                else:
	            nextHop = currNode['nexthops'][i % len(currNode['nexthops'])]
    	            actions = setReplicaOutPort(actions, switchNum, currSwitchNum, nextHop, replicaNum)
	        Globals.COMPONENT.install_datapath_flow(currMac, miniFlow, idle_timeout, hard_timeout, actions, bufid, priority, inport, packet)
	        Globals.RULESLOG.write(mac_to_str(currMac) + " Install Multipath @ " + str(currSwitchNum) + " to dest " + str(switchNum) + ' ' + ip_to_str(miniFlow[NW_SRC]) + '/' + str(miniFlow[NW_SRC_N_WILD]) + '\n')
	else:
	    if switchNum == currSwitchNum:
		nextHop = 0
		actions = setReplicaOutPort(rewriteActions, switchNum, currSwitchNum, nextHop, replicaNum)
	    else:
		nextHopIndex = random.randint(0, len(currNode['nexthops']) - 1)
		nextHop = currNode['nexthops'][nextHopIndex]
#		nextHop = Globals.FORWARDINGTABLE[switchNum][currSwitchNum]['prevhop']
		actions = setReplicaOutPort(actions, switchNum, currSwitchNum, nextHop, replicaNum)
	    Globals.COMPONENT.install_datapath_flow(currMac, flow, idle_timeout, hard_timeout, actions, bufid, priority, inport, packet)
	    Globals.RULESLOG.write(mac_to_str(currMac) + " Install Multipath @ " + str(currSwitchNum) + " to dest " + str(switchNum) + ' ' + ip_to_str(flow[NW_SRC]) + '\n')
    Globals.RULESLOG.write('Install Wildcard: ' + ip_to_str(flow[NW_SRC]) + '\n')
Example #6
0
    def l2_forwarding (self, dpid, inport, packet, bufid) :
        
        [forward_type, outports] = self.fdb.search (dpid, 
                                                    mac_to_str (packet.src), 
                                                    mac_to_str (packet.dst), 
                                                    inport)
        
        if forward_type == 'FLOOD' :
            actions = []
            for port in outports :
                actions.append ([openflow.OFPAT_OUTPUT, [0, port]])

            print 'flooding dipd=%x dstmac=%s' % (dpid, mac_to_str (packet.dst))
            print outports
            self.send_openflow (dpid, bufid, packet.arr, actions, inport)

        elif forward_type == 'UNICAST' :
            flow = extract_flow (packet)
            flow[core.IN_PORT] = inport
        
            actions = [[openflow.OFPAT_OUTPUT, [0, outports.pop ()]]]
            self.install_datapath_flow (dpid, flow, FLOW_LIFETIME,
                                        openflow.OFP_FLOW_PERMANENT, actions,
                                        bufid, openflow.OFP_DEFAULT_PRIORITY,
                                        inport, packet.arr)

        return
Example #7
0
def updateInstalledCounters(switchNum, ports):
    switch = getSwitch(Globals.SWITCHES, switchNum)
    Globals.log.info(mac_to_str(switchNum) + ' has ' + str(len(ports)) + ' ports')
    for i, port in enumerate(ports):
        for j, client in enumerate(switch['clients']):
	    client['oldCount'] = client['newCount']
            if port['port_no'] == client['port']:
		client['newCount'] = port['rx_packets']
#                client['newCount'] = Globals.EMA_CONSTANT * port['rx_packets'] + (1 - Globals.EMA_CONSTANT) * client['oldCount']
#		client['newCount'] = port['rx_packets']
		client['avg'] = Globals.EMA_CONSTANT * (client['newCount'] - client['oldCount']) + (1 - Globals.EMA_CONSTANT) * client['oldCount']
		Globals.STATSLOG.write(mac_to_str(switchNum) + ' ' + str(client['ip']) + ' -> ' + str(port['rx_packets']) + '\n')
Example #8
0
def install_replica_flow(flow, idle_timeout, hard_timeout, actions, bufid,
                         priority, inport, packet, replicaNum, rewriteActions):
    switchNum = findReplicasSwitch(replicaNum)
    orderMultipaths = getMultipaths(switchNum)
    Globals.log.info("Order Multipaths")
    Globals.log.info(str(orderMultipaths))
    for currNode in orderMultipaths:
        currSwitchNum = currNode['no']
        currMac = currNode['mac']
        if flow.has_key(NW_SRC_N_WILD):
            flowList = getMultiFlow(flow, len(currNode['nexthops']))
            for i, miniFlow in enumerate(flowList):
                if switchNum == currSwitchNum:
                    nextHop = 0
                    actions = setReplicaOutPort(rewriteActions, switchNum,
                                                currSwitchNum, nextHop,
                                                replicaNum)
                else:
                    nextHop = currNode['nexthops'][i %
                                                   len(currNode['nexthops'])]
                    actions = setReplicaOutPort(actions, switchNum,
                                                currSwitchNum, nextHop,
                                                replicaNum)
                Globals.COMPONENT.install_datapath_flow(
                    currMac, miniFlow, idle_timeout, hard_timeout, actions,
                    bufid, priority, inport, packet)
                Globals.RULESLOG.write(
                    mac_to_str(currMac) + " Install Multipath @ " +
                    str(currSwitchNum) + " to dest " + str(switchNum) + ' ' +
                    ip_to_str(miniFlow[NW_SRC]) + '/' +
                    str(miniFlow[NW_SRC_N_WILD]) + '\n')
        else:
            if switchNum == currSwitchNum:
                nextHop = 0
                actions = setReplicaOutPort(rewriteActions, switchNum,
                                            currSwitchNum, nextHop, replicaNum)
            else:
                nextHopIndex = random.randint(0, len(currNode['nexthops']) - 1)
                nextHop = currNode['nexthops'][nextHopIndex]
                #		nextHop = Globals.FORWARDINGTABLE[switchNum][currSwitchNum]['prevhop']
                actions = setReplicaOutPort(actions, switchNum, currSwitchNum,
                                            nextHop, replicaNum)
            Globals.COMPONENT.install_datapath_flow(currMac, flow,
                                                    idle_timeout, hard_timeout,
                                                    actions, bufid, priority,
                                                    inport, packet)
            Globals.RULESLOG.write(
                mac_to_str(currMac) + " Install Multipath @ " +
                str(currSwitchNum) + " to dest " + str(switchNum) + ' ' +
                ip_to_str(flow[NW_SRC]) + '\n')
    Globals.RULESLOG.write('Install Wildcard: ' + ip_to_str(flow[NW_SRC]) +
                           '\n')
    def host_bind_handler(self, data):
        """ Handler for host_bind_event """
        assert(data is not None)
        try:
            bind_data   = data.__dict__
            dladdr      = pkt_utils.mac_to_str(bind_data['dladdr'])
            host_ipaddr = nxw_utils.convert_ipv4_to_str(bind_data['nwaddr'])

            # Check reason value
            reason     = int(bind_data['reason'])
            if not reason in self.__reasons:
                LOG.error("Got host_leave event with unsupported reason value")
                return CONTINUE
            reason_str = self.__reasons[reason]
            LOG.info("Received host_bind_ev with reason '%s'" % reason_str)

            # XXX FIXME: Insert mapping for values <--> reason
            if reason > 7:
                if dladdr not in self.hosts:
                    LOG.debug("Ignoring Received host_leave_ev for an host" + \
                              " not present in DB")
                    return CONTINUE
                else:
                    ret = self.__host_leave(dladdr)
                    if not ret:
                        return CONTINUE

            elif (reason < 3 or reason == 5) and (bind_data['nwaddr'] == 0):
                LOG.debug("Ignoring host_bind_ev without IPaddr info")
                return CONTINUE
            elif (reason > 2) and (reason != 5):
                LOG.error("Unsupported reason for host_bind_ev: '%s'" % \
                           reason_str)
                return CONTINUE

            LOG.info("Received host_bind_ev with the following data: %s" % \
                      str(bind_data))

            # Check for presence of the host in stored (internal) hosts
            if dladdr in self.hosts:
                if self.hosts[dladdr].ip_addr is None:
                    LOG.debug("Got host_bind_ev for an host not posted yet")
                    # Post host
                    payload = {"ip_addr"    : host_ipaddr,
                               "mac"        : dladdr,
                               "peer_dpid"  : self.hosts[dladdr].rem_dpid,
                               "peer_portno": self.hosts[dladdr].rem_port}
                    req = requests.post(url=self.url + "pckt_host",
                                        headers=self.hs,
                                        data=json.dumps(payload))
                    LOG.debug("URL=%s, response(code=%d, content=%s)",
                              req.url, req.status_code, str(req.content))
                else:
                    LOG.debug("Got host_bind_ev for an host already posted")

            else:
                LOG.debug("Got host_bind_ev for an host not authenticated yet")

        except Exception, err:
            LOG.error("Got error in host_bind_handler (%s)" % str(err))
Example #10
0
    def dp_join(self, dp, stats):
        if self.known_switches.has_key(dp):
            lg.err("Received datapath join for a known switch: %s" % hex(dp))
            del self.known_switches[dp]

        import pprint
        lg.debug("Received datapath join %s: %s" % (hex(dp), pprint.pformat(stats)))

        stats['dpid']     = dp 

        ip = self.ctxt.get_switch_ip(dp)
        stats["ip"] = str(create_ipaddr(c_htonl(ip)))

        self.known_switches[dp] = stats

        ports_by_id = {}
        ports_by_name = {}
        for port in stats["ports"]:
          new_mac = mac_to_str(port['hw_addr'])
          port['hw_addr'] = new_mac 

          ports_by_name[port['name']] = port
          ports_by_id[port['port_no']] = port

        stats["ports_by_id"] = ports_by_id
        stats["ports_by_name"] = ports_by_name

        return CONTINUE
Example #11
0
    def dp_join(self, dp, stats):

        dpid_obj = datapathid.from_host(dp)
        stats['dpid']     = dp 
        self.dp_stats[dp] = stats
       
        # convert all port hw_addrs to ASCII
        # and register all port names with bindings storage
   
        port_list = self.dp_stats[dp]['ports']
        for i in range(0,len(port_list)):
          new_mac = mac_to_str(port_list[i]['hw_addr']).replace(':','-')
          port_list[i]['hw_addr'] = new_mac 

        # polling intervals for switch statistics
        self.dp_poll_period[dp] = {} 
        self.dp_poll_period[dp]['table'] = DEFAULT_POLL_TABLE_PERIOD
        self.dp_poll_period[dp]['port']  = DEFAULT_POLL_PORT_PERIOD
        self.dp_poll_period[dp]['aggr']  = DEFAULT_POLL_AGGREGATE_PERIOD

        # Switch descriptions do not change while connected, so just send once
        self.ctxt.send_desc_stats_request(dp)
           
        # stagger timers by one second
        self.post_callback(self.dp_poll_period[dp]['table'], 
                              lambda : self.table_timer(dp))
        self.post_callback(self.dp_poll_period[dp]['port'] + 1, 
                              lambda : self.port_timer(dp))

        return CONTINUE
Example #12
0
def do_l2_learning(dpid, inport, packet, buf, bufid):
    global inst

    # learn MAC on incoming port
    srcaddr = packet.src.tostring()
    if ord(srcaddr[0]) & 1:
        return
    if inst.st[dpid].has_key(srcaddr):
        dst = inst.st[dpid][srcaddr]
        if dst[0] != inport:
            log.msg('MAC has moved from ' + str(dst) + 'to' + str(inport),
                    system='pyswitch')
        else:
            return
    else:
        log.msg('learned MAC ' + mac_to_str(packet.src) + ' on %d %d' %
                (dpid, inport),
                system="pyswitch")

    # learn or update timestamp of entry
    inst.st[dpid][srcaddr] = (inport, time(), packet)
    # and set-up wildcard flow to this mac address
    flow = {}
    flow[core.DL_DST] = packet.src
    actions = [[openflow.OFPAT_OUTPUT, [0, inport]]]
    inst.install_datapath_flow(dpid, flow, CACHE_TIMEOUT,
                               openflow.OFP_FLOW_PERMANENT, actions, None,
                               openflow.OFP_DEFAULT_PRIORITY, inport, None)
    def __build_fentry_db(self, ingress):
        flow = {"dl_type"       : None,
                "dl_src"        : None,
                "dl_dst"        : None,
                "dl_vlan"       : None,
                "dl_vlan_pcp"   : None,
                "nw_src"        : None,
                "nw_dst"        : None,
                "nw_proto"      : None,
                "in_port"       : None,
                "nw_src_n_wild" : None,
                "nw_dst_n_wild" : None,
                "tp_src"        : None,
                "tp_dst"        : None,
                }
        # update flow with not null received values
        for key in ingress:
            # conversions for mac_addr and nw_addr
            if (key == "dl_src") or (key == "dl_dst"):
                flow[key] = pkt_utils.mac_to_str(ingress[key])
            elif (key == "nw_src") or (key == "nw_dst"):
                flow[key] = pkt_utils.ip_to_str(ingress[key])
            else:
                flow[key] = ingress[key]

        return flow
    def host_auth_handler(self, data):
        """ Handler for host_auth_event """
        assert(data is not None)
        try:
            auth_data = data.__dict__
            LOG.info("Received host_auth_ev with the following data: %s" %
                      str(auth_data))
            dladdr      = pkt_utils.mac_to_str(auth_data['dladdr'])
            host_ipaddr = nxw_utils.convert_ipv4_to_str(auth_data['nwaddr'])
            try:
                # connect and open transaction
                self.db_conn.open_transaction()
                if auth_data['nwaddr'] == 0:
                    LOG.debug("Received auth_event without IP address...")
                    mac_addresses = self.db_conn.port_get_macs()
                    if dladdr in mac_addresses:
                        LOG.debug("Ignoring received auth_ev for OF switch...")
                        return CONTINUE

                    else:
                        # Since Datapath_join event for an OF switch with
                        # dladdr could be caught later, we need to store info
                        self.hosts[dladdr]          = nxw_utils.Host(dladdr)
                        self.hosts[dladdr].rem_dpid = auth_data['datapath_id']
                        self.hosts[dladdr].rem_port = auth_data['port']
                        return CONTINUE

                if dladdr in self.auth_hosts:
                    LOG.debug("Ignoring auth_event (more notifications for" + \
                              " multiple inter-switch links)")
                    return CONTINUE
                self.auth_hosts.append(dladdr)

                host_idx = None
                try:
                    host_idx = self.db_conn.host_get_index(dladdr)
                except Exception, err:
                    LOG.debug("Any host with mac='%s' in DB" % str(dladdr))

                if host_idx is None:
                    LOG.debug("Adding new host with MAC addr '%s'" % \
                              str(dladdr))
                    try:
                        # Insert Host info into DB
                        self.__host_insert_db(dladdr,
                                              auth_data['datapath_id'],
                                              auth_data['port'],
                                              host_ipaddr)
                        LOG.info("Added host '%s' into DB" % str(dladdr))
                        if dladdr in self.auth_hosts:
                            self.auth_hosts.remove(dladdr)
                            log.debug("Removed '%s' from (local) auth hosts" %
                                      str(dladdr))
                    except nxw_utils.DBException as err:
                        LOG.error(str(err))
                        self.db_conn.rollback()
                    except Exception, err:
                        LOG.error("Cannot insert host info into DB ('%s')")
                else:
Example #15
0
 def port_status_handler(self, dpid, reason, port):
     intdp = int(dpid)
     if intdp not in self.dp_stats:
         log.err("port status from unknown datapath", system="switchstats")
         return
     # copy over existing port status
     for i in range(0, len(self.dp_stats[intdp]["ports"])):
         oldport = self.dp_stats[intdp]["ports"][i]
         if oldport["name"] == port["name"]:
             port["hw_addr"] = mac_to_str(port["hw_addr"]).replace(":", "-")
             self.dp_stats[intdp]["ports"][i] = port
Example #16
0
 def port_status_handler(self, dpid, reason, port):
     intdp = int(dpid)
     if intdp not in self.dp_stats:
         log.err('port status from unknown datapath', system='switchstats')
         return
     # copy over existing port status
     for i in range(0, len(self.dp_stats[intdp]['ports'])):
         oldport  = self.dp_stats[intdp]['ports'][i]
         if oldport['name'] == port['name']:
             port['hw_addr'] = mac_to_str(port['hw_addr']).replace(':','-')
             self.dp_stats[intdp]['ports'][i] = port
Example #17
0
def delete_flow(flow, replicaNum):
    switchNum = findReplicasSwitch(replicaNum)
    deleteMultipaths = getMultipaths(switchNum)
    for currNode in deleteMultipaths:
        currSwitchNum = currNode['no']
        currMac = currNode['mac']
        flowList = getMultiFlow(flow, len(currNode['nexthops']))
        for i, miniFlow in enumerate(flowList):
            Globals.COMPONENT.delete_strict_datapath_flow(currMac, miniFlow)
	    if not flow.has_key(NW_SRC_N_WILD):
	        Globals.RULESLOG.write(mac_to_str(currMac) + " Delete Multipath @ " + str(currSwitchNum) + " to dest " + str(switchNum) + ' ' + ip_to_str(flow[NW_SRC]) + '\n')
	    else:
	        Globals.RULESLOG.write(mac_to_str(currMac) + " Delete Multipath @ " + str(currSwitchNum) + " to dest " + str(switchNum) + ' ' + ip_to_str(flow[NW_SRC]) + '/' + str(flow[NW_SRC_N_WILD]) + '\n')

#    orderDelete = getAllPaths(switchNum)
#    for switch in orderDelete:
#        currMac = getMac(switch)
#        Globals.log.info('Delete Flow: ' + str(flow) + ' at ' + str(switch))
#        Globals.COMPONENT.delete_strict_datapath_flow(currMac, flow)
    Globals.RULESLOG.write('Delete: ' + ip_to_str(flow[NW_SRC]) + '/' + str(flow[NW_SRC_N_WILD]) + '\n')
def timer_callback():
    global inst

    curtime  = time()
    for dpid in inst.st.keys():
        for entry in inst.st[dpid].keys():
            if (curtime - inst.st[dpid][entry][1]) > CACHE_TIMEOUT:
                log.msg('timing out entry'+mac_to_str(entry)+str(inst.st[dpid][entry])+' on switch %x' % dpid, system='pyswitch')
                inst.st[dpid].pop(entry)

    inst.post_callback(1, timer_callback)
    return True
def do_l2_learning(dpid, inport, packet):
    global inst 


    # learn MAC on incoming port
    srcaddr = packet.src.tostring()

    if ord(srcaddr[0]) & 1:
        return
    if inst.st[dpid].has_key(srcaddr):
        dst = inst.st[dpid][srcaddr]
        if dst[0] != inport:
            log.msg('MAC has moved from '+str(dst)+'to'+str(inport), system='pyswitch')
        else:
            return
    else:
        log.msg('learned MAC '+mac_to_str(packet.src)+' on %d %d'% (dpid,inport), system="pyswitch")
        logger.info('learned MAC '+mac_to_str(packet.src)+' on %x %d'% (dpid,inport))
    # learn or update timestamp of entry
    inst.st[dpid][srcaddr] = (inport, time(), packet)

    # Replace any old entry for (switch,mac).
    mac = mac_to_int(packet.src)
Example #20
0
def timer_callback():
    global inst

    curtime = time()
    for dpid in inst.st.keys():
        for entry in inst.st[dpid].keys():
            if (curtime - inst.st[dpid][entry][1]) > CACHE_TIMEOUT:
                log.msg('timing out entry' + mac_to_str(entry) +
                        str(inst.st[dpid][entry]) + ' on switch %x' % dpid,
                        system='pyswitch')
                inst.st[dpid].pop(entry)

    inst.post_callback(1, timer_callback)
    return True
Example #21
0
    def learn_and_forward(self, dpid, inport, packet, buf, bufid):
        logger.info("Learning & Forwarding Packet" + str(packet))

        # Starter psuedocode for learning switch exercise

        if not self.mac_to_port.has_key(dpid):
            self.mac_to_port[dpid] = {}

    #learn the port for the source MAC
        srcaddr = packet.src.tostring()
        if (self.mac_to_port[dpid].has_key(srcaddr)):
            # If address has already been learned, check if it has moved
            dst = self.mac_to_port[dpid][srcaddr]
            if dst[0] != inport:
                logger.info('MAC has moved from ' + str(dst) + 'to' +
                            str(inport))
        else:
            logger.info('Learned MAC ' + mac_to_str(packet.src) + 'on %d %d' %
                        (dpid, inport))
            self.mac_to_port[dpid][srcaddr] = (inport, packet)

    #if (destination MAC of the packet is known)
        dstaddr = packet.dst.tostring()
        if (self.mac_to_port[dpid].has_key(dstaddr)):
            logger.info('Learned Destionation MAC')
            prt = self.mac_to_port[dpid][dstaddr]

            #send unicast packet to known output port
            self.send_openflow(dpid, bufid, buf, prt[0], inport)

            # push down flow entry


#	    flow = extract_flow(packet)
#	    flow[core.IN_PORT] = inport
#	    actions = [[openflow.OFPAT_OUTPUT, [0, prt[0]]]]
#	    CACHE_TIMEOUT = 5
#	    self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT,
#				       openflow.OFP_FLOW_PERMANENT, actions,
#				       bufid, openflow.OFP_DEFAULT_PRIORITY,
#				       inport, buf)
#
        else:
            #flood packet out everything but the input port
            self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
Example #22
0
    def dp_join(self, dp, stats):
	lg.warn('############### dp_join ###############\n')
	#lg.warn('dp_list_size = ', len(dp_list))
	global dp_num
	if dp in dp_list:
		dp_list.remove(dp)
	lg.warn(dp)
	lg.warn('#######################################\n')
	dp_list.append(dp)
	dp_list.sort()
        dpid_obj = datapathid.from_host(dp)
        stats['dpid']     = dp 
        self.dp_stats[dp] = stats
       
        # convert all port hw_addrs to ASCII
        # and register all port names with bindings storage
   
        port_list = self.dp_stats[dp]['ports']
        for i in range(0,len(port_list)):
          new_mac = mac_to_str(port_list[i]['hw_addr']).replace(':','-')
          port_list[i]['hw_addr'] = new_mac 

        # polling intervals for switch statistics
        self.dp_poll_period[dp] = {} 
        self.dp_poll_period[dp]['table'] = DEFAULT_POLL_TABLE_PERIOD
        self.dp_poll_period[dp]['port']  = DEFAULT_POLL_PORT_PERIOD
        self.dp_poll_period[dp]['aggr']  = DEFAULT_POLL_AGGREGATE_PERIOD
	self.dp_poll_period[dp]['flow']  = DEFAULT_POLL_FLOW_PERIOD

        # Switch descriptions do not change while connected, so just send once
        #self.ctxt.send_desc_stats_request(dp)
           
        # stagger timers by one second
        self.post_callback(self.dp_poll_period[dp]['table'], 
                              lambda : self.table_timer(dp))
        self.post_callback(self.dp_poll_period[dp]['port'] + 0.5, 
                              lambda : self.port_timer(dp))
	self.post_callback(self.dp_poll_period[dp]['aggr'] + 1,
                              lambda : self.aggr_timer(dp))
	self.post_callback(self.dp_poll_period[dp]['flow'] + 1.5,
                              lambda : self.flow_timer(dp))
	self.post_callback(DEFAULT_POLL_FILE_PERIOD,
                              lambda : self.file_timer())

        return CONTINUE 
Example #23
0
    def packet_in_callback(self, dpid, inport, reason, len, bufid, packet):
        """Packet-in handler""" 
        if not packet.parsed:
            log.debug('Ignoring incomplete packet')
        else:
            print 'Packet-in no router', dpid, '--Fonte:', mac_to_str(packet.src), '--Destino:', mac_to_str(packet.dst)
            print 'In-Port:', inport

        if self.im == None:
            self.im = InstallationManager()
            self.im.nox = self
            #self.im.samples_number = 10
            self.im.collect_begin_installs()
            self.install_routes()
            self.im.collect_end_installs()
            self.im.start()

        return CONTINUE
Example #24
0
    def learn_and_forward(self, dpid, inport, packet, buf, bufid):
	logger.info("Learning & Forwarding Packet" + str(packet))

        # Starter psuedocode for learning switch exercise

        if not self.mac_to_port.has_key(dpid):
            self.mac_to_port[dpid] = {}

        #learn the port for the source MAC
	srcaddr = packet.src.tostring()
	if (self.mac_to_port[dpid].has_key(srcaddr)):
	    # If address has already been learned, check if it has moved
	    dst = self.mac_to_port[dpid][srcaddr]
	    if dst[0] != inport:
		logger.info('MAC has moved from ' + str(dst) + 'to' + str(inport))
	else:
	    logger.info('Learned MAC ' + mac_to_str(packet.src) + 'on %d %d' % (dpid, inport))
	    self.mac_to_port[dpid][srcaddr] = (inport, packet)

        #if (destination MAC of the packet is known)
	dstaddr = packet.dst.tostring()
	if (self.mac_to_port[dpid].has_key(dstaddr)):
	    logger.info('Learned Destionation MAC')
	    prt = self.mac_to_port[dpid][dstaddr]

	    #send unicast packet to known output port
	    self.send_openflow(dpid, bufid, buf, prt[0], inport)

	    # push down flow entry
#	    flow = extract_flow(packet)
#	    flow[core.IN_PORT] = inport
#	    actions = [[openflow.OFPAT_OUTPUT, [0, prt[0]]]]
#	    CACHE_TIMEOUT = 5
#	    self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT,
#				       openflow.OFP_FLOW_PERMANENT, actions,
#				       bufid, openflow.OFP_DEFAULT_PRIORITY,
#				       inport, buf)
#
	else:
	    #flood packet out everything but the input port
	    self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
    def host_auth_handler(self, data):
        """ Handler for host_auth_event """
        assert(data is not None)
        try:
            auth_data = data.__dict__
            LOG.info("Received host_auth_ev with the following data: %s" %
                      str(auth_data))
            dladdr      = pkt_utils.mac_to_str(auth_data['dladdr'])
            host_ipaddr = nxw_utils.convert_ipv4_to_str(auth_data['nwaddr'])

            if dladdr in self.hosts:
                LOG.debug("Ignoring auth_event (more notifications for" + \
                          " multiple inter-switch links)")
                return CONTINUE

            r_ = dpid_from_host(auth_data['datapath_id'])
            if not r_: return CONTINUE

            self.hosts[dladdr]          = nxw_utils.Host(dladdr)
            self.hosts[dladdr].rem_dpid = r_
            self.hosts[dladdr].rem_port = auth_data['port']

            if auth_data['nwaddr'] == 0:
                LOG.debug("Received auth_event without IP address...")

            else:
                LOG.debug("Received auth_event with IP address info...")
                self.hosts[dladdr].ip_addr = host_ipaddr
                # post host
                payload = {"ip_addr"     : host_ipaddr,
                           "mac"         : dladdr,
                           "peer_dpid"   : r_,
                           "peer_portno" : auth_data['port']}
                req = requests.post(url=self.url + "pckt_host",
                                    headers=self.hs, data=json.dumps(payload))
                LOG.debug("URL=%s, response(code=%d, content=%s)",
                          req.url, req.status_code, str(req.content))

        except Exception, err:
            LOG.error("Got errors in host_auth_ev handler ('%s')" % str(err))
    def __do_l2_learning(self, dpid, inport, packet):
        """ Layer 2 addresses learning """
        assert(dpid   is not None)
        assert(inport is not None)
        assert(packet is not None)
        # learn MAC on incoming port
        srcaddr = packet.src.tostring()
        if ord(srcaddr[0]) & 1:
            return
        if srcaddr in self.switches[dpid]:
            dst = self.switches[dpid][srcaddr]
            if dst[0] != inport:
                LOG.debug("MAC has moved from '%s' to '%s' " % (str(dst),
                                                                str(inport)))
            else:
                return
        else:
            LOG.debug("Learned MAC '%s' on %d %d " % \
                        (pkt_utils.mac_to_str(packet.src),
                         dpid, inport))

        # learn or update timestamp of entry
        self.switches[dpid][srcaddr] = (inport, time(), packet)
    def datapath_join_handler(self, dpid, stats):
        """ Handler for datapath_join event """
        assert (dpid  is not None)
        assert (stats is not None)

        dpid_ = dpid_from_host(dpid)
        if not dpid_: return CONTINUE

        try:
            ports = []
            for p_info in stats['ports']:
                port = {}
                port['port_no'] = p_info['port_no']
                port['hw_addr'] = pkt_utils.mac_to_str(p_info['hw_addr'])
                port['name'] = p_info['name']
                port['config'] = p_info['config']
                port['state'] = p_info['state']
                port['curr'] = p_info['curr']
                port['advertised'] = p_info['advertised']
                port['supported'] = p_info['supported']
                port['peer'] = p_info['peer']
                ports.append(port)

            payload = {"dpid": dpid_,
                       "region": "packet_" + self.region,
                       "ofp_capabilities": stats['caps'],
                       "ofp_actions": stats['actions'],
                       "buffers": stats['n_bufs'],
                       "tables": stats['n_tables'],
                       "ports": ports}
            req = requests.post(url=self.url + "pckt_dpid", headers=self.hs,
                                data=json.dumps(payload))
            LOG.debug("URL=%s, response(code=%d, content=%s)",
                      req.url, req.status_code, str(req.content))

        except Exception, err:
            LOG.error("Got error in datapath_join handler (%s)" % str(err))
Example #28
0
def do_l2_learning(dpid, inport, packet):
    global inst

    # learn MAC on incoming port
    srcaddr = packet.src.tostring()
    if ord(srcaddr[0]) & 1:
        return
    if inst.st[dpid].has_key(srcaddr):
        dst = inst.st[dpid][srcaddr]
        if dst[0] != inport:
            log.msg('MAC has moved from ' + str(dst) + 'to' + str(inport),
                    system='pyswitch')
        else:
            return
    else:
        log.msg('learned MAC ' + mac_to_str(packet.src) + ' on %d %d' %
                (dpid, inport),
                system="pyswitch")

    # learn or update timestamp of entry
    inst.st[dpid][srcaddr] = (inport, time(), packet)

    # Replace any old entry for (switch,mac).
    mac = mac_to_int(packet.src)
Example #29
0
def do_l2_learning(dpid, inport, packet, buf, bufid):
    global inst 

    # learn MAC on incoming port
    srcaddr = packet.src.tostring()
    if ord(srcaddr[0]) & 1:
        return
    if inst.st[dpid].has_key(srcaddr):
        dst = inst.st[dpid][srcaddr]
        if dst[0] != inport:
            log.msg('MAC has moved from '+str(dst)+'to'+str(inport), system='pyswitch')
        else:
            return
    else:
        log.msg('learned MAC '+mac_to_str(packet.src)+' on %d %d'% (dpid,inport), system="pyswitch")

    # learn or update timestamp of entry
    inst.st[dpid][srcaddr] = (inport, time(), packet)
    # and set-up wildcard flow to this mac address
    flow = {}
    flow[core.DL_DST] = packet.src
    actions = [[openflow.OFPAT_OUTPUT, [0, inport]]]
    inst.install_datapath_flow(dpid, flow, CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, actions,
    None, openflow.OFP_DEFAULT_PRIORITY, inport, None)
Example #30
0
    def packet_in_callback(self, dpid, inport, reason, len, bufid, packet):

        # Install initial setup forwarding rules
	if self.Init == True:
	    self.post_callback(Globals.PORT_STATS_PERIOD, lambda : self.port_timer())
	    self.Init = False

        # Controller Attention
	if reason == openflow.OFPR_ACTION:
	    self.myIPTransition.controllerAction(packet)

	# Incoming ARPs
	elif packet.type == Globals.ARP_TYPE:

	    # Response to our ARP requests 
	    # 1. Record MAC 
	    # 2. Install appropriate IP Forwarding Rule: Change dest VIP to dest Replica i
            if packet.dst == octstr_to_array(Globals.VMAC):
	        foundMacs = True
                for i in range(0, Globals.NUMREPLICAS):
	            if ((packet.next.protosrc == ipstr_to_int(Globals.REPLICAS[i]['ip'])) and (Globals.REPLICAS[i]['mac'] != mac_to_str(packet.src))):
		        Globals.REPLICAS[i]['mac'] = mac_to_str(packet.src)
			Globals.REPLICAS[i]['port'] = inport

			for j, switchJ in enumerate(Globals.SWITCHES):
			    if switchJ['mac'] == dpid:
				switchJ['replicas'].append(Globals.REPLICAS[i]['no'])

		    if (Globals.REPLICAS[i]['mac'] == ''):
		        foundMacs = False

	        if foundMacs == True and self.AllMacsFound == False:
		    Globals.log.info('REPLICAS ' + str(Globals.REPLICAS))
		    Globals.log.info('SWITCHES ' + str(Globals.SWITCHES))
		    Globals.log.info('\n')
		    Globals.log.info('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
		    rulePairList = self.myEvalRules.updateAlphas()
		    self.myIPTransition.installRules(rulePairList)
		    Globals.log.info('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')
		    Globals.log.info('\n')
		    self.AllMacsFound = True

    	    # Requests for VIP respond with ARP Response
   	    elif packet.next.protodst == ipstr_to_int(Globals.VIP):
		srcIP = ip_to_str(packet.next.protosrc)
	
		# IP Rules
		(flow, defaultActions, rewriteActions) = IPs.get_forwarding_srcrule(srcIP, mac_to_str(packet.src), Globals.VMAC, Globals.VIP, inport)
		self.Multipath.install_microflow_flow(flow, openflow.OFP_FLOW_PERMANENT, openflow.OFP_FLOW_PERMANENT, defaultActions, None, openflow.OFP_DEFAULT_PRIORITY, 0, None, dpid, inport, rewriteActions)

	        arpResponse = Arps.create_virtual_arp_response(packet, octstr_to_array(Globals.VMAC), ipstr_to_int(Globals.VIP))
                self.Multipath.send(dpid, None, arpResponse, [[openflow.OFPAT_OUTPUT, [0, inport]]], openflow.OFPP_CONTROLLER)

	    else:
		arpResponse = Arps.create_arp_response(packet)
		self.Multipath.send(dpid, None, arpResponse, [[openflow.OFPAT_OUTPUT, [0, inport]]], openflow.OFPP_CONTROLLER)

        elif packet.type == Globals.IP_TYPE:
	    Globals.log.info("Warning! S1 SHOULD NOT BE RECEIVING IP Traffic!!!")
#	    self.myIPTransition.controllerAction(packet)

        return CONTINUE
Example #31
0
    def lldp_input_handler(self, dp_id, inport, ofp_reason, total_frame_len, buffer_id, packet):

        assert (packet.type == ethernet.LLDP_TYPE)

        if not packet.next:
            lg.error("lldp_input_handler lldp packet could not be parsed")
            return

        assert (isinstance(packet.next, lldp))

        lldph = packet.next
        if  (len(lldph.tlvs) < 4) or \
            (lldph.tlvs[0].type != lldp.CHASSIS_ID_TLV) or\
            (lldph.tlvs[1].type != lldp.PORT_ID_TLV) or\
            (lldph.tlvs[2].type != lldp.TTL_TLV):
            lg.error("lldp_input_handler invalid lldp packet")
            return

        # parse out chassis id
        if lldph.tlvs[0].subtype != chassis_id.SUB_MAC:
            lg.error("lldp chassis ID subtype is not MAC, ignoring")
            return
        assert(len(lldph.tlvs[0].id) == 6)
        cid = lldph.tlvs[0].id

        # convert 48bit cid (in nbo) to longlong
        chassid = cid[5]       | cid[4] << 8  | \
                  cid[3] << 16 | cid[2] << 24 |  \
                  cid[1] << 32 | cid[0] << 40

        # if chassid is from a switch we're not connected to, ignore
        dst_dpid_ = None
        for k_ in self.dps.keys():
            if chassid == (k_ & 0x00ffffff):
                dst_dpid_ = k_
                break

            else:
                for info in self.dps[k_]['ports']:
                    chassid_mac = array_to_octstr(array.array('B',struct.pack('!Q',chassid))[2:])
                    if chassid_mac == mac_to_str(info['hw_addr']):
                        dst_dpid_ = k_
                        break

                if dst_dpid_:
                    break

        if not dst_dpid_:
            lg.debug('Received LLDP packet from unconnected switch')
            return

        chassid = dst_dpid_

        # grab 16bit port ID from port tlv
        if lldph.tlvs[1].subtype != port_id.SUB_PORT:
            return # not one of ours
        if len(lldph.tlvs[1].id) != 2:
            lg.error("invalid lldph port_id format")
            return
        (portid,)  =  struct.unpack("!H", lldph.tlvs[1].id)

        if (dp_id, inport) == (chassid, portid):
            lg.error('Loop detected, received our own LLDP event')
            return

        # print 'LLDP packet in from',longlong_to_octstr(chassid),' port',str(portid)

        #linktuple = (longlong_to_octstr(dp_id), inport, longlong_to_octstr(chassid), portid)
        linktuple = (dp_id, inport, chassid, portid)

        if linktuple not in self.adjacency_list:
            self.add_link(linktuple)
            lg.warn('new link detected ('+longlong_to_octstr(linktuple[0])+' p:'\
                       +str(linktuple[1]) +' -> '+\
                       longlong_to_octstr(linktuple[2])+\
                       ' p:'+str(linktuple[3])+')')


        # add to adjaceny list or update timestamp
        self.adjacency_list[(dp_id, inport, chassid, portid)] = time.time()
    def host_bind_handler(self, data):
        """ Handler for host_binf_event """
        assert(data is not None)
        try:
            bind_data   = data.__dict__
            dladdr      = pkt_utils.mac_to_str(bind_data['dladdr'])
            host_ipaddr = nxw_utils.convert_ipv4_to_str(bind_data['nwaddr'])

            # Check reason value
            reason     = int(bind_data['reason'])
            if not reason in self.__reasons:
                LOG.error("Got host_leave event with unsupported reason value")
                return CONTINUE
            reason_str = self.__reasons[reason]
            LOG.info("Received host_bind_ev with reason '%s'" % reason_str)

            # XXX FIXME: Insert mapping for values <--> reason
            if reason > 7:
                ret = self.__host_leave(dladdr)
                if not ret:
                    return CONTINUE
            elif (reason < 3 or reason == 5) and (bind_data['nwaddr'] == 0):
                LOG.debug("Ignoring host_bind_ev without IPaddr info")
                return CONTINUE
            elif (reason > 2) and (reason != 5):
                LOG.error("Unsupported reason for host_bind_ev: '%s'" % \
                           reason_str)
                return CONTINUE

            LOG.info("Received host_bind_ev with the following data: %s" % \
                      str(bind_data))

            try:
                try:
                    self.db_conn.open_transaction()
                    host_idx = None
                    host_idx = self.db_conn.host_get_index(dladdr)
                    LOG.debug("Host with mac_addr '%s' has index '%s'" % \
                               (str(dladdr), str(host_idx)))
                except Exception, err:
                    LOG.debug("Any host with mac='%s' in DB" % str(dladdr))

                if dladdr in self.hosts:
                    LOG.debug("Got host_bind_ev for an host not present " + \
                              "in DB yet")

                    # Insert Host info into DB
                    self.__host_insert_db(dladdr,
                                          self.hosts[dladdr].rem_dpid,
                                          self.hosts[dladdr].rem_port,
                                          host_ipaddr)
                    LOG.info("Added host '%s' into DB" % str(dladdr))
                    self.hosts.pop(dladdr)
                    # XXX FIXME Remove auth_hosts (maintain only self.hosts)
                    if dladdr in self.auth_hosts:
                        self.auth_hosts.remove(dladdr)

                else:
                    LOG.debug("Got host_bind_ev for an host already " + \
                              "present in DB")
                    LOG.debug("Updating host info in DB...")
                    self.db_conn.host_update(dladdr, host_ipaddr)
                    self.db_conn.commit()
                    LOG.info("Host info updated successfully")
            except nxw_utils.DBException as err:
                LOG.error(str(err))
                self.db_conn.rollback()
            finally:
                self.db_conn.close()


            # check ior-dispatcher on pce node
            if not self.ior_topo and not self.pce_topology_enable():
                LOG.error("Unable to contact ior-dispatcher on PCE node!")
                return CONTINUE

            nodes = [host_ipaddr]
            # Update flow-pce topology (hosts)
            LOG.debug("Hosts=%s", nodes)
            self.fpce.add_node_from_string(host_ipaddr)
            # update flow-pce topology (links between DPID and host)
            try:
                # connect and open transaction
                self.db_conn.open_transaction()
                # Host_insert
                dpid    = self.db_conn.host_get_dpid(dladdr)
                in_port = self.db_conn.host_get_inport(dladdr)
            except nxw_utils.DBException as err:
                LOG.error(str(err))
                self.db_conn.rollback()
            finally:
                self.db_conn.close()

            try:
                node = self.node_get_frompidport(dpid, in_port)
                nodes.append(node)
            except nxw_utils.DBException as err:
                LOG.error(str(err))
            except Exception, err:
                LOG.error(str(err))
    def datapath_join_handler(self, dpid, stats):
        """ Handler for datapath_join event """
        assert (dpid  is not None)
        assert (stats is not None)

        # insert values into topology-db
        try:
            # connect and open transaction
            self.db_conn.open_transaction()

            # datapath_insert
            self.db_conn.datapath_insert(d_id=dpid,
                                         d_name="ofswitch-" + str(dpid),
                                         caps=stats['caps'],
                                         actions=stats['actions'],
                                         buffers=stats['n_bufs'],
                                         tables=stats['n_tables'])
            # port_insert
            for p_info in stats['ports']:
                mac = pkt_utils.mac_to_str(p_info['hw_addr'])
                self.db_conn.port_insert(d_id=dpid,
                                         port_no=p_info['port_no'],
                                         hw_addr=mac,
                                         name=p_info['name'],
                                         config=p_info['config'],
                                         state=p_info['state'],
                                         curr=p_info['curr'],
                                         advertised=p_info['advertised'],
                                         supported=p_info['supported'],
                                         peer=p_info['peer'])
            # commit transaction
            self.db_conn.commit()
            LOG.debug("Successfull committed information!")

        except nxw_utils.DBException as err:
            LOG.error(str(err))
            # rollback transaction
            self.db_conn.rollback()

        finally:
            self.db_conn.close()

        self.post_callback(5, lambda : self.table_timer(dpid))
        self.post_callback(5, lambda : self.port_timer(dpid))

        # check ior-dispatcher on pce node
        if not self.ior_topo and not self.pce_topology_enable():
            LOG.error("Unable to contact ior-dispatcher on PCE node!")
            return CONTINUE

        # get datapath and ports index from topology-db
        nodes = []
        try:
            for p_info in stats['ports']:
                node = self.node_get_frompidport(dpid, p_info['port_no'])
                nodes.append(node)

        except nxw_utils.DBException as err:
            LOG.error(str(err))

        except Exception, err:
            LOG.error(str(err))
Example #34
0
    def learn_and_forward(self, dpid, inport, packet, buf, bufid):
	# Flood

	# Find MAC + IP from header
	srcMACaddr = packet.src.tostring()
	ippkt = self.get_ippacket(packet)
	srcIPaddr = '0.0.0.0'
	if (ippkt != None):
	    srcIPaddr = ip_to_str(ippkt.srcip)

	# Does the source MAC + IP need to be learned?
	if (self.mac_to_port.has_key(srcMACaddr)):
	    dstMACaddr = self.mac_to_port[srcMACaddr]
	    if dstMACaddr[0] != inport:
		logger.info('MAC moved from ' + str(dst) + ' to ' + str(inport))
	    elif (dstMACaddr[1] == '0.0.0.0') and (srcIPaddr != None):
		logger.info('IP update')
		self.mac_to_port[srcMACaddr] = (inport, srcIPaddr)
	# If not, update table entry
        else:
	    logger.info('MAC learned ' + mac_to_str(packet.src) + ' on %d %d' % (dpid, inport))
  	    self.mac_to_port[srcMACaddr] = (inport, srcIPaddr)

	# Have we already learned destination MAC + IP?
	dstMACaddr = packet.dst.tostring()
	dstIPaddr = None
	if (ippkt != None):
	    dstIPaddr = ip_to_str(ippkt.dstip)

	logger.info('Sending to destination')

        # Is this server address?
	if ((dstIPaddr != None) and (dstIPaddr == "10.0.0.0")):
	    logger.info('SPECIAL FORWARDING IP\n')
	    for item in self.mac_to_port.items():
		logger.info(str(item) + "\n")
		if (item[1] == "10.0.0.2"):
		    logger.info('Found 10.0.0.2 and sending packet\n');
		    self.send_openflow(dpid, bufid, buf, item[0], inport)
	    	#prt = self.mac_to_port[dstMACaddr] # CHANGE
	    	#self.send_openflow(dpid, bufid, buf, prt[0] ,inport)

	# HARDCODED
	if (isinstance(packet.next, arp.arp) and (ip_to_str(packet.next.protodst) ==  "10.0.0.0")):
            logger.info('SPECIAL FORWARDING ARP\n')
            for item in self.mac_to_port.items():
                logger.info(str(item) + ": " + str(item[1][1]) + "\n")
                if (str(item[1][1]) == '10.0.0.2'):
                    logger.info('Found 10.0.0.2 and sending packet\n');
                    #self.send_openflow(dpid, bufid, buf, item[1][0], inport)

            	    # Install Flow Rule
                    #flow = extract_flow(packet)
                    #flow[core.IN_PORT] = inport
		    #flow = {}
		    #flow[DL_TYPE] = 0x0800
		    #flow[NW_PROTO] = 17
		    #flow[NW_DST] = ippkt.srcip
		    #flow[NW_DST_N_WILD] = 31

                    #actions = [[openflow.OFPAT_OUTPUT, [0, item[1][0]]]]
                    #CACHE_TIMEOUT = 100
                    #self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT,
                    #                   openflow.OFP_FLOW_PERMANENT, actions,
                    #                   bufid, openflow.OFP_DEFAULT_PRIORITY,
                    #                   inport, buf)




	# Otherwise forward appropriately
	elif (self.mac_to_port.has_key(dstMACaddr)):
	    prt = self.mac_to_port[dstMACaddr]
	    #self.send_openflow(dpid, bufid, buf, prt[0] ,inport)

	# If we have not then flood
	else:
	    self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)

            # Install Flow Rule
            #flow = extract_flow(packet)
            #flow[core.IN_PORT] = inport
            flow = {}
            #flow[DL_TYPE] = 0x0800
            #flow[NW_PROTO] = 17
            #flow[NW_DST] = 
            flow[NW_DST_N_WILD] = 32

            actions = [[openflow.OFPAT_OUTPUT, [0, 1]]]
            CACHE_TIMEOUT = 100
            self.install_datapath_flow(dpid, flow, CACHE_TIMEOUT,
                                       openflow.OFP_FLOW_PERMANENT, actions,
                                       bufid, openflow.OFP_DEFAULT_PRIORITY,
                                       inport, buf)
Example #35
0
 def l2_learning (self, dpid, inport, packet) :
     self.fdb.update (dpid, mac_to_str (packet.src), inport)
     return