X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.c;h=a0c7b288328093547bc65d618f43cc9aed103e44;hb=816fd533f85923c03cf8d9d6450bd9a0845d5160;hp=d46fcf3cfcac3a2ff05810feeab368c35dbb4ce4;hpb=c2b565b54e36bc33d0406afb225c9bf3d01405ef;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index d46fcf3cf..a0c7b2883 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -34,6 +34,7 @@ #include "lacp.h" #include "learn.h" #include "mac-learning.h" +#include "meta-flow.h" #include "multipath.h" #include "netdev.h" #include "netlink.h" @@ -1193,7 +1194,7 @@ update_stp_port_state(struct ofport_dpif *ofport) if (stp_learn_in_state(ofport->stp_state) != stp_learn_in_state(state)) { /* xxx Learning action flows should also be flushed. */ - mac_learning_flush(ofproto->ml); + mac_learning_flush(ofproto->ml, &ofproto->revalidate_set); } fwd_change = stp_forward_in_state(ofport->stp_state) != stp_forward_in_state(state); @@ -1296,6 +1297,10 @@ stp_run(struct ofproto_dpif *ofproto) update_stp_port_state(ofport); } } + + if (stp_check_and_reset_fdb_flush(ofproto->stp)) { + mac_learning_flush(ofproto->ml, &ofproto->revalidate_set); + } } } @@ -1879,7 +1884,7 @@ bundle_run(struct ofbundle *bundle) } bond_run(bundle->bond, &bundle->ofproto->revalidate_set, - lacp_negotiated(bundle->lacp)); + lacp_status(bundle->lacp)); if (bond_should_send_learning_packets(bundle->bond)) { bundle_send_learning_packets(bundle); } @@ -2064,7 +2069,7 @@ mirror_set(struct ofproto *ofproto_, void *aux, } ofproto->need_revalidate = true; - mac_learning_flush(ofproto->ml); + mac_learning_flush(ofproto->ml, &ofproto->revalidate_set); mirror_update_dups(ofproto); return 0; @@ -2083,7 +2088,7 @@ mirror_destroy(struct ofmirror *mirror) ofproto = mirror->ofproto; ofproto->need_revalidate = true; - mac_learning_flush(ofproto->ml); + mac_learning_flush(ofproto->ml, &ofproto->revalidate_set); mirror_bit = MIRROR_MASK_C(1) << mirror->idx; HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) { @@ -2126,8 +2131,7 @@ set_flood_vlans(struct ofproto *ofproto_, unsigned long *flood_vlans) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); if (mac_learning_set_flood_vlans(ofproto->ml, flood_vlans)) { - ofproto->need_revalidate = true; - mac_learning_flush(ofproto->ml); + mac_learning_flush(ofproto->ml, &ofproto->revalidate_set); } return 0; } @@ -2421,7 +2425,7 @@ struct flow_miss_op { * OpenFlow controller as necessary according to their individual * configurations. */ static void -send_packet_in_miss(struct ofproto_dpif *ofproto, struct ofpbuf *packet, +send_packet_in_miss(struct ofproto_dpif *ofproto, const struct ofpbuf *packet, const struct flow *flow) { struct ofputil_packet_in pin; @@ -2576,7 +2580,6 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct flow_miss *miss, continue; } - list_remove(&packet->list_node); if (flow->vlan_tci != subfacet->initial_tci) { /* This packet was received on a VLAN splinter port. We added * a VLAN to the packet to make the packet resemble the flow, @@ -2739,14 +2742,10 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls, /* Process each element in the to-do list, constructing the set of * operations to batch. */ n_ops = 0; - HMAP_FOR_EACH_SAFE (miss, next_miss, hmap_node, &todo) { + HMAP_FOR_EACH (miss, hmap_node, &todo) { handle_flow_miss(ofproto, miss, flow_miss_ops, &n_ops); - ofpbuf_list_delete(&miss->packets); - hmap_remove(&todo, &miss->hmap_node); - free(miss); } assert(n_ops <= ARRAY_SIZE(flow_miss_ops)); - hmap_destroy(&todo); /* Execute batch. */ for (i = 0; i < n_ops; i++) { @@ -2765,7 +2764,6 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls, if (op->subfacet->actions != execute->actions) { free((struct nlattr *) execute->actions); } - ofpbuf_delete((struct ofpbuf *) execute->packet); break; case DPIF_OP_FLOW_PUT: @@ -2775,6 +2773,12 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls, break; } } + HMAP_FOR_EACH_SAFE (miss, next_miss, hmap_node, &todo) { + ofpbuf_list_delete(&miss->packets); + hmap_remove(&todo, &miss->hmap_node); + free(miss); + } + hmap_destroy(&todo); } static void @@ -3367,6 +3371,7 @@ facet_check_consistency(struct facet *facet) struct rule_dpif *rule; struct subfacet *subfacet; + bool may_log = false; bool ok; /* Check the rule for consistency. */ @@ -3379,22 +3384,24 @@ facet_check_consistency(struct facet *facet) } return false; } else if (rule != facet->rule) { - struct ds s; + may_log = !VLOG_DROP_WARN(&rl); + ok = false; + if (may_log) { + struct ds s; - ds_init(&s); - flow_format(&s, &facet->flow); - ds_put_format(&s, ": facet associated with wrong rule (was " - "table=%"PRIu8",", facet->rule->up.table_id); - cls_rule_format(&facet->rule->up.cr, &s); - ds_put_format(&s, ") (should have been table=%"PRIu8",", - rule->up.table_id); - cls_rule_format(&rule->up.cr, &s); - ds_put_char(&s, ')'); - - VLOG_WARN("%s", ds_cstr(&s)); - ds_destroy(&s); + ds_init(&s); + flow_format(&s, &facet->flow); + ds_put_format(&s, ": facet associated with wrong rule (was " + "table=%"PRIu8",", facet->rule->up.table_id); + cls_rule_format(&facet->rule->up.cr, &s); + ds_put_format(&s, ") (should have been table=%"PRIu8",", + rule->up.table_id); + cls_rule_format(&rule->up.cr, &s); + ds_put_char(&s, ')'); - ok = false; + VLOG_WARN("%s", ds_cstr(&s)); + ds_destroy(&s); + } } else { ok = true; } @@ -3424,42 +3431,47 @@ facet_check_consistency(struct facet *facet) || memcmp(subfacet->actions, odp_actions->data, subfacet->actions_len)); if (should_install != subfacet->installed || actions_changed) { - struct odputil_keybuf keybuf; - struct ofpbuf key; - struct ds s; + if (ok) { + may_log = !VLOG_DROP_WARN(&rl); + ok = false; + } - ok = false; + if (may_log) { + struct odputil_keybuf keybuf; + struct ofpbuf key; + struct ds s; - ds_init(&s); - subfacet_get_key(subfacet, &keybuf, &key); - odp_flow_key_format(key.data, key.size, &s); - - ds_put_cstr(&s, ": inconsistency in subfacet"); - if (should_install != subfacet->installed) { - enum odp_key_fitness fitness = subfacet->key_fitness; - - ds_put_format(&s, " (should%s have been installed)", - should_install ? "" : " not"); - ds_put_format(&s, " (may_set_up_flow=%s, fitness=%s)", - ctx.may_set_up_flow ? "true" : "false", - odp_key_fitness_to_string(fitness)); - } - if (actions_changed) { - ds_put_cstr(&s, " (actions were: "); - format_odp_actions(&s, subfacet->actions, - subfacet->actions_len); - ds_put_cstr(&s, ") (correct actions: "); - format_odp_actions(&s, odp_actions->data, - odp_actions->size); - ds_put_char(&s, ')'); - } else { - ds_put_cstr(&s, " (actions: "); - format_odp_actions(&s, subfacet->actions, - subfacet->actions_len); - ds_put_char(&s, ')'); + ds_init(&s); + subfacet_get_key(subfacet, &keybuf, &key); + odp_flow_key_format(key.data, key.size, &s); + + ds_put_cstr(&s, ": inconsistency in subfacet"); + if (should_install != subfacet->installed) { + enum odp_key_fitness fitness = subfacet->key_fitness; + + ds_put_format(&s, " (should%s have been installed)", + should_install ? "" : " not"); + ds_put_format(&s, " (may_set_up_flow=%s, fitness=%s)", + ctx.may_set_up_flow ? "true" : "false", + odp_key_fitness_to_string(fitness)); + } + if (actions_changed) { + ds_put_cstr(&s, " (actions were: "); + format_odp_actions(&s, subfacet->actions, + subfacet->actions_len); + ds_put_cstr(&s, ") (correct actions: "); + format_odp_actions(&s, odp_actions->data, + odp_actions->size); + ds_put_char(&s, ')'); + } else { + ds_put_cstr(&s, " (actions: "); + format_odp_actions(&s, subfacet->actions, + subfacet->actions_len); + ds_put_char(&s, ')'); + } + VLOG_WARN("%s", ds_cstr(&s)); + ds_destroy(&s); } - VLOG_WARN("%s", ds_cstr(&s)); - ds_destroy(&s); } next: @@ -4557,9 +4569,11 @@ static void xlate_output_reg_action(struct action_xlate_ctx *ctx, const struct nx_action_output_reg *naor) { + struct mf_subfield src; uint64_t ofp_port; - ofp_port = nxm_read_field_bits(naor->src, naor->ofs_nbits, &ctx->flow); + nxm_decode(&src, naor->src, naor->ofs_nbits); + ofp_port = mf_get_subfield(&src, &ctx->flow); if (ofp_port <= UINT16_MAX) { xlate_output_action__(ctx, ofp_port, ntohs(naor->max_len)); @@ -5804,17 +5818,23 @@ ofproto_dpif_lookup(const char *name) } static void -ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, int argc OVS_UNUSED, +ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, int argc, const char *argv[], void *aux OVS_UNUSED) { - const struct ofproto_dpif *ofproto; + struct ofproto_dpif *ofproto; - ofproto = ofproto_dpif_lookup(argv[1]); - if (!ofproto) { - unixctl_command_reply(conn, 501, "no such bridge"); - return; + if (argc > 1) { + ofproto = ofproto_dpif_lookup(argv[1]); + if (!ofproto) { + unixctl_command_reply(conn, 501, "no such bridge"); + return; + } + mac_learning_flush(ofproto->ml, &ofproto->revalidate_set); + } else { + HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) { + mac_learning_flush(ofproto->ml, &ofproto->revalidate_set); + } } - mac_learning_flush(ofproto->ml); unixctl_command_reply(conn, 200, "table successfully flushed"); } @@ -6114,8 +6134,8 @@ ofproto_dpif_unixctl_init(void) unixctl_command_register( "ofproto/trace", "bridge {tun_id in_port packet | odp_flow [-generate]}", - 2, 4, ofproto_unixctl_trace, NULL); - unixctl_command_register("fdb/flush", "bridge", 1, 1, + 2, 5, ofproto_unixctl_trace, NULL); + unixctl_command_register("fdb/flush", "[bridge]", 0, 1, ofproto_unixctl_fdb_flush, NULL); unixctl_command_register("fdb/show", "bridge", 1, 1, ofproto_unixctl_fdb_show, NULL);