+static inline uint64_t flow_u64_value(const struct flow *flow, size_t index)
+{
+ return ((uint64_t *)(flow))[index];
+}
+
+static inline uint64_t *flow_u64_lvalue(struct flow *flow, size_t index)
+{
+ return &((uint64_t *)(flow))[index];
+}
+
+static inline bool
+flow_get_next_in_map(const struct flow *flow, uint64_t map, uint64_t *value)
+{
+ if (map) {
+ *value = flow_u64_value(flow, raw_ctz(map));
+ return true;
+ }
+ return false;
+}
+
+/* Iterate through all flow u64 values specified by 'MAP'. */
+#define FLOW_FOR_EACH_IN_MAP(VALUE, FLOW, MAP) \
+ for (uint64_t map__ = (MAP); \
+ flow_get_next_in_map(FLOW, map__, &(VALUE)); \
+ map__ = zero_rightmost_1bit(map__))
+
+/* Iterate through all struct flow u64 indices specified by 'MAP'. */
+#define MAP_FOR_EACH_INDEX(U64IDX, MAP) \
+ for (uint64_t map__ = (MAP); \
+ map__ && ((U64IDX) = raw_ctz(map__), true); \
+ map__ = zero_rightmost_1bit(map__))
+
+#define FLOW_U64_SIZE(FIELD) \
+ DIV_ROUND_UP(sizeof(((struct flow *)0)->FIELD), sizeof(uint64_t))
+
+#define MINIFLOW_MAP(FIELD) \
+ (((UINT64_C(1) << FLOW_U64_SIZE(FIELD)) - 1) \
+ << (offsetof(struct flow, FIELD) / sizeof(uint64_t)))
+
+struct mf_for_each_in_map_aux {
+ const uint64_t *values;
+ uint64_t fmap;
+ uint64_t map;
+};
+
+static inline bool
+mf_get_next_in_map(struct mf_for_each_in_map_aux *aux, uint64_t *value)
+{
+ if (aux->map) {
+ uint64_t rm1bit = rightmost_1bit(aux->map);
+ aux->map -= rm1bit;
+
+ if (aux->fmap & rm1bit) {
+ /* Advance 'aux->values' to point to the value for 'rm1bit'. */
+ uint64_t trash = aux->fmap & (rm1bit - 1);
+ if (trash) {
+ aux->fmap -= trash;
+ aux->values += count_1bits(trash);
+ }
+
+ /* Retrieve the value for 'rm1bit' then advance past it. */
+ aux->fmap -= rm1bit;
+ *value = *aux->values++;
+ } else {
+ *value = 0;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/* Iterate through all miniflow u64 values specified by 'MAP'. */
+#define MINIFLOW_FOR_EACH_IN_MAP(VALUE, FLOW, MAP) \
+ for (struct mf_for_each_in_map_aux aux__ \
+ = { miniflow_get_values(FLOW), (FLOW)->map, MAP }; \
+ mf_get_next_in_map(&aux__, &(VALUE)); \
+ )
+
+/* This can be used when it is known that 'u64_idx' is set in 'map'. */
+static inline uint64_t
+miniflow_values_get__(const uint64_t *values, uint64_t map, int u64_idx)
+{
+ return values[count_1bits(map & ((UINT64_C(1) << u64_idx) - 1))];
+}
+
+/* This can be used when it is known that 'u64_idx' is set in
+ * the map of 'mf'. */
+static inline uint64_t
+miniflow_get__(const struct miniflow *mf, int u64_idx)
+{
+ return miniflow_values_get__(miniflow_get_values(mf), mf->map, u64_idx);
+}
+
+/* Get the value of 'FIELD' of an up to 8 byte wide integer type 'TYPE' of
+ * a miniflow. */
+#define MINIFLOW_GET_TYPE(MF, TYPE, OFS) \
+ (((MF)->map & (UINT64_C(1) << (OFS) / sizeof(uint64_t))) \
+ ? ((OVS_FORCE const TYPE *) \
+ (miniflow_get_values(MF) \
+ + count_1bits((MF)->map & \
+ ((UINT64_C(1) << (OFS) / sizeof(uint64_t)) - 1)))) \
+ [(OFS) % sizeof(uint64_t) / sizeof(TYPE)] \
+ : 0) \
+
+#define MINIFLOW_GET_U8(FLOW, FIELD) \
+ MINIFLOW_GET_TYPE(FLOW, uint8_t, offsetof(struct flow, FIELD))
+#define MINIFLOW_GET_U16(FLOW, FIELD) \
+ MINIFLOW_GET_TYPE(FLOW, uint16_t, offsetof(struct flow, FIELD))
+#define MINIFLOW_GET_BE16(FLOW, FIELD) \
+ MINIFLOW_GET_TYPE(FLOW, ovs_be16, offsetof(struct flow, FIELD))
+#define MINIFLOW_GET_U32(FLOW, FIELD) \
+ MINIFLOW_GET_TYPE(FLOW, uint32_t, offsetof(struct flow, FIELD))
+#define MINIFLOW_GET_BE32(FLOW, FIELD) \
+ MINIFLOW_GET_TYPE(FLOW, ovs_be32, offsetof(struct flow, FIELD))
+#define MINIFLOW_GET_U64(FLOW, FIELD) \
+ MINIFLOW_GET_TYPE(FLOW, uint64_t, offsetof(struct flow, FIELD))
+#define MINIFLOW_GET_BE64(FLOW, FIELD) \
+ MINIFLOW_GET_TYPE(FLOW, ovs_be64, offsetof(struct flow, FIELD))
+
+static inline uint64_t miniflow_get(const struct miniflow *,
+ unsigned int u64_ofs);