Message ID | 1484352826-46375-3-git-send-email-azhou@ovn.org |
---|---|
State | Superseded |
Delegated to: | Daniele Di Proietto |
Headers | show |
Needs rebasing if you address my comments to the previous patch. Jarno > On Jan 13, 2017, at 4:13 PM, Andy Zhou <azhou@ovn.org> wrote: > > Add logic to detect whether datapath support clone. > Enhance the xlate logic to make use of it. > Added logic to turn on/off clone support for testing. > > Signed-off-by: Andy Zhou <azhou@ovn.org> > --- > ofproto/ofproto-dpif-xlate.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- > ofproto/ofproto-dpif-xlate.h | 2 ++ > ofproto/ofproto-dpif.c | 23 +++++++++++++++++++++++ > tests/ofproto-dpif.at | 11 +++++++++++ > 4 files changed, 78 insertions(+), 2 deletions(-) > > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c > index e02771e..89801f7 100644 > --- a/ofproto/ofproto-dpif-xlate.c > +++ b/ofproto/ofproto-dpif-xlate.c > @@ -4520,9 +4520,29 @@ xlate_sample_action(struct xlate_ctx *ctx, > tunnel_out_port, false); > } > > +/* Only called if the datapath supports 'OVS_ACTION_ATTR_CLONE'. > + * > + * Translates 'oc' within OVS_ACTION_ATTR_CLONE. */ > static void > compose_clone_action(struct xlate_ctx *ctx, const struct ofpact_nest *oc) > { > + size_t clone_offset; > + size_t actions_offset; > + > + clone_offset = nl_msg_start_nested(ctx->odp_actions, > + OVS_ACTION_ATTR_CLONE); > + actions_offset = nl_msg_start_nested(ctx->odp_actions, > + OVS_CLONE_ATTR_ACTIONS); > + > + do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx); > + > + nl_msg_end_non_empty_nested(ctx->odp_actions, actions_offset); > + nl_msg_end_non_empty_nested(ctx->odp_actions, clone_offset); > +} > + > +static void > +xlate_clone(struct xlate_ctx *ctx, const struct ofpact_nest *oc) > +{ > bool old_was_mpls = ctx->was_mpls; > bool old_conntracked = ctx->conntracked; > struct flow old_flow = ctx->xin->flow; > @@ -4537,7 +4557,16 @@ compose_clone_action(struct xlate_ctx *ctx, const struct ofpact_nest *oc) > ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub); > ofpbuf_put(&ctx->action_set, old_action_set.data, old_action_set.size); > > - do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx); > + if (ctx->xbridge->support.clone) { > + /* Datapath clone action will make sure the pre clone packets > + * are used for actions after clone. Save and restore > + * ctx->base_flow to reflect this for the openflow pipeline. */ > + struct flow old_base_flow = ctx->base_flow; > + compose_clone_action(ctx, oc); > + ctx->base_flow = old_base_flow; > + } else { > + do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx); > + } > > ofpbuf_uninit(&ctx->action_set); > ctx->action_set = old_action_set; > @@ -5383,7 +5412,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, > break; > > case OFPACT_CLONE: > - compose_clone_action(ctx, ofpact_get_CLONE(a)); > + xlate_clone(ctx, ofpact_get_CLONE(a)); > break; > > case OFPACT_CT: > @@ -6169,3 +6198,14 @@ xlate_mac_learning_update(const struct ofproto_dpif *ofproto, > > update_learning_table__(xbridge, xbundle, dl_src, vlan, is_grat_arp); > } > + > +void > +xlate_disable_dp_clone(const struct ofproto_dpif *ofproto) > +{ > + struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp); > + struct xbridge *xbridge = xbridge_lookup(xcfg, ofproto); > + > + if (xbridge) { > + xbridge->support.clone = false; > + } > +} > diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h > index 5d00d6d..3986f26 100644 > --- a/ofproto/ofproto-dpif-xlate.h > +++ b/ofproto/ofproto-dpif-xlate.h > @@ -206,6 +206,8 @@ void xlate_mac_learning_update(const struct ofproto_dpif *ofproto, > ofp_port_t in_port, struct eth_addr dl_src, > int vlan, bool is_grat_arp); > > +void xlate_disable_dp_clone(const struct ofproto_dpif *); > + > void xlate_txn_start(void); > void xlate_txn_commit(void); > > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > index fca93a0..327aac9 100644 > --- a/ofproto/ofproto-dpif.c > +++ b/ofproto/ofproto-dpif.c > @@ -5015,6 +5015,26 @@ disable_datapath_truncate(struct unixctl_conn *conn OVS_UNUSED, > } > > static void > +disable_datapath_clone(struct unixctl_conn *conn OVS_UNUSED, > + int argc, const char *argv[], > + void *aux OVS_UNUSED) > +{ > + struct ds ds = DS_EMPTY_INITIALIZER; > + const char *br = argv[argc -1]; > + struct ofproto_dpif *ofproto; > + > + ofproto = ofproto_dpif_lookup(br); > + if (!ofproto) { > + unixctl_command_reply_error(conn, "no such bridge"); > + return; > + } > + xlate_disable_dp_clone(ofproto); > + udpif_flush(ofproto->backer->udpif); > + ds_put_format(&ds, "Datapath clone action disabled for bridge %s", br); > + unixctl_command_reply(conn, ds_cstr(&ds)); > +} > + > +static void > ofproto_unixctl_init(void) > { > static bool registered; > @@ -5043,6 +5063,9 @@ ofproto_unixctl_init(void) > > unixctl_command_register("dpif/disable-truncate", "", 0, 0, > disable_datapath_truncate, NULL); > + > + unixctl_command_register("dpif/disable-dp-clone", "bridge", 1, 1, > + disable_datapath_clone, NULL); > } > > static odp_port_t > diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at > index a4bf5a3..e861d9f 100644 > --- a/tests/ofproto-dpif.at > +++ b/tests/ofproto-dpif.at > @@ -6446,6 +6446,17 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt], [0], [ignore]) > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout]) > > AT_CHECK([tail -1 stdout], [0], [dnl > +Datapath actions: clone(set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2),clone(set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3),4 > +]) > + > +dnl Test flow xlate openflow clone action without using datapath clone action. > +AT_CHECK([ovs-appctl dpif/disable-dp-clone br0], [0], > +[Datapath clone action disabled for bridge br0 > +]) > + > +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout]) > + > +AT_CHECK([tail -1 stdout], [0], [dnl > Datapath actions: set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2,set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3,set(eth(src=50:54:00:00:00:09)),set(ipv4(src=10.10.10.2,dst=10.10.10.1)),4 > ]) > > -- > 2.7.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index e02771e..89801f7 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -4520,9 +4520,29 @@ xlate_sample_action(struct xlate_ctx *ctx, tunnel_out_port, false); } +/* Only called if the datapath supports 'OVS_ACTION_ATTR_CLONE'. + * + * Translates 'oc' within OVS_ACTION_ATTR_CLONE. */ static void compose_clone_action(struct xlate_ctx *ctx, const struct ofpact_nest *oc) { + size_t clone_offset; + size_t actions_offset; + + clone_offset = nl_msg_start_nested(ctx->odp_actions, + OVS_ACTION_ATTR_CLONE); + actions_offset = nl_msg_start_nested(ctx->odp_actions, + OVS_CLONE_ATTR_ACTIONS); + + do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx); + + nl_msg_end_non_empty_nested(ctx->odp_actions, actions_offset); + nl_msg_end_non_empty_nested(ctx->odp_actions, clone_offset); +} + +static void +xlate_clone(struct xlate_ctx *ctx, const struct ofpact_nest *oc) +{ bool old_was_mpls = ctx->was_mpls; bool old_conntracked = ctx->conntracked; struct flow old_flow = ctx->xin->flow; @@ -4537,7 +4557,16 @@ compose_clone_action(struct xlate_ctx *ctx, const struct ofpact_nest *oc) ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub); ofpbuf_put(&ctx->action_set, old_action_set.data, old_action_set.size); - do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx); + if (ctx->xbridge->support.clone) { + /* Datapath clone action will make sure the pre clone packets + * are used for actions after clone. Save and restore + * ctx->base_flow to reflect this for the openflow pipeline. */ + struct flow old_base_flow = ctx->base_flow; + compose_clone_action(ctx, oc); + ctx->base_flow = old_base_flow; + } else { + do_xlate_actions(oc->actions, ofpact_nest_get_action_len(oc), ctx); + } ofpbuf_uninit(&ctx->action_set); ctx->action_set = old_action_set; @@ -5383,7 +5412,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CLONE: - compose_clone_action(ctx, ofpact_get_CLONE(a)); + xlate_clone(ctx, ofpact_get_CLONE(a)); break; case OFPACT_CT: @@ -6169,3 +6198,14 @@ xlate_mac_learning_update(const struct ofproto_dpif *ofproto, update_learning_table__(xbridge, xbundle, dl_src, vlan, is_grat_arp); } + +void +xlate_disable_dp_clone(const struct ofproto_dpif *ofproto) +{ + struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp); + struct xbridge *xbridge = xbridge_lookup(xcfg, ofproto); + + if (xbridge) { + xbridge->support.clone = false; + } +} diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 5d00d6d..3986f26 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -206,6 +206,8 @@ void xlate_mac_learning_update(const struct ofproto_dpif *ofproto, ofp_port_t in_port, struct eth_addr dl_src, int vlan, bool is_grat_arp); +void xlate_disable_dp_clone(const struct ofproto_dpif *); + void xlate_txn_start(void); void xlate_txn_commit(void); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index fca93a0..327aac9 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5015,6 +5015,26 @@ disable_datapath_truncate(struct unixctl_conn *conn OVS_UNUSED, } static void +disable_datapath_clone(struct unixctl_conn *conn OVS_UNUSED, + int argc, const char *argv[], + void *aux OVS_UNUSED) +{ + struct ds ds = DS_EMPTY_INITIALIZER; + const char *br = argv[argc -1]; + struct ofproto_dpif *ofproto; + + ofproto = ofproto_dpif_lookup(br); + if (!ofproto) { + unixctl_command_reply_error(conn, "no such bridge"); + return; + } + xlate_disable_dp_clone(ofproto); + udpif_flush(ofproto->backer->udpif); + ds_put_format(&ds, "Datapath clone action disabled for bridge %s", br); + unixctl_command_reply(conn, ds_cstr(&ds)); +} + +static void ofproto_unixctl_init(void) { static bool registered; @@ -5043,6 +5063,9 @@ ofproto_unixctl_init(void) unixctl_command_register("dpif/disable-truncate", "", 0, 0, disable_datapath_truncate, NULL); + + unixctl_command_register("dpif/disable-dp-clone", "bridge", 1, 1, + disable_datapath_clone, NULL); } static odp_port_t diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index a4bf5a3..e861d9f 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -6446,6 +6446,17 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt], [0], [ignore]) AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], [dnl +Datapath actions: clone(set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2),clone(set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3),4 +]) + +dnl Test flow xlate openflow clone action without using datapath clone action. +AT_CHECK([ovs-appctl dpif/disable-dp-clone br0], [0], +[Datapath clone action disabled for bridge br0 +]) + +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout]) + +AT_CHECK([tail -1 stdout], [0], [dnl Datapath actions: set(ipv4(src=10.10.10.2,dst=192.168.4.4)),2,set(eth(src=80:81:81:81:81:81)),set(ipv4(src=10.10.10.2,dst=192.168.5.5)),3,set(eth(src=50:54:00:00:00:09)),set(ipv4(src=10.10.10.2,dst=10.10.10.1)),4 ])
Add logic to detect whether datapath support clone. Enhance the xlate logic to make use of it. Added logic to turn on/off clone support for testing. Signed-off-by: Andy Zhou <azhou@ovn.org> --- ofproto/ofproto-dpif-xlate.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- ofproto/ofproto-dpif-xlate.h | 2 ++ ofproto/ofproto-dpif.c | 23 +++++++++++++++++++++++ tests/ofproto-dpif.at | 11 +++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-)