ofproto: Move rule_execute() out of ofopgroup_complete().
authorBen Pfaff <blp@nicira.com>
Thu, 12 Sep 2013 07:25:28 +0000 (00:25 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 13 Sep 2013 04:19:53 +0000 (21:19 -0700)
commit8fa060283120fc128b1c5e455a4491246ffa2a2d
treeb07c9f9cd7741f0300ee06b426e07575d947272a
parent5cd864b705bd5099a8bca3bfa39d70d7ce873a9a
ofproto: Move rule_execute() out of ofopgroup_complete().

One goal we're moving toward is to be able to execute "learn" actions
in each thread that handles packets that arrive on an interface just before
we forward those packets.  The planned strategy there is to have a global
lock that protects everything required to modify the flow table.  Generally
this works out well, but rule_execute() is a trouble spot.  That's because
it's called during a flow table modification (when that global lock is
held) which means that a "learn" action triggered by the executing the
packet would try to recursively modify the flow table and reacquire the
global lock.

I can see two ways out of this issue.  One would be to make the global lock
a recursive one, or otherwise deal with handling recursive flow_mods.  The
other is to just queue up flow_mods due to rule_execute(), which itself is
a corner case (it only happens when a flow_mod sent via OpenFlow includes
a buffer_id).  (I guess there could be other more radical solutions, like
just dropping packets that contain "learn" actions if they occur in this
situation.)

This commit implements the second solution because it seems less likely to
be wrong in a way that crashes the switch.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
ofproto/ofproto-provider.h
ofproto/ofproto.c