from pox.core import core import pox.openflow.libopenflow_01 as of import re import datetime from sqlalchemy import create_engine, ForeignKey from sqlalchemy import Column, Date, Integer, String from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, backref from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.sql.expression import exists log = core.getLogger() engine = create_engine('sqlite:///nwtopology.db', echo=False) Base = declarative_base() Session = sessionmaker(bind=engine) session = Session() ######################################################################## class SourcetoPort(Base): """""" __tablename__ = 'source_to_port' id = Column(Integer, primary_key=True) port_no = Column(Integer) src_address = Column(String,index=True) #---------------------------------------------------------------------- def __init__(self, src_address,port_no): """""" self.src_address = src_address self.port_no = port_no ######################################################################## #create tables Base.metadata.create_all(engine) class Tutorial (object): def __init__ (self, connection): self.connection = connection connection.addListeners(self) # Use this table to keep track of which ethernet address is on # which switch port (keys are MACs, values are ports). self.mac_to_port = {} self.matrix={} #This will keep track of the traffic matrix. #matrix[i][j]=number of times a packet from i went to j def send_packet (self, buffer_id, raw_data, out_port, in_port): #print "calling send_packet" #Sends a packet out of the specified switch port. msg = of.ofp_packet_out() msg.in_port = in_port msg.data = raw_data # Add an action to send to the specified port action = of.ofp_action_output(port = out_port) msg.actions.append(action) # Send message to switch self.connection.send(msg) def act_like_hub (self, packet, packet_in): #flood packet on all ports self.send_packet(packet_in.buffer_id, packet_in.data, of.OFPP_FLOOD, packet_in.in_port) def act_like_switch (self, packet, packet_in): """ Implement switch-like behavior. """ # Learn the port for the source MAC #print "RECIEVED FROM PORT ",packet_in.in_port , "SOURCE ",packet.src # create a Session #Session = sessionmaker(bind=engine) #session = Session() self.mac_to_port[packet.src]=packet_in.in_port #if self.mac_to_port.get(packet.dst)!=None: #print "count for dst",session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).count(),str(packet.dst) #if session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).count(): if session.query(exists().where(SourcetoPort.src_address == str(packet.dst))).scalar() is not None: #send this packet print "got info from the database" q_res = session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).one() self.send_packet(packet_in.buffer_id, packet_in.data,q_res.port_no, packet_in.in_port) #create a flow modification message msg = of.ofp_flow_mod() #set the fields to match from the incoming packet msg.match = of.ofp_match.from_packet(packet) #send the rule to the switch so that it does not query the controller again. msg.actions.append(of.ofp_action_output(port=q_res.port_no)) #push the rule self.connection.send(msg) else: #flood this packet out as we don't know about this node. print "flooding the first packet" self.send_packet(packet_in.buffer_id, packet_in.data, of.OFPP_FLOOD, packet_in.in_port) #self.matrix[(packet.src,packet.dst)]+=1 entry = SourcetoPort(src_address=str(packet.src) , port_no=packet_in.in_port) #add the record to the session object session.add(entry) #add the record to the session object session.commit() def _handle_PacketIn (self, event): """ Handles packet in messages from the switch. """ packet = event.parsed # This is the parsed packet data. if not packet.parsed: log.warning("Ignoring incomplete packet") return packet_in = event.ofp # The actual ofp_packet_in message. #self.act_like_hub(packet, packet_in) self.act_like_switch(packet, packet_in) def launch (): """ Starts the component """ def start_switch (event): log.debug("Controlling %s" % (event.connection,)) Tutorial(event.connection) core.openflow.addListenerByName("ConnectionUp", start_switch)
When I run the above code I get the following error: The problem that I am facing is for some reason if I use if session.query(exists().where(SourcetoPort.src_address == str(packet.dst))).scalar() is not None: in place of count query. #if session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).count(): The querying from the database q_res = session.query(SourcetoPort).filter_by(src_address=str(packet.dst)).first() self.send_packet(packet_in.buffer_id, packet_in.data,q_res.port_no, packet_in.in_port) is giving the following error: DEBUG:core:POX 0.1.0 (betta) going up... DEBUG:core:Running on CPython (2.7.3/Aug 1 2012 05:14:39) DEBUG:core:Platform is Linux-3.5.0-23-generic-x86_64-with-Ubuntu-12.04-precise INFO:core:POX 0.1.0 (betta) is up. DEBUG:openflow.of_01:Listening on 0.0.0.0:6633 INFO:openflow.of_01:[00-00-00-00-00-02 1] connected DEBUG:tutorial:Controlling [00-00-00-00-00-02 1] got info from the database ERROR:core:Exception while handling Connection!PacketIn... Traceback (most recent call last): File "/home/karthik/pox/pox/lib/revent/revent.py", line 234, in raiseEventNoErrors return self.raiseEvent(event, *args, **kw) File "/home/karthik/pox/pox/lib/revent/revent.py", line 281, in raiseEvent rv = event._invoke(handler, *args, **kw) File "/home/karthik/pox/pox/lib/revent/revent.py", line 159, in _invoke return handler(self, *args, **kw) File "/home/karthik/pox/tutorial.py", line 118, in _handle_PacketIn self.act_like_switch(packet, packet_in) File "/home/karthik/pox/tutorial.py", line 86, in act_like_switch self.send_packet(packet_in.buffer_id, packet_in.data,q_res.port_no, packet_in.in_port) AttributeError: 'NoneType' object has no attribute 'port_no' got info from the database ERROR:core:Exception while handling Connection!PacketIn... -- http://mail.python.org/mailman/listinfo/python-list