Place all of the detected datapath features into a separate structure, initialized when the dpif_backer is opened and shared with xbridges.
Signed-off-by: Joe Stringer <joestrin...@nicira.com> --- ofproto/ofproto-dpif-xlate.c | 80 +++++++++++++++--------------------------- ofproto/ofproto-dpif-xlate.h | 7 ++-- ofproto/ofproto-dpif.c | 64 +++++++++++++-------------------- ofproto/ofproto-dpif.h | 18 ++++++++++ 4 files changed, 73 insertions(+), 96 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 55ae683..e02c8fa 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -96,21 +96,8 @@ struct xbridge { bool has_in_band; /* Bridge has in band control? */ bool forward_bpdu; /* Bridge forwards STP BPDUs? */ - /* True if the datapath supports recirculation. */ - bool enable_recirc; - - /* True if the datapath supports variable-length - * OVS_USERSPACE_ATTR_USERDATA in OVS_ACTION_ATTR_USERSPACE actions. - * False if the datapath supports only 8-byte (or shorter) userdata. */ - bool variable_length_userdata; - - /* Number of MPLS label stack entries that the datapath supports - * in matches. */ - size_t max_mpls_depth; - - /* True if the datapath supports masked data in OVS_ACTION_ATTR_SET - * actions. */ - bool masked_set_action; + /* Datapath feature support. */ + struct dpif_backer_support support; }; struct xbundle { @@ -492,10 +479,7 @@ static void xlate_xbridge_set(struct xbridge *, struct dpif *, const struct dpif_ipfix *, const struct netflow *, bool forward_bpdu, bool has_in_band, - bool enable_recirc, - bool variable_length_userdata, - size_t max_mpls_depth, - bool masked_set_action); + const struct dpif_backer_support *); static void xlate_xbundle_set(struct xbundle *xbundle, enum port_vlan_mode vlan_mode, int vlan, unsigned long *trunks, bool use_priority_tags, @@ -563,10 +547,7 @@ xlate_xbridge_set(struct xbridge *xbridge, const struct dpif_ipfix *ipfix, const struct netflow *netflow, bool forward_bpdu, bool has_in_band, - bool enable_recirc, - bool variable_length_userdata, - size_t max_mpls_depth, - bool masked_set_action) + const struct dpif_backer_support *support) { if (xbridge->ml != ml) { mac_learning_unref(xbridge->ml); @@ -611,10 +592,7 @@ xlate_xbridge_set(struct xbridge *xbridge, xbridge->dpif = dpif; xbridge->forward_bpdu = forward_bpdu; xbridge->has_in_band = has_in_band; - xbridge->enable_recirc = enable_recirc; - xbridge->variable_length_userdata = variable_length_userdata; - xbridge->max_mpls_depth = max_mpls_depth; - xbridge->masked_set_action = masked_set_action; + xbridge->support = *support; } static void @@ -698,10 +676,8 @@ xlate_xbridge_copy(struct xbridge *xbridge) xbridge->dpif, xbridge->ml, xbridge->stp, xbridge->rstp, xbridge->ms, xbridge->mbridge, xbridge->sflow, xbridge->ipfix, xbridge->netflow, - xbridge->forward_bpdu, - xbridge->has_in_band, xbridge->enable_recirc, - xbridge->variable_length_userdata, - xbridge->max_mpls_depth, xbridge->masked_set_action); + xbridge->forward_bpdu, xbridge->has_in_band, + &xbridge->support); LIST_FOR_EACH (xbundle, list_node, &xbridge->xbundles) { xlate_xbundle_copy(new_xbridge, xbundle); } @@ -852,9 +828,8 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, const struct dpif_sflow *sflow, const struct dpif_ipfix *ipfix, const struct netflow *netflow, - bool forward_bpdu, bool has_in_band, bool enable_recirc, - bool variable_length_userdata, size_t max_mpls_depth, - bool masked_set_action) + bool forward_bpdu, bool has_in_band, + const struct dpif_backer_support *support) { struct xbridge *xbridge; @@ -872,9 +847,7 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, xbridge->name = xstrdup(name); xlate_xbridge_set(xbridge, dpif, ml, stp, rstp, ms, mbridge, sflow, ipfix, - netflow, forward_bpdu, has_in_band, enable_recirc, - variable_length_userdata, max_mpls_depth, - masked_set_action); + netflow, forward_bpdu, has_in_band, support); } static void @@ -1754,7 +1727,7 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, struct flow_wildcards *wc = &ctx->xout->wc; struct ofport_dpif *ofport; - if (ctx->xbridge->enable_recirc) { + if (ctx->xbridge->support.recirc) { use_recirc = bond_may_recirc( out_xbundle->bond, &xr.recirc_id, &xr.hash_basis); @@ -2953,10 +2926,11 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, } if (out_port != ODPP_NONE) { + bool use_masked = ctx->xbridge->support.masked_set_action; + ctx->xout->slow |= commit_odp_actions(flow, &ctx->base_flow, ctx->xout->odp_actions, - wc, - ctx->xbridge->masked_set_action); + wc, use_masked); if (xr) { struct ovs_action_hash *act_hash; @@ -3426,6 +3400,7 @@ execute_controller_action(struct xlate_ctx *ctx, int len, { struct ofproto_packet_in *pin; struct dp_packet *packet; + bool use_masked; ctx->xout->slow |= SLOW_CONTROLLER; if (!ctx->xin->packet) { @@ -3434,10 +3409,10 @@ execute_controller_action(struct xlate_ctx *ctx, int len, packet = dp_packet_clone(ctx->xin->packet); + use_masked = ctx->xbridge->support.masked_set_action; ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow, ctx->xout->odp_actions, - &ctx->xout->wc, - ctx->xbridge->masked_set_action); + &ctx->xout->wc, use_masked); odp_execute_actions(NULL, &packet, 1, false, ctx->xout->odp_actions->data, @@ -3479,12 +3454,13 @@ static void compose_recirculate_action(struct xlate_ctx *ctx) { struct recirc_metadata md; + bool use_masked; uint32_t id; + use_masked = ctx->xbridge->support.masked_set_action; ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow, ctx->xout->odp_actions, - &ctx->xout->wc, - ctx->xbridge->masked_set_action); + &ctx->xout->wc, use_masked); recirc_metadata_from_flow(&md, &ctx->xin->flow); @@ -3534,10 +3510,11 @@ compose_mpls_push_action(struct xlate_ctx *ctx, struct ofpact_push_mpls *mpls) n = flow_count_mpls_labels(flow, wc); if (!n) { + bool use_masked = ctx->xbridge->support.masked_set_action; + ctx->xout->slow |= commit_odp_actions(flow, &ctx->base_flow, ctx->xout->odp_actions, - &ctx->xout->wc, - ctx->xbridge->masked_set_action); + &ctx->xout->wc, use_masked); } else if (n >= FLOW_MAX_MPLS_LABELS) { if (ctx->xin->packet != NULL) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -3561,7 +3538,7 @@ compose_mpls_pop_action(struct xlate_ctx *ctx, ovs_be16 eth_type) int n = flow_count_mpls_labels(flow, wc); if (flow_pop_mpls(flow, n, eth_type, wc)) { - if (ctx->xbridge->enable_recirc) { + if (ctx->xbridge->support.recirc) { ctx->was_mpls = true; } } else if (n >= FLOW_MAX_MPLS_LABELS) { @@ -3885,8 +3862,9 @@ xlate_sample_action(struct xlate_ctx *ctx, /* Scale the probability from 16-bit to 32-bit while representing * the same percentage. */ uint32_t probability = (os->probability << 16) | os->probability; + bool use_masked; - if (!ctx->xbridge->variable_length_userdata) { + if (!ctx->xbridge->support.variable_length_userdata) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_ERR_RL(&rl, "ignoring NXAST_SAMPLE action because datapath " @@ -3895,10 +3873,10 @@ xlate_sample_action(struct xlate_ctx *ctx, return; } + use_masked = ctx->xbridge->support.masked_set_action; ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow, ctx->xout->odp_actions, - &ctx->xout->wc, - ctx->xbridge->masked_set_action); + &ctx->xout->wc, use_masked); compose_flow_sample_cookie(os->probability, os->collector_set_id, os->obs_domain_id, os->obs_point_id, &cookie); @@ -4743,7 +4721,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) if (is_ip_any(flow)) { wc->masks.nw_frag |= FLOW_NW_FRAG_MASK; } - if (xbridge->enable_recirc) { + if (xbridge->support.recirc) { /* Always exactly match recirc_id when datapath supports * recirculation. */ wc->masks.recirc_id = UINT32_MAX; diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 6c8ade3..e39847b 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -210,11 +210,8 @@ void xlate_ofproto_set(struct ofproto_dpif *, const char *name, struct dpif *, struct rstp *, const struct mcast_snooping *, const struct mbridge *, const struct dpif_sflow *, const struct dpif_ipfix *, const struct netflow *, - bool forward_bpdu, - bool has_in_band, bool enable_recirc, - bool variable_length_userdata, - size_t mpls_label_stack_length, - bool masked_set_action); + bool forward_bpdu, bool has_in_band, + const struct dpif_backer_support *support); void xlate_remove_ofproto(struct ofproto_dpif *); void xlate_bundle_set(struct ofproto_dpif *, struct ofbundle *, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 01d99c5..8f1df74 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -271,30 +271,11 @@ struct dpif_backer { bool recv_set_enable; /* Enables or disables receiving packets. */ - /* Recirculation. */ - bool enable_recirc; /* True if the datapath supports recirculation */ - - /* True if the datapath supports unique flow identifiers */ - bool enable_ufid; - - /* True if the datapath supports variable-length - * OVS_USERSPACE_ATTR_USERDATA in OVS_ACTION_ATTR_USERSPACE actions. - * False if the datapath supports only 8-byte (or shorter) userdata. */ - bool variable_length_userdata; - - /* True if the datapath supports masked data in OVS_ACTION_ATTR_SET - * actions. */ - bool masked_set_action; - - /* Maximum number of MPLS label stack entries that the datapath supports - * in a match */ - size_t max_mpls_depth; - /* Version string of the datapath stored in OVSDB. */ char *dp_version_string; - /* True if the datapath supports tnl_push and pop actions. */ - bool enable_tnl_push_pop; + /* Datapath feature support. */ + struct dpif_backer_support support; struct atomic_count tnl_count; }; @@ -370,19 +351,19 @@ ofproto_dpif_cast(const struct ofproto *ofproto) size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *ofproto) { - return ofproto->backer->max_mpls_depth; + return ofproto->backer->support.max_mpls_depth; } bool ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *ofproto) { - return ofproto->backer->enable_recirc; + return ofproto->backer->support.recirc; } bool ofproto_dpif_get_enable_ufid(struct dpif_backer *backer) { - return backer->enable_ufid; + return backer->support.ufid; } static void ofproto_trace(struct ofproto_dpif *, struct flow *, @@ -646,10 +627,7 @@ type_run(const char *type) ofproto->netflow, ofproto->up.forward_bpdu, connmgr_has_in_band(ofproto->up.connmgr), - ofproto->backer->enable_recirc, - ofproto->backer->variable_length_userdata, - ofproto->backer->max_mpls_depth, - ofproto->backer->masked_set_action); + &ofproto->backer->support); HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) { xlate_bundle_set(ofproto, bundle, bundle->name, @@ -873,10 +851,7 @@ struct odp_garbage { }; static bool check_variable_length_userdata(struct dpif_backer *backer); -static size_t check_max_mpls_depth(struct dpif_backer *backer); -static bool check_recirc(struct dpif_backer *backer); -static bool check_ufid(struct dpif_backer *backer); -static bool check_masked_set_action(struct dpif_backer *backer); +static void check_support(struct dpif_backer *backer); static int open_dpif_backer(const char *type, struct dpif_backer **backerp) @@ -971,12 +946,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp) shash_add(&all_dpif_backers, type, backer); - backer->enable_recirc = check_recirc(backer); - backer->max_mpls_depth = check_max_mpls_depth(backer); - backer->masked_set_action = check_masked_set_action(backer); - backer->enable_ufid = check_ufid(backer); - - backer->enable_tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif); + check_support(backer); atomic_count_init(&backer->tnl_count, 0); error = dpif_recv_set(backer->dpif, backer->recv_set_enable); @@ -994,7 +964,8 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp) /* This check fails if performed before udpif threads have been set, * as the kernel module checks that the 'pid' in userspace action * is non-zero. */ - backer->variable_length_userdata = check_variable_length_userdata(backer); + backer->support.variable_length_userdata + = check_variable_length_userdata(backer); backer->dp_version_string = dpif_get_dp_version(backer->dpif); return error; @@ -1003,7 +974,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp) bool ovs_native_tunneling_is_on(struct ofproto_dpif *ofproto) { - return ofproto_use_tnl_push_pop && ofproto->backer->enable_tnl_push_pop && + return ofproto_use_tnl_push_pop && ofproto->backer->support.tnl_push_pop && atomic_count_get(&ofproto->backer->tnl_count); } @@ -1228,6 +1199,19 @@ check_masked_set_action(struct dpif_backer *backer) return !error; } +static void +check_support(struct dpif_backer *backer) +{ + /* This feature needs to be tested after udpif threads are set. */ + backer->support.variable_length_userdata = false; + + backer->support.recirc = check_recirc(backer); + backer->support.max_mpls_depth = check_max_mpls_depth(backer); + backer->support.masked_set_action = check_masked_set_action(backer); + backer->support.ufid = check_ufid(backer); + backer->support.tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif); +} + static int construct(struct ofproto *ofproto_) { diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 9566924..f9f62ab 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -73,6 +73,24 @@ BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); * Ofproto-dpif-xlate is responsible for translating OpenFlow actions into * datapath actions. */ +/* Stores the various features which the corresponding backer supports. */ +struct dpif_backer_support { + /* True if the datapath supports variable-length + * OVS_USERSPACE_ATTR_USERDATA in OVS_ACTION_ATTR_USERSPACE actions. + * False if the datapath supports only 8-byte (or shorter) userdata. */ + bool variable_length_userdata; + + /* Maximum number of MPLS label stack entries that the datapath supports + * in a match */ + size_t max_mpls_depth; + + /* True if the datapath supports the corresponding feature. */ + bool masked_set_action; + bool recirc; + bool tnl_push_pop; + bool ufid; +}; + size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *); bool ofproto_dpif_get_enable_recirc(const struct ofproto_dpif *); bool ofproto_dpif_get_enable_ufid(struct dpif_backer *backer); -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev