+/**
+ * RTE_TABLE_ACTION_LB
+ */
+static int
+lb_cfg_check(struct rte_table_action_lb_config *cfg)
+{
+ if ((cfg == NULL) ||
+ (cfg->key_size < RTE_TABLE_ACTION_LB_KEY_SIZE_MIN) ||
+ (cfg->key_size > RTE_TABLE_ACTION_LB_KEY_SIZE_MAX) ||
+ (!rte_is_power_of_2(cfg->key_size)) ||
+ (cfg->f_hash == NULL))
+ return -1;
+
+ return 0;
+}
+
+struct lb_data {
+ uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
+} __attribute__((__packed__));
+
+static int
+lb_apply(struct lb_data *data,
+ struct rte_table_action_lb_params *p)
+{
+ memcpy(data->out, p->out, sizeof(data->out));
+
+ return 0;
+}
+
+static __rte_always_inline void
+pkt_work_lb(struct rte_mbuf *mbuf,
+ struct lb_data *data,
+ struct rte_table_action_lb_config *cfg)
+{
+ uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->key_offset);
+ uint32_t *out = RTE_MBUF_METADATA_UINT32_PTR(mbuf, cfg->out_offset);
+ uint64_t digest, pos;
+ uint32_t out_val;
+
+ digest = cfg->f_hash(pkt_key,
+ cfg->key_mask,
+ cfg->key_size,
+ cfg->seed);
+ pos = digest & (RTE_TABLE_ACTION_LB_TABLE_SIZE - 1);
+ out_val = data->out[pos];
+
+ *out = out_val;
+}
+