+/* Makes 'rule' match field 'mf' exactly, with the value matched taken from
+ * 'value'. The caller is responsible for ensuring that 'rule' meets 'mf''s
+ * prerequisites. */
+void
+mf_set_flow_value(const struct mf_field *mf,
+ const union mf_value *value, struct flow *flow)
+{
+ switch (mf->id) {
+ case MFF_TUN_ID:
+ flow->tun_id = value->be64;
+ break;
+
+ case MFF_IN_PORT:
+ flow->in_port = ntohs(value->be16);
+ break;
+
+#if FLOW_N_REGS > 0
+ case MFF_REG0:
+#endif
+#if FLOW_N_REGS > 1
+ case MFF_REG1:
+#endif
+#if FLOW_N_REGS > 2
+ case MFF_REG2:
+#endif
+#if FLOW_N_REGS > 3
+ case MFF_REG3:
+#endif
+#if FLOW_N_REGS > 4
+ case MFF_REG4:
+#endif
+#if FLOW_N_REGS > 5
+#error
+#endif
+#if FLOW_N_REGS > 0
+ flow->regs[mf->id - MFF_REG0] = ntohl(value->be32);
+ break;
+#endif
+
+ case MFF_ETH_SRC:
+ memcpy(flow->dl_src, value->mac, ETH_ADDR_LEN);
+ break;
+
+ case MFF_ETH_DST:
+ memcpy(flow->dl_src, value->mac, ETH_ADDR_LEN);
+ break;
+
+ case MFF_ETH_TYPE:
+ flow->dl_type = value->be16;
+ break;
+
+ case MFF_VLAN_TCI:
+ flow->vlan_tci = value->be16;
+ break;
+
+ case MFF_VLAN_VID:
+ flow_set_vlan_vid(flow, value->be16);
+ break;
+
+ case MFF_VLAN_PCP:
+ flow_set_vlan_pcp(flow, value->u8);
+ break;
+
+ case MFF_IPV4_SRC:
+ flow->nw_src = value->be32;
+ break;
+
+ case MFF_IPV4_DST:
+ flow->nw_dst = value->be32;
+ break;
+
+ case MFF_IPV6_SRC:
+ flow->ipv6_src = value->ipv6;
+ break;
+
+ case MFF_IPV6_DST:
+ flow->ipv6_dst = value->ipv6;
+ break;
+
+ case MFF_IPV6_LABEL:
+ flow->ipv6_label = value->be32 & ~htonl(IPV6_LABEL_MASK);
+ break;
+
+ case MFF_IP_PROTO:
+ flow->nw_proto = value->u8;
+ break;
+
+ case MFF_IP_DSCP:
+ flow->nw_tos &= ~IP_DSCP_MASK;
+ flow->nw_tos |= value->u8 & IP_DSCP_MASK;
+ break;
+
+ case MFF_IP_ECN:
+ flow->nw_tos &= ~IP_ECN_MASK;
+ flow->nw_tos |= value->u8 & IP_ECN_MASK;
+ break;
+
+ case MFF_IP_TTL:
+ flow->nw_ttl = value->u8;
+ break;
+
+ case MFF_IP_FRAG:
+ flow->nw_frag &= value->u8;
+ break;
+
+ case MFF_ARP_OP:
+ flow->nw_proto = ntohs(value->be16);
+ break;
+
+ case MFF_ARP_SPA:
+ flow->nw_src = value->be32;
+ break;
+
+ case MFF_ARP_TPA:
+ flow->nw_dst = value->be32;
+ break;
+
+ case MFF_ARP_SHA:
+ case MFF_ND_SLL:
+ memcpy(flow->arp_sha, value->mac, ETH_ADDR_LEN);
+ break;
+
+ case MFF_ARP_THA:
+ case MFF_ND_TLL:
+ memcpy(flow->arp_tha, value->mac, ETH_ADDR_LEN);
+ break;
+
+ case MFF_TCP_SRC:
+ case MFF_UDP_SRC:
+ flow->tp_src = value->be16;
+ break;
+
+ case MFF_TCP_DST:
+ case MFF_UDP_DST:
+ flow->tp_dst = value->be16;
+ break;
+
+ case MFF_ICMPV4_TYPE:
+ case MFF_ICMPV6_TYPE:
+ flow->tp_src = htons(value->u8);
+ break;
+
+ case MFF_ICMPV4_CODE:
+ case MFF_ICMPV6_CODE:
+ flow->tp_dst = htons(value->u8);
+ break;
+
+ case MFF_ND_TARGET:
+ flow->nd_target = value->ipv6;
+ break;
+
+ case MFF_N_IDS:
+ default:
+ NOT_REACHED();
+ }
+}
+