void
test_flowinfo_mpls_unicast_tc_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add MPLS TC matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_MPLS_TC_MATCH(test_flow[s], TEST_TC(s));
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_MPLS_UT_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_ipv6_udp_dst_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add the UDP destination port matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_UDP_DST_MATCH(test_flow[s], TEST_L4_PORT(s));
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_IPV6_UDP_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_ipv6_nd_ns_target_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add the IPv6 ND NS target address match. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_IPV6_ND_TARGET_MATCH(test_flow[s], &ipv6tgt[s]);
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_IPV6_ND_UT_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_arp_tpa_w_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add the ARP IPv4 target address matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_ARP_TPA_W_MATCH(test_flow[s], &ipv4tgt[s], ipv4mask);
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_ARP_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_arp_op_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add the ARP operation matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_ARP_OP_MATCH(test_flow[s], TEST_ARP_OP(s));
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_ARP_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_ipv6_icmpv6_code_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add the ICMP code matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_ICMPV6_CODE_MATCH(test_flow[s], TEST_ICMPV6_CODE(s));
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_IPV6_ICMPV6_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_ipv6_exthdr_w_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add the IPv6 extension header matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_IPV6_EXTHDR_W_MATCH(test_flow[s], TEST_IPV6_EXTHDRS(s), exthdrmask);
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_IPV6_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_ipv6_flowlabel_adddel(void) {
  size_t s;

  TEST_ASSERT_OBJECTS();

  /* Add the IPv6 protocol and flowlabel matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    FLOW_ADD_IP_PROTO_MATCH(test_flow[s], TEST_IPV6_PROTO(s));
    FLOW_ADD_IPV6_FLOWLABEL_MATCH(test_flow[s], TEST_IPV6_FLOWLABEL(s));
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_IPV6_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_eth_src_w_adddel(void) {
  size_t s;
  uint8_t addr[OFP_ETH_ALEN];

  TEST_ASSERT_OBJECTS();

  /* Add Ethernet destination matches. */
  OS_MEMCPY(addr, srcaddr, sizeof(addr));
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    addr[OFP_ETH_ALEN - 1] = (uint8_t)s;
    FLOW_ADD_ETH_SRC_W_MATCH(test_flow[s], addr, maskaddr);
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Delete the matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
  }
}
void
test_flowinfo_ipv6_nd_ns_sll_adddel(void) {
  size_t s;
  uint8_t addr[OFP_ETH_ALEN];

  TEST_ASSERT_OBJECTS();

  /* Add the IPv6 ND NS source link-layer address match. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    OS_MEMCPY(addr, macsrc, sizeof(addr));
    addr[sizeof(addr) - 1] = TEST_ETH_ADDR_LSB(s);
    FLOW_ADD_IPV6_ND_SLL_MATCH(test_flow[s], addr);
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_IPV6_ND_UT_PREREQUISITE(test_flow[s]);
  }
}
void
test_flowinfo_arp_tha_w_adddel(void) {
  size_t s;
  uint8_t addr[OFP_ETH_ALEN];

  TEST_ASSERT_OBJECTS();

  /* Add the ARP MAC target address matches. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    OS_MEMCPY(addr, mactgt, sizeof(addr));
    addr[sizeof(addr) - 1] = TEST_ETH_ADDR_LSB(s);
    FLOW_ADD_ARP_THA_W_MATCH(test_flow[s], addr, macmask);
  }

  /* Run the sideeffect-free scenario. */
  TEST_SCENARIO_FLOWINFO_SEF(flowinfo);

  /* Reset the matches.  Mind the prerequisite. */
  for (s = 0; s < ARRAY_LEN(test_flow); s++) {
    TAILQ_INIT(&test_flow[s]->match_list);
    FLOW_ADD_ARP_PREREQUISITE(test_flow[s]);
  }
}