#include "lacp.h"
#include "learn.h"
#include "mac-learning.h"
+#include "meta-flow.h"
#include "multipath.h"
#include "netdev.h"
#include "netlink.h"
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);
update_stp_port_state(ofport);
}
}
+
+ if (stp_check_and_reset_fdb_flush(ofproto->stp)) {
+ mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+ }
}
}
}
ofproto->need_revalidate = true;
- mac_learning_flush(ofproto->ml);
+ mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
mirror_update_dups(ofproto);
return 0;
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) {
{
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;
}
* 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;
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,
/* 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++) {
if (op->subfacet->actions != execute->actions) {
free((struct nlattr *) execute->actions);
}
- ofpbuf_delete((struct ofpbuf *) execute->packet);
break;
case DPIF_OP_FLOW_PUT:
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
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));
unixctl_command_reply(conn, 501, "no such bridge");
return;
}
- mac_learning_flush(ofproto->ml);
- ofproto->need_revalidate = true;
+ 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->need_revalidate = true;
+ mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
}
}