+ /* Allow ARP requests from the remote side's MAC. */
+ memset(&flow, 0, sizeof flow);
+ flow.dl_type = htons(ETH_TYPE_ARP);
+ memcpy(flow.dl_src, remote_mac, ETH_ADDR_LEN);
+ flow.nw_proto = ARP_OP_REQUEST;
+ setup_flow(in_band, IBR_FROM_REMOTE_ARP, &flow,
+ (OFPFW_DL_TYPE | OFPFW_DL_SRC | OFPFW_NW_PROTO),
+ OFPP_NORMAL);
+ } else {
+ drop_flow(in_band, IBR_TO_REMOTE_ARP);
+ drop_flow(in_band, IBR_FROM_REMOTE_ARP);
+ }
+
+ 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);
+