- if (controller_mac) {
- /* Switch ARP requests sent by the controller. (OFPP_NORMAL will "do
- * the right thing" regarding VLANs here.) */
- memset(&flow, 0, sizeof flow);
- flow.dl_type = htons(ETH_TYPE_ARP);
- memcpy(flow.dl_dst, eth_addr_broadcast, ETH_ADDR_LEN);
- memcpy(flow.dl_src, controller_mac, ETH_ADDR_LEN);
- setup_flow(in_band, IBR_ARP_FROM_CTL, &flow,
- OFPFW_DL_TYPE | OFPFW_DL_DST | OFPFW_DL_SRC,
- OFPP_NORMAL);
-
- /* OpenFlow traffic to or from the controller.
- *
- * (A given field's value is completely ignored if it is wildcarded,
- * which is why we can get away with using a single 'flow' in each
- * case here.) */
- memset(&flow, 0, sizeof flow);
- flow.dl_type = htons(ETH_TYPE_IP);
- memcpy(flow.dl_src, controller_mac, ETH_ADDR_LEN);
- memcpy(flow.dl_dst, controller_mac, ETH_ADDR_LEN);
- flow.nw_proto = IP_TYPE_TCP;
- flow.tp_src = htons(OFP_TCP_PORT);
- flow.tp_dst = htons(OFP_TCP_PORT);
- setup_flow(in_band, IBR_TO_CTL_OFP_SRC, &flow,
- (OFPFW_DL_TYPE | OFPFW_DL_DST | OFPFW_NW_PROTO
- | OFPFW_TP_SRC), OFPP_NORMAL);
- setup_flow(in_band, IBR_TO_CTL_OFP_DST, &flow,
- (OFPFW_DL_TYPE | OFPFW_DL_DST | OFPFW_NW_PROTO
- | OFPFW_TP_DST), OFPP_NORMAL);
- setup_flow(in_band, IBR_FROM_CTL_OFP_SRC, &flow,
- (OFPFW_DL_TYPE | OFPFW_DL_SRC | OFPFW_NW_PROTO
- | OFPFW_TP_SRC), OFPP_NORMAL);
- setup_flow(in_band, IBR_FROM_CTL_OFP_DST, &flow,
- (OFPFW_DL_TYPE | OFPFW_DL_SRC | OFPFW_NW_PROTO
- | OFPFW_TP_DST), OFPP_NORMAL);
- } else {
- drop_flow(in_band, IBR_ARP_FROM_CTL);
- drop_flow(in_band, IBR_TO_CTL_OFP_DST);
- drop_flow(in_band, IBR_TO_CTL_OFP_SRC);
- drop_flow(in_band, IBR_FROM_CTL_OFP_DST);
- drop_flow(in_band, IBR_FROM_CTL_OFP_SRC);
+ HMAP_FOR_EACH_SAFE (rule, next, hmap_node, &ib->rules) {
+ switch (rule->op) {
+ case ADD:
+ ofproto_add_flow(ib->ofproto, &rule->match, rule->priority,
+ ofpacts.data, ofpacts.size);
+ break;
+
+ case DEL:
+ ofproto_delete_flow(ib->ofproto, &rule->match, rule->priority);
+ hmap_remove(&ib->rules, &rule->hmap_node);
+ free(rule);
+ break;
+ }