-
- /* Table 0, Priority 100.
- * ======================
- *
- * We have now determined the full set of port bindings associated with
- * each "localnet" network. Only create flows for datapaths that have
- * another local binding. Otherwise, we know it would just be dropped.
- */
- struct shash_node *ln_bindings_node, *ln_bindings_node_next;
- SHASH_FOR_EACH_SAFE (ln_bindings_node, ln_bindings_node_next,
- &localnet_inputs) {
- struct localnet_bindings *ln_bindings = ln_bindings_node->data;
- struct localnet_vlan *ln_vlan, *ln_vlan_next;
- HMAP_FOR_EACH_SAFE (ln_vlan, ln_vlan_next, node, &ln_bindings->vlans) {
- struct match match;
- match_init_catchall(&match);
- match_set_in_port(&match, ln_bindings->ofport);
- if (ln_vlan->tag) {
- match_set_dl_vlan(&match, htons(ln_vlan->tag));
- } else {
- /* Match priority-tagged frames, e.g. VLAN ID 0.
- *
- * We'll add a second flow for frames that lack any 802.1Q
- * header later. */
- match_set_dl_tci_masked(&match, htons(VLAN_CFI),
- htons(VLAN_VID_MASK | VLAN_CFI));
- }
-
- struct ofpbuf ofpacts;
- ofpbuf_init(&ofpacts, 0);
-
- ofpact_put_STRIP_VLAN(&ofpacts);
- uint32_t ofpacts_orig_size = ofpacts.size;
-
- struct binding_elem *b;
- LIST_FOR_EACH_POP (b, list_elem, &ln_vlan->bindings) {
- struct hmap_node *ld;
- ld = hmap_first_with_hash(local_datapaths,
- b->binding->datapath->tunnel_key);
- if (ld) {
- /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
- put_load(b->binding->datapath->tunnel_key, MFF_LOG_DATAPATH,
- 0, 64, &ofpacts);
- put_load(b->binding->tunnel_key, MFF_LOG_INPORT, 0, 32,
- &ofpacts);
- put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts);
- }
-
- free(b);
- }
-
- if (ofpacts.size > ofpacts_orig_size) {
- ofctrl_add_flow(flow_table, 0, 100, &match, &ofpacts);
-
- if (!ln_vlan->tag) {
- /* Add a second flow for frames that lack any 802.1Q
- * header. For these, drop the OFPACT_STRIP_VLAN
- * action. */
- ofpbuf_pull(&ofpacts, ofpacts_orig_size);
- match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI));
- ofctrl_add_flow(flow_table, 0, 100, &match, &ofpacts);
- }
- }
-
- ofpbuf_uninit(&ofpacts);
-
- hmap_remove(&ln_bindings->vlans, &ln_vlan->node);
- free(ln_vlan);
- }
- shash_delete(&localnet_inputs, ln_bindings_node);
- hmap_destroy(&ln_bindings->vlans);
- free(ln_bindings);
- }
- shash_destroy(&localnet_inputs);
-
- simap_destroy(&localnet_to_ofport);