It’s not too surprising that the code doesn’t work. Among other things, I
think it’s from Ryu and not POX.
I mentioned this before, but with some additional detail, you need to do the
following three things:
1. Write a handler for flow removed messages. It might be a method in which
case it’ll have a "self" parameter, or vary in other ways, but it might look
something more or less like:
def _handle_FlowRemoved (event):
if not event.idleTimeout: return # Only care about idle timeouts
print "entry for %s -> %s removed" % (event.match.dl_src, event.match.dl_dst)
2. Listen to the FlowRemoved event. There are several ways to do this; the
best one may depend on other aspects of your code. You could listen to the
event for all switches (core.openflow), or from a specific connection. But it
might look something like:
core.openflow.addListenerByName("FlowRemoved", _handle_FlowRemoved)
3. When you create a table entry, set the flag so that the switch sends a flow
removed message. This might look something like:
fm = of.ofp_flow_mod()
…
fm.flags = of.OFPFF_SEND_FLOW_REM
…
connection.send(fm)
Some recommended reading from the manual:
The Event System (introduction)
Handling Events
OpenFlow in POX (introduction)
OpenFlow Events
Hope that helps.
-- Murphy
On Nov 27, 2013, at 11:07 AM, Sayed Qaiser Ali Shah <[email protected]>
wrote:
> I used code below for flow removed handling. I got it from internet
>
> def flow_removed_handler(self, ev):
> msg = ev.msg
> print msg
> dp = msg.datapath
> ofp = dp.ofproto
> if msg.reason == ofp.OFPRR_IDLE_TIMEOUT:
> reason = 'IDLE TIMEOUT'
> elif msg.reason == ofp.OFPRR_HARD_TIMEOUT:
> reason = 'HARD TIMEOUT'
> elif msg.reason == ofp.OFPRR_DELETE:
> reason = 'DELETE'
> else:
> reason = 'unknown'
> self.logger.info('OFPFlowRemoved received: '
> 'match=%s cookie=%d priority=%d reason=%s '
> 'duration_sec=%d duration_nsec=%d '
> 'idle_timeout=%d packet_count=%d byte_count=%d',
> msg.match, msg.cookie, msg.priority, reason,
> msg.duration_sec, msg.duration_nsec,
> msg.idle_timeout, msg.packet_count, msg.byte_count)
>
>
> The code I used didn't work. How to make the code functional. I know it is
> not listening to flow removed message. How to make it enable so that it can
> listen flow removed message.
>
>
>
> On Wed, Nov 27, 2013 at 4:45 PM, Sayed Qaiser Ali Shah
> <[email protected]> wrote:
> Yup dear thank you so much. I will try this.
> :)
>
>
> On Wed, Nov 27, 2013 at 4:49 AM, Murphy McCauley <[email protected]>
> wrote:
> On Nov 26, 2013, at 12:26 PM, Sayed Qaiser Ali Shah
> <[email protected]> wrote:
>
> > Dear Murphy I tried a lot but I am unable to use the flag properly. Kindly
> > help me out in the scenario. I want to remove all entries from dictionary
> > defined after idle_time_out. The pseudocode is as below.
> > msg.idle_timeout = 10
> > if msg.idle_timeout== True:
> > self.macaddrtable=' '
>
> This isn't the right logic. You tell the switch you want a flow to expire if
> it has timed out. Only the switch knows when this has happened. If you want
> to find out at the controller, you need to switch to tell you.
>
> So when you install the flow entry with an idle_timeout, set the flow-mod's
> .flag attribute to OFPFF_SEND_FLOW_REM.
>
> Additionally, set a handler for the OpenFlow componet's FlowRemoved event.
>
> When the FlowRemoved handler is executed, it's because a flow has been
> removed.
>
> See the POX manual for more info on the FlowRemoved event and setting event
> handlers.
>
> As a last note, you probably want to do self.macaddrtable.clear() or
> something rather than assigning it to be an empty string?
>
> Hope that gets you started.
>
> -- Murphy
>
> > Kindly help me out because I am unable to do this.
> >
> >
> > On Sun, Nov 24, 2013 at 2:50 AM, Murphy McCauley
> > <[email protected]> wrote:
> > Like the rest of OpenFlow, it's described in the OpenFlow specification:
> > http://archive.openflow.org/documents/openflow-spec-v1.0.0.pdf
> >
> > Also, if you google "OFPFF_SEND_FLOW_REM pox" you should get several
> > examples of setting the flag.
> >
> > In the POX wiki manual, there is some description of the FlowRemoved event
> > and of handling events in general.
> >
> >
> > -- Murphy
> >
> > On Nov 23, 2013, at 10:51 AM, Sayed Qaiser Ali Shah
> > <[email protected]> wrote:
> >
> >> I tried to used OFPFF_SEND_FLOW_REM flag and also searched on net but
> >> didn't get any specific answer. Please tell me how to use this flag? or
> >> give me a link from which I can get help.
> >> Thanks
> >>
> >>
> >> On Sat, Nov 23, 2013 at 7:28 PM, Sayed Qaiser Ali Shah
> >> <[email protected]> wrote:
> >> I think so. I want to delete entry from dictionary defined on controller.
> >> Thanks. I will try this.
> >>
> >>
> >> On Sat, Nov 23, 2013 at 11:04 AM, Murphy McCauley
> >> <[email protected]> wrote:
> >>
> >> On Nov 22, 2013, at 12:57 PM, Sayed Qaiser Ali Shah
> >> <[email protected]> wrote:
> >>
> >>> Hello Murphy McCauley,
> >>>
> >>> I solved the duplication problem now I want to refresh the dictionary I
> >>> have defined after an idle_timeout. I want to set idle_timeout to 10. I
> >>> tried this but didn't get what I wanted.
> >>>
> >>> msg.idle_timeout = 10
> >>> if msg.idle_timeout== True:
> >>> self.macaddrtable=' '
> >>>
> >>> This will destroy all entries in dictionary. Is there any other way so
> >>> that only that entry whose idle_timeout has expired is removed and then
> >>> rearrange remaining entries in dictionary.
> >>> Just as a reminder. macaddrtable is dictionary defined which contains
> >>> source and destination mac addresses. When a packet arrives controller
> >>> its entry is saved in the dictionary macaddrtable.
> >>
> >> If you set the OFPFF_SEND_FLOW_REM flag when installing the table entry,
> >> you'll get a FlowRemoved event when it expires. Maybe that's what you
> >> need?
> >>
> >> -- Murphy
> >>
> >>> On Fri, Nov 15, 2013 at 6:05 PM, Sayed Qaiser Ali Shah
> >>> <[email protected]> wrote:
> >>> Ok thank you I will check it out.
> >>>
> >>>
> >>> On Fri, Nov 15, 2013 at 5:54 PM, Murphy McCauley
> >>> <[email protected]> wrote:
> >>> I'm just suggesting you work backwards to find the problem. Use
> >>> Wireshark to monitor the traffic to help determine where the duplicates
> >>> are coming from. If they're coming from a switch, I suggest you inspect
> >>> the table on that switch to see which table entry the switch. Then
> >>> analyze the OpenFlow traffic to that switch to find the OpenFlow messages
> >>> which installed the problematic entries. Then analyze your controller
> >>> code to see where you sent those problematic entries.
> >>> -- Murphy
> >>>
> >>>
> >>> On Nov 15, 2013, at 4:49 AM, Sayed Qaiser Ali Shah
> >>> <[email protected]> wrote:
> >>>
> >>>> Thank you so much. Yes you are right about what you said but is there is
> >>>> any other way, so that I can do this. I can read individual entries
> >>>> statically but the problem is I want to get it dynamic.
> >>>> Like I can print individual entries by using:
> >>>>
> >>>> print self.macaddrtable[1]
> >>>> print self.macaddrtable[2]
> >>>> print self.macaddrtable[3]
> >>>> print self.macaddrtable[4]
> >>>>
> >>>> To get desired result dynamically I used loop. But you know what I got.
> >>>> :(
> >>>>
> >>>>
> >>>> On Fri, Nov 15, 2013 at 3:36 PM, Murphy McCauley
> >>>> <[email protected]> wrote:
> >>>>
> >>>> On Nov 15, 2013, at 2:20 AM, Sayed Qaiser Ali Shah
> >>>> <[email protected]> wrote:
> >>>>
> >>>>> Hello Murphy actually I am working on Traffic Engineering. I am now
> >>>>> learning that how to forward traffic when we have dictionary on
> >>>>> controller. I want to forward some entries of dictionary via queue-1
> >>>>> and some entries via queue-2. For this I have created dictionary and it
> >>>>> created successfully with you help. Those entries of dictionary contain
> >>>>> Source Mac Address and Destination Mac address. I created 2 queues on
> >>>>> Interface 1 of switch. I then Pinged host 2 from host 1 and host 1 from
> >>>>> host 3. It inserted four entries in dictionary created on controller.
> >>>>> Entries in Dictionary are
> >>>>> {1: (EthAddr('00:00:00:00:00:02'), EthAddr('00:00:00:00:00:01')),
> >>>>> 2: (EthAddr('00:00:00:00:00:01'), EthAddr('00:00:00:00:00:02')),
> >>>>> 3: (EthAddr('00:00:00:00:00:01'), EthAddr('00:00:00:00:00:03')),
> >>>>> 4: (EthAddr('00:00:00:00:00:03'), EthAddr('00:00:00:00:00:01')) }
> >>>>> Dear Murphy you asked earlier that you didn't get what I wanted to do.
> >>>>> I think that I am just explaining it in easy way that I just want to
> >>>>> forward two entries of dictionary via queue-1 and other 2 entries of
> >>>>> dictionary via queue-2. I am just doing practice on different
> >>>>> techniques of Traffic Engineering. I used the following code for
> >>>>> forwarding traffic via queues:
> >>>>>
> >>>>> if self.macaddrtable=='': //When we have no entry in macaddrtable
> >>>>> dictionary
> >>>>> queue=1
> >>>>> msg.actions.append(of.ofp_action_enqueue(port = port, queue_id
> >>>>> = queue))
> >>>>> else:
> >>>>> for a in self.macaddrtable:
> >>>>> if a<=2:
> >>>>> queue=1
> >>>>> msg.actions.append(of.ofp_action_enqueue(port = port,
> >>>>> queue_id = queue))
> >>>>> elif a>2:
> >>>>> queue=2
> >>>>> msg.actions.append(of.ofp_action_enqueue(port = port,
> >>>>> queue_id = queue))
> >>>>>
> >>>>> The code worked fine and forwarded traffic via desired queues but after
> >>>>> about 10 seconds of pinging, duplicate packets were detected. I don't
> >>>>> know why duplicate packets were detected. Can you please tell the
> >>>>> reason?
> >>>>
> >>>> My best guesses are that you are somehow creating a flow entry with
> >>>> multiple actions or a loop, but it's hard to say. I'd suggest that you
> >>>> try to use Wireshark or a similar tool to figure out where the
> >>>> duplicates are coming from. You should see the duplicates at the port
> >>>> of the destination host and the egress port of the last switch. Work
> >>>> backwards from there. If you find the source of the duplications is a
> >>>> switch, examine the flow table of that switch and see if you can spot
> >>>> the reason.
> >>>>
> >>>> -- Murphy
> >>>>
> >>>>> On Tue, Nov 12, 2013 at 2:00 AM, Murphy McCauley
> >>>>> <[email protected]> wrote:
> >>>>> It's still hard for me to answer questions since I still don't know
> >>>>> what you're really trying to accomplish here.
> >>>>>
> >>>>> If you want entries to time out on the switch, set timeouts when
> >>>>> installing the table entry (sending the flow_mod). If you want
> >>>>> notifications when flows are removed on the switch, that's also an
> >>>>> option you can set when installing the entry; then listen to the
> >>>>> FlowRemoved event to tell when it has actually happened.
> >>>>>
> >>>>> I'm not sure what you mean by "exact mac". Your code records the
> >>>>> address the packets were sent to. If they were sent to the broadcast
> >>>>> address, then... that's the destination.
> >>>>>
> >>>>> -- Murphy
> >>>>>
> >>>>> On Nov 11, 2013, at 9:42 AM, Sayed Qaiser Ali Shah
> >>>>> <[email protected]> wrote:
> >>>>>
> >>>>>> Thank you so much Murphy for your help. I did it the way you
> >>>>>> explained. But how can I refresh entries in the table. i.e. how to set
> >>>>>> idle timeout and hard timeout for this so that the table can be
> >>>>>> refreshed or how the entries can be updated when a flow is removed
> >>>>>> from flow table on Switch.
> >>>>>> Another Problem is:
> >>>>>> The code is as below.
> >>>>>>
> >>>>>> if (packet.src,packet.dst) not in self.macaddrs and
> >>>>>> (packet.dst,packet.src) not in self.macaddrs:
> >>>>>> self.macaddrs.add((packet.src,packet.dst))
> >>>>>> self.macaddrtable[f_id]=(packet.src,packet.dst)
> >>>>>> f_id=f_id+1
> >>>>>> print "Mac Table is "
> >>>>>> print self.macaddrtable
> >>>>>>
> >>>>>> When I created a topology with 3 hosts the following result was shown
> >>>>>>
> >>>>>> Mac Table is
> >>>>>> {1: (EthAddr('00:00:00:00:00:01'), EthAddr('ff:ff:ff:ff:ff:ff')), 2:
> >>>>>> (EthAddr('00:00:00:00:00:02'), EthAddr('00:00:00:00:00:01')), 3:
> >>>>>> (EthAddr('00:00:00:00:00:03'), EthAddr('00:00:00:00:00:01')), 4:
> >>>>>> (EthAddr('00:00:00:00:00:02'), EthAddr('ff:ff:ff:ff:ff:ff')), 5:
> >>>>>> (EthAddr('00:00:00:00:00:03'), EthAddr('00:00:00:00:00:02'))}
> >>>>>>
> >>>>>> The result I expected is little bit different in terms of broadcast
> >>>>>> address. Like in 1 destination mac is ff:ff:ff:ff:ff:ff but I was
> >>>>>> expecting 00:00:00:00:00:02 and similar is the case with some other
> >>>>>> entries as well.
> >>>>>> Is there any way so that I can get desired exact mac, not broadcast?
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On Sun, Nov 10, 2013 at 5:00 AM, Murphy McCauley
> >>>>>> <[email protected]> wrote:
> >>>>>> It sounds like you need to record them as a pair to get what you want,
> >>>>>> so ... put them in as a pair.
> >>>>>>
> >>>>>> It looks like I may have been responsible for the problem you were
> >>>>>> seeing -- a little typo inserted an errant right square bracket. Try:
> >>>>>> self.macaddrs.add((packet.src,packet.dst))
> >>>>>>
> >>>>>> It's still not clear from context whether ordering matters to you (is
> >>>>>> A sending to B the same as B sending to A?). If it isn't, you might
> >>>>>> want to sort the two addresses or just check for both...
> >>>>>>
> >>>>>> if (packet.src,packet.dst) not in self.macaddrs and
> >>>>>> (packet.dst,packet.src) not in self.macaddrs:
> >>>>>>
> >>>>>> -- Murphy
> >>>>>>
> >>>>>> On Nov 9, 2013, at 3:32 PM, Sayed Qaiser Ali Shah
> >>>>>> <[email protected]> wrote:
> >>>>>>
> >>>>>>> Thank you so much Murphy. I tried it but got little problem in add
> >>>>>>> function i.e. when I used
> >>>>>>> self.macaddrs.add((packet.src,packet.dst])) it generated error in
> >>>>>>> this function then I tried
> >>>>>>> self.macaddrs.add(packet.src,packet.dst)
> >>>>>>> It also generated an error that add must have 1 argument where as 2
> >>>>>>> given. Then I tried
> >>>>>>>
> >>>>>>> if (packet.src,packet.dst) not in self.macaddrs:
> >>>>>>> self.macaddrs.add(packet.src)
> >>>>>>> self.macaddrs.add(packet.dst)
> >>>>>>> self.macaddrtable[f_id]=(packet.src,packet.dst)
> >>>>>>> f_id=f_id+1
> >>>>>>>
> >>>>>>> It didn't generate an error and I didn't get any repeated result but
> >>>>>>> there was some problem in the code I got results as below.
> >>>>>>> When I ping host1 from host 2 it added record in dictionary. Then I
> >>>>>>> ping host 3 from h1 record was inserted again but the problem was, as
> >>>>>>> record of host 1, host 2 and host 3 was saved in macaddrs and two
> >>>>>>> records were there but when I pinged the hosts present in macaddrs
> >>>>>>> i.e. 1, 2, 3 like I ping host 2 from h3 as record was not present in
> >>>>>>> macaddrtable still record was not added to dictionary. It is because
> >>>>>>> addresses are saving in macaddrs one by one individually i.e. first
> >>>>>>> source and then destination address. When packet arrives controller
> >>>>>>> it checks for source and destination address in macaddrs as when
> >>>>>>> there are individual record of each host it then doesn't execute IF
> >>>>>>> body because source and destination addresses are already there as
> >>>>>>> individual address. What to do with this???? Kindly help.
> >>>>>>>
> >>>>>>>
> >>>>>>> On Sun, Nov 10, 2013 at 3:26 AM, Murphy McCauley
> >>>>>>> <[email protected]> wrote:
> >>>>>>> One possible answer is that you should keep a set of the ones you've
> >>>>>>> added so far...
> >>>>>>> self.macaddrtable = {}
> >>>>>>> self.macaddrs = set()
> >>>>>>>
> >>>>>>> ...
> >>>>>>>
> >>>>>>> if (packet.src,packet.dst) not in self.macaddrs:
> >>>>>>> self.macaddrs.add((packet.src,packet.dst]))
> >>>>>>> self.macaddrtable[f_id]=(packet.src,packet.dst)
> >>>>>>> f_id=f_id+1
> >>>>>>>
> >>>>>>>
> >>>>>>> There might be better things to be done, but it's impossible to say
> >>>>>>> without knowing more (e.g., what you're trying to accomplish, what
> >>>>>>> f_id is used for, etc.).
> >>>>>>>
> >>>>>>> -- Murphy
> >>>>>>>
> >>>>>>> On Nov 9, 2013, at 10:35 AM, Sayed Qaiser Ali Shah
> >>>>>>> <[email protected]> wrote:
> >>>>>>>
> >>>>>>> > Hello everybody,
> >>>>>>> >
> >>>>>>> > I have defined dictionary in POX controller and I by the name
> >>>>>>> > addrtable and I am saving two things in this dictionary i.e. Source
> >>>>>>> > mac and destination mac. What I have done is
> >>>>>>> >
> >>>>>>> > self.macaddrtable = {}
> >>>>>>> > ...
> >>>>>>> > f_id=1
> >>>>>>> > self.macaddrtable[f_id]={packet.src, packet.dst}
> >>>>>>> > print self.macaddrtable
> >>>>>>> > f_id=f_id+1
> >>>>>>> >
> >>>>>>> > It is saving source mac and destination mac in the dictionary but
> >>>>>>> > the problem is when f_id increases it then save same source and
> >>>>>>> > destination mac again and again.
> >>>>>>> > What I want is to save mac address only if its not in dictionary.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> --
> >>>>>>> Regards
> >>>>>>>
> >>>>>>> Sayed Qaiser Ali Shah
> >>>>>>> MSIT-12
> >>>>>>> NUST (SEECS)
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> --
> >>>>>> Regards
> >>>>>>
> >>>>>> Sayed Qaiser Ali Shah
> >>>>>> MSIT-12
> >>>>>> NUST (SEECS)
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> --
> >>>>> Regards
> >>>>>
> >>>>> Sayed Qaiser Ali Shah
> >>>>> MSIT-12
> >>>>> NUST (SEECS)
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> --
> >>>> Regards
> >>>>
> >>>> Sayed Qaiser Ali Shah
> >>>> MSIT-12
> >>>> NUST (SEECS)
> >>>
> >>>
> >>>
> >>>
> >>> --
> >>> Regards
> >>>
> >>> Sayed Qaiser Ali Shah
> >>> MSIT-12
> >>> NUST (SEECS)
> >>>
> >>>
> >>>
> >>> --
> >>> Regards
> >>>
> >>> Sayed Qaiser Ali Shah
> >>> MSIT-12
> >>> NUST (SEECS)
> >>
> >>
> >>
> >>
> >> --
> >> Regards
> >>
> >> Sayed Qaiser Ali Shah
> >> MSIT-12
> >> NUST (SEECS)
> >>
> >>
> >>
> >> --
> >> Regards
> >>
> >> Sayed Qaiser Ali Shah
> >> MSIT-12
> >> NUST (SEECS)
> >
> >
> >
> >
> > --
> > Regards
> >
> > Sayed Qaiser Ali Shah
> > MSIT-12
> > NUST (SEECS)
>
>
>
>
> --
> Regards
>
> Sayed Qaiser Ali Shah
> MSIT-12
> NUST (SEECS)
>
>
>
> --
> Regards
>
> Sayed Qaiser Ali Shah
> MSIT-12
> NUST (SEECS)