+ flow.nw_proto = ARP_OP_REPLY;
+ setup_flow(in_band, IBR_TO_LOCAL_ARP, &flow,
+ (OFPFW_DL_TYPE | OFPFW_DL_DST | OFPFW_NW_PROTO),
+ OFPP_NORMAL);
+
+ /* Allow the connection's interface to be the source of ARP traffic. */
+ memset(&flow, 0, sizeof flow);
+ flow.dl_type = htons(ETH_TYPE_ARP);
+ memcpy(flow.dl_src, local_mac, ETH_ADDR_LEN);
+ flow.nw_proto = ARP_OP_REQUEST;
+ setup_flow(in_band, IBR_FROM_LOCAL_ARP, &flow,
+ (OFPFW_DL_TYPE | OFPFW_DL_SRC | OFPFW_NW_PROTO),
+ OFPP_NORMAL);
+ } else {
+ drop_flow(in_band, IBR_TO_LOCAL_ARP);
+ drop_flow(in_band, IBR_FROM_LOCAL_ARP);
+ }
+
+ if (remote_mac) {
+ /* Allow ARP replies to the remote side's MAC. */
+ memset(&flow, 0, sizeof flow);
+ flow.dl_type = htons(ETH_TYPE_ARP);
+ memcpy(flow.dl_dst, remote_mac, ETH_ADDR_LEN);
+ flow.nw_proto = ARP_OP_REPLY;
+ setup_flow(in_band, IBR_TO_REMOTE_ARP, &flow,
+ (OFPFW_DL_TYPE | OFPFW_DL_DST | OFPFW_NW_PROTO),
+ OFPP_NORMAL);
+
+ /* 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),