+/*
+ * table.
+ */
+static struct table *
+table_find(struct rte_swx_pipeline *p, const char *name);
+
+static int
+instr_table_translate(struct rte_swx_pipeline *p,
+ struct action *action,
+ char **tokens,
+ int n_tokens,
+ struct instruction *instr,
+ struct instruction_data *data __rte_unused)
+{
+ struct table *t;
+
+ CHECK(!action, EINVAL);
+ CHECK(n_tokens == 2, EINVAL);
+
+ t = table_find(p, tokens[1]);
+ CHECK(t, EINVAL);
+
+ instr->type = INSTR_TABLE;
+ instr->table.table_id = t->id;
+ return 0;
+}
+
+static inline void
+instr_table_exec(struct rte_swx_pipeline *p)
+{
+ struct thread *t = &p->threads[p->thread_id];
+ struct instruction *ip = t->ip;
+ uint32_t table_id = ip->table.table_id;
+ struct rte_swx_table_state *ts = &t->table_state[table_id];
+ struct table_runtime *table = &t->tables[table_id];
+ uint64_t action_id;
+ uint8_t *action_data;
+ int done, hit;
+
+ /* Table. */
+ done = table->func(ts->obj,
+ table->mailbox,
+ table->key,
+ &action_id,
+ &action_data,
+ &hit);
+ if (!done) {
+ /* Thread. */
+ TRACE("[Thread %2u] table %u (not finalized)\n",
+ p->thread_id,
+ table_id);
+
+ thread_yield(p);
+ return;
+ }
+
+ action_id = hit ? action_id : ts->default_action_id;
+ action_data = hit ? action_data : ts->default_action_data;
+
+ TRACE("[Thread %2u] table %u (%s, action %u)\n",
+ p->thread_id,
+ table_id,
+ hit ? "hit" : "miss",
+ (uint32_t)action_id);
+
+ t->action_id = action_id;
+ t->structs[0] = action_data;
+ t->hit = hit;
+
+ /* Thread. */
+ thread_ip_action_call(p, t, action_id);
+}
+