Thanks for catching this, I’m not sure if I was aware of resubmit to the current table feature when I wrote that.
Acked-by: Jarno Rajahalme <ja...@ovn.org> > On Jan 22, 2016, at 3:59 PM, Ben Pfaff <b...@ovn.org> wrote: > > When recirculation defers actions for processing later, it decides > based on the actions being saved whether it needs to record the table > and cookie from which they originated. Until now, it was thought that > this was only important for actions that send packets to the controller > (because those actions send the table ID and cookie). This overlooked > a special case of the "resubmit" action which also depends on the > current table ID, which meant that this special case malfunctioned if > it came after recirculation. This commit fixes the problem, and adds > a test. > > Found while testing another feature under development. > > Signed-off-by: Ben Pfaff <b...@ovn.org> > --- > ofproto/ofproto-dpif-xlate.c | 21 ++++++++++++++------- > tests/ofproto-dpif.at | 25 +++++++++++++++++++++++++ > 2 files changed, 39 insertions(+), 7 deletions(-) > > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c > index 6549191..4b25bf4 100644 > --- a/ofproto/ofproto-dpif-xlate.c > +++ b/ofproto/ofproto-dpif-xlate.c > @@ -4165,8 +4165,7 @@ recirc_put_unroll_xlate(struct xlate_ctx *ctx) > > /* Copy remaining actions to the action_set to be executed after > recirculation. > * UNROLL_XLATE action is inserted, if not already done so, before actions > that > - * may generate asynchronous messages from the current table and without > - * matching another rule. */ > + * may depend on the current table ID or flow cookie. */ > static void > recirc_unroll_actions(const struct ofpact *ofpacts, size_t ofpacts_len, > struct xlate_ctx *ctx) > @@ -4175,17 +4174,25 @@ recirc_unroll_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { > switch (a->type) { > - /* May generate asynchronous messages. */ > case OFPACT_OUTPUT_REG: > case OFPACT_GROUP: > case OFPACT_OUTPUT: > case OFPACT_CONTROLLER: > case OFPACT_DEC_MPLS_TTL: > case OFPACT_DEC_TTL: > + /* These actions may generate asynchronous messages, which > include > + * table ID and flow cookie information. */ > recirc_put_unroll_xlate(ctx); > break; > > - /* These may not generate PACKET INs. */ > + case OFPACT_RESUBMIT: > + if (ofpact_get_RESUBMIT(a)->table_id == 0xff) { > + /* This resubmit action is relative to the current table, so > we > + * need to track what table that is.*/ > + recirc_put_unroll_xlate(ctx); > + } > + break; > + > case OFPACT_SET_TUNNEL: > case OFPACT_REG_MOVE: > case OFPACT_SET_FIELD: > @@ -4193,8 +4200,7 @@ recirc_unroll_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > case OFPACT_STACK_POP: > case OFPACT_LEARN: > case OFPACT_WRITE_METADATA: > - case OFPACT_RESUBMIT: /* May indirectly generate PACKET INs, > */ > - case OFPACT_GOTO_TABLE: /* but from a different table and rule. > */ > + case OFPACT_GOTO_TABLE: > case OFPACT_ENQUEUE: > case OFPACT_SET_VLAN_VID: > case OFPACT_SET_VLAN_PCP: > @@ -4228,11 +4234,12 @@ recirc_unroll_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > case OFPACT_DEBUG_RECIRC: > case OFPACT_CT: > case OFPACT_NAT: > + /* These may not generate PACKET INs. */ > break; > > - /* These need not be copied for restoration. */ > case OFPACT_NOTE: > case OFPACT_CONJUNCTION: > + /* These need not be copied for restoration. */ > continue; > } > /* Copy the action over. */ > diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at > index 3a8c893..bfb1b56 100644 > --- a/tests/ofproto-dpif.at > +++ b/tests/ofproto-dpif.at > @@ -4178,6 +4178,31 @@ AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath > actions: 4 > OVS_VSWITCHD_STOP > AT_CLEANUP > > +# This test verifies that the table ID is preserved across recirculation > +# when a resubmit action requires it (because the action is relative to > +# the current table rather than specifying a table). > +AT_SETUP([ofproto-dpif - resubmit with recirculation]) > +OVS_VSWITCHD_START > +ADD_OF_PORTS([br0], [1], [2], [3]) > + > +AT_DATA([flows.txt], [dnl > +table=0 in_port=1 actions=2,resubmit(,1) > +table=1 in_port=1 actions=debug_recirc,resubmit:55 > +table=1 in_port=55 actions=3 > +]) > +AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) > + > +flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)" > +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], > [stdout]) > +AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: 2,recirc(0x1) > +]) > +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow,recirc_id(1)" > -generate], [0], [stdout]) > +AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: 3 > +]) > + > +OVS_VSWITCHD_STOP > +AT_CLEANUP > + > # Two testcases below are for the ofproto/trace command > # The first one tests all correct syntax: > # ofproto/trace [dp_name] odp_flow [-generate|packet] > -- > 2.1.3 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev