X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.c;h=cdc21bca65c12516403e52c589a97ec25fb6f2cd;hb=264ecd63860eaf705669edac1bdc7292d8da0843;hp=42138b9913d30cf74d643fdfdcf64258765fb9e0;hpb=015e08bcc1e211e3326d21b8c4178b0152252d29;p=openvswitch diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 42138b99..cdc21bca 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -22,6 +22,7 @@ #include "autopath.h" #include "bond.h" +#include "bundle.h" #include "byte-order.h" #include "connmgr.h" #include "coverage.h" @@ -332,6 +333,8 @@ struct ofproto_dpif { /* Support for debugging async flow mods. */ struct list completions; + + bool has_bundle_action; /* True when the first bundle action appears. */ }; /* Defer flow mod completion until "ovs-appctl ofproto/unclog"? (Useful only @@ -467,6 +470,8 @@ construct(struct ofproto *ofproto_) ofproto_dpif_unixctl_init(); + ofproto->has_bundle_action = false; + return 0; } @@ -709,6 +714,7 @@ port_construct(struct ofport *port_) port->bundle = NULL; port->cfm = NULL; port->tag = tag_create_random(); + port->may_enable = true; if (ofproto->sflow) { dpif_sflow_add_port(ofproto->sflow, port->odp_port, @@ -1261,6 +1267,7 @@ mirror_set(struct ofproto *ofproto_, void *aux, mirror = ofproto->mirrors[idx] = xzalloc(sizeof *mirror); mirror->ofproto = ofproto; mirror->idx = idx; + mirror->aux = aux; mirror->out_vlan = -1; mirror->name = NULL; } @@ -1436,6 +1443,14 @@ port_run(struct ofport_dpif *ofport) enable = enable && lacp_slave_may_enable(ofport->bundle->lacp, ofport); } + if (ofport->may_enable != enable) { + struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto); + + if (ofproto->has_bundle_action) { + ofproto->need_revalidate = true; + } + } + ofport->may_enable = enable; } @@ -1856,11 +1871,12 @@ facet_max_idle(const struct ofproto_dpif *ofproto) * N_BUCKETS buckets whose width is BUCKET_WIDTH msecs each. Each facet * that is installed in the kernel gets dropped in the appropriate bucket. * After the histogram has been built, we compute the cutoff so that only - * the most-recently-used 1% of facets (but at least 1000 flows) are kept - * cached. At least the most-recently-used bucket of facets is kept, so - * actually an arbitrary number of facets can be kept in any given - * expiration run (though the next run will delete most of those unless - * they receive additional data). + * the most-recently-used 1% of facets (but at least + * ofproto->up.flow_eviction_threshold flows) are kept cached. At least + * the most-recently-used bucket of facets is kept, so actually an + * arbitrary number of facets can be kept in any given expiration run + * (though the next run will delete most of those unless they receive + * additional data). * * This requires a second pass through the facets, in addition to the pass * made by update_stats(), because the former function never looks @@ -1875,7 +1891,7 @@ facet_max_idle(const struct ofproto_dpif *ofproto) int i; total = hmap_count(&ofproto->facets); - if (total <= 1000) { + if (total <= ofproto->up.flow_eviction_threshold) { return N_BUCKETS * BUCKET_WIDTH; } @@ -1893,7 +1909,8 @@ facet_max_idle(const struct ofproto_dpif *ofproto) subtotal = bucket = 0; do { subtotal += buckets[bucket++]; - } while (bucket < N_BUCKETS && subtotal < MAX(1000, total / 100)); + } while (bucket < N_BUCKETS && + subtotal < MAX(ofproto->up.flow_eviction_threshold, total / 100)); if (VLOG_IS_DBG_ENABLED()) { struct ds s; @@ -2032,7 +2049,7 @@ execute_odp_actions(struct ofproto_dpif *ofproto, const struct flow *flow, struct ofpbuf *packet) { if (actions_len == NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)) - && odp_actions->nla_type == ODP_ACTION_ATTR_CONTROLLER) { + && odp_actions->nla_type == ODP_ACTION_ATTR_USERSPACE) { /* As an optimization, avoid a round-trip from userspace to kernel to * userspace. This also avoids possibly filling up kernel packet * buffers along the way. */ @@ -2770,7 +2787,7 @@ send_packet(struct ofproto_dpif *ofproto, uint32_t odp_port, static void do_xlate_actions(const union ofp_action *in, size_t n_in, struct action_xlate_ctx *ctx); -static bool xlate_normal(struct action_xlate_ctx *); +static void xlate_normal(struct action_xlate_ctx *); static void commit_odp_actions(struct action_xlate_ctx *ctx) @@ -2794,6 +2811,11 @@ commit_odp_actions(struct action_xlate_ctx *ctx) base->nw_dst = flow->nw_dst; } + if (base->nw_tos != flow->nw_tos) { + nl_msg_put_u8(odp_actions, ODP_ACTION_ATTR_SET_NW_TOS, flow->nw_tos); + base->nw_tos = flow->nw_tos; + } + if (base->vlan_tci != flow->vlan_tci) { if (!(flow->vlan_tci & htons(VLAN_CFI))) { nl_msg_put_flag(odp_actions, ODP_ACTION_ATTR_STRIP_VLAN); @@ -2936,7 +2958,7 @@ xlate_output_action__(struct action_xlate_ctx *ctx, break; case OFPP_CONTROLLER: commit_odp_actions(ctx); - nl_msg_put_u64(ctx->odp_actions, ODP_ACTION_ATTR_CONTROLLER, max_len); + nl_msg_put_u64(ctx->odp_actions, ODP_ACTION_ATTR_USERSPACE, max_len); break; case OFPP_LOCAL: add_output_action(ctx, OFPP_LOCAL); @@ -3047,6 +3069,28 @@ xlate_autopath(struct action_xlate_ctx *ctx, autopath_execute(naa, &ctx->flow, ofp_port); } +static bool +slave_enabled_cb(uint16_t ofp_port, void *ofproto_) +{ + struct ofproto_dpif *ofproto = ofproto_; + struct ofport_dpif *port; + + switch (ofp_port) { + case OFPP_IN_PORT: + case OFPP_TABLE: + case OFPP_NORMAL: + case OFPP_FLOOD: + case OFPP_ALL: + case OFPP_LOCAL: + return true; + case OFPP_CONTROLLER: /* Not supported by the bundle action. */ + return false; + default: + port = get_ofp_port(ofproto, ofp_port); + return port ? port->may_enable : false; + } +} + static void do_xlate_actions(const union ofp_action *in, size_t n_in, struct action_xlate_ctx *ctx) @@ -3072,6 +3116,7 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, const struct nx_action_set_queue *nasq; const struct nx_action_multipath *nam; const struct nx_action_autopath *naa; + const struct nx_action_bundle *nab; enum ofputil_action_code code; ovs_be64 tun_id; @@ -3115,7 +3160,7 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, break; case OFPUTIL_OFPAT_SET_NW_TOS: - ctx->flow.nw_tos = ia->nw_tos.nw_tos; + ctx->flow.nw_tos = ia->nw_tos.nw_tos & IP_DSCP_MASK; break; case OFPUTIL_OFPAT_SET_TP_SRC: @@ -3178,6 +3223,21 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, naa = (const struct nx_action_autopath *) ia; xlate_autopath(ctx, naa); break; + + case OFPUTIL_NXAST_BUNDLE: + ctx->ofproto->has_bundle_action = true; + nab = (const struct nx_action_bundle *) ia; + xlate_output_action__(ctx, bundle_execute(nab, &ctx->flow, + slave_enabled_cb, + ctx->ofproto), 0); + break; + + case OFPUTIL_NXAST_BUNDLE_LOAD: + ctx->ofproto->has_bundle_action = true; + nab = (const struct nx_action_bundle *) ia; + bundle_execute_load(nab, &ctx->flow, slave_enabled_cb, + ctx->ofproto); + break; } } } @@ -3319,7 +3379,8 @@ dst_is_duplicate(const struct dst_set *set, const struct dst *test) static bool ofbundle_trunks_vlan(const struct ofbundle *bundle, uint16_t vlan) { - return bundle->vlan < 0 && vlan_bitmap_contains(bundle->trunks, vlan); + return (bundle->vlan < 0 + && (!bundle->trunks || bitmap_is_set(bundle->trunks, vlan))); } static bool @@ -3365,7 +3426,7 @@ compose_dsts(struct action_xlate_ctx *ctx, uint16_t vlan, static bool vlan_is_mirrored(const struct ofmirror *m, int vlan) { - return vlan_bitmap_contains(m->vlans, vlan); + return !m->vlans || bitmap_is_set(m->vlans, vlan); } /* Returns true if a packet with Ethernet destination MAC 'dst' may be mirrored @@ -3715,10 +3776,7 @@ is_admissible(struct ofproto_dpif *ofproto, const struct flow *flow, return true; } -/* If the composed actions may be applied to any packet in the given 'flow', - * returns true. Otherwise, the actions should only be applied to 'packet', or - * not at all, if 'packet' was NULL. */ -static bool +static void xlate_normal(struct action_xlate_ctx *ctx) { struct ofbundle *in_bundle; @@ -3749,7 +3807,8 @@ xlate_normal(struct action_xlate_ctx *ctx) * of time where we could learn from a packet reflected on a bond and * blackhole packets before the learning table is updated to reflect * the correct port. */ - return false; + ctx->may_set_up_flow = false; + return; } else { out_bundle = OFBUNDLE_FLOOD; } @@ -3763,8 +3822,6 @@ done: if (in_bundle) { compose_actions(ctx, vlan, in_bundle, out_bundle); } - - return true; } static bool