- if (controller_ip) {
- /* Allow ARP replies to the controller's IP. */
- memset(&flow, 0, sizeof flow);
- flow.dl_type = htons(ETH_TYPE_ARP);
- flow.nw_proto = ARP_OP_REPLY;
- flow.nw_dst = controller_ip;
- setup_flow(in_band, IBR_TO_CTL_ARP, &flow,
- (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_DST_MASK),
- OFPP_NORMAL);
-
- /* Allow ARP requests from the controller's IP. */
- memset(&flow, 0, sizeof flow);
- flow.dl_type = htons(ETH_TYPE_ARP);
- flow.nw_proto = ARP_OP_REQUEST;
- flow.nw_src = controller_ip;
- setup_flow(in_band, IBR_FROM_CTL_ARP, &flow,
- (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK),
- 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);
- flow.nw_proto = IP_TYPE_TCP;
- flow.nw_src = controller_ip;
- flow.nw_dst = controller_ip;
- flow.tp_src = htons(OFP_TCP_PORT);
- flow.tp_dst = htons(OFP_TCP_PORT);
- setup_flow(in_band, IBR_TO_CTL_OFP, &flow,
- (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_DST_MASK
- | OFPFW_TP_DST), OFPP_NORMAL);
- setup_flow(in_band, IBR_FROM_CTL_OFP, &flow,
- (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK
- | OFPFW_TP_SRC), OFPP_NORMAL);
- } else {
- drop_flow(in_band, IBR_TO_CTL_ARP);
- drop_flow(in_band, IBR_FROM_CTL_ARP);
- drop_flow(in_band, IBR_TO_CTL_OFP);
- drop_flow(in_band, IBR_FROM_CTL_OFP);
+ /* Drop old rules. */
+ drop_rules(ib);
+
+ /* Figure out new rules. */
+ memcpy(ib->installed_local_mac, ib->local_mac, ETH_ADDR_LEN);
+ ib->remote_addrs = xmalloc(ib->n_remotes * sizeof *ib->remote_addrs);
+ ib->n_remote_addrs = 0;
+ ib->remote_macs = xmalloc(ib->n_remotes * ETH_ADDR_LEN);
+ ib->n_remote_macs = 0;
+ for (r = ib->remotes; r < &ib->remotes[ib->n_remotes]; r++) {
+ ib->remote_addrs[ib->n_remote_addrs++] = r->remote_addr;
+ if (!eth_addr_is_zero(r->remote_mac)) {
+ memcpy(&ib->remote_macs[ib->n_remote_macs * ETH_ADDR_LEN],
+ r->remote_mac, ETH_ADDR_LEN);
+ ib->n_remote_macs++;
+ }