- 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);
- }