/*ARGSUSED*/ static int action_format( uintptr_t addr, const void *data, void *arg) { afdata_t *afp = (afdata_t *)arg; ipp_action_t *ap; int rc; ap = mdb_alloc(sizeof (ipp_action_t), UM_SLEEP); if (mdb_vread(ap, sizeof (ipp_action_t), addr) == -1) { mdb_warn("failed to read ipp_action_t at %p", addr); rc = WALK_ERR; goto done; } if (afp->af_flags & AF_VERBOSE) rc = action_dump(addr, ap, afp->af_banner); else rc = action_summary(addr, ap, afp->af_banner); afp->af_banner = B_FALSE; done: mdb_free(ap, sizeof (ipp_action_t)); return (rc); }
static int json_printer_fe(char *buf, int pos, int prio, struct header *h, struct match *ma, struct action *ac) { char buf2[128]; pos += sprintf(buf+pos, "{\"priority\":\"%d\",", prio); pos += match_dump_json(ma, h, buf+pos); action_dump(ac, buf2, 128); if(buf[pos-1] == ',') pos--; pos += sprintf(buf+pos, ",\"actions\":\"%s\"},", buf2); return pos; }
static int emit_rule(struct xswitch *sw, struct flow_table *ft, struct trace_tree *tree, struct match *ma, int priority, struct action *ac_pi) { int i; struct trace_tree_L *tl; struct trace_tree_V *tv; struct trace_tree_T *tt; struct trace_tree_D *td; struct trace_tree_G *tg; struct msgbuf *msg; struct match *maa; struct action *a; char buf[128], buf2[128]; struct expr *move_expr; switch(tree->type) { case TT_L: tl = (struct trace_tree_L *)tree; match_dump(ma, buf, 128); action_dump(tl->ac, buf2, 128); xdebug("tid %d: %2d, %s, %s\n", flow_table_get_tid(ft), priority, buf, buf2); if(tl->index == -1) { tl->index = flow_table_get_entry_index(ft); msg = msg_flow_entry_add(ft, tl->index, priority, ma, tl->ac); } else { msg = msg_flow_entry_mod(ft, tl->index, priority, ma, tl->ac); } xswitch_send(sw, msg); return priority + 1; case TT_V: tv = (struct trace_tree_V *)tree; for(i = 0; i < tv->num_branches; i++) { maa = match_copy(ma); match_add(maa, tv->name, tv->branches[i].value, value_from_64(0xffffffffffffffffull)); priority = emit_rule(sw, ft, tv->branches[i].tree, maa, priority, ac_pi); match_free(maa); } return priority; case TT_T: tt = (struct trace_tree_T *)tree; priority = emit_rule(sw, ft, tt->f, ma, priority, ac_pi); maa = match_copy(ma); match_add(maa, tt->name, tt->value, value_from_64(0xffffffffffffffffull)); action_dump(ac_pi, buf, 128); xdebug("tid %d: %2d, BARRIER, %s\n", flow_table_get_tid(ft), priority, buf); if(tt->barrier_index == -1) { tt->barrier_index = flow_table_get_entry_index(ft); msg = msg_flow_entry_add(ft, tt->barrier_index, priority, maa, ac_pi); } else { msg = msg_flow_entry_mod(ft, tt->barrier_index, priority, maa, ac_pi); } xswitch_send(sw, msg); priority = emit_rule(sw, ft, tt->t, maa, priority + 1, ac_pi); match_free(maa); return priority; case TT_G: tg = (struct trace_tree_G *)tree; if(tg->ft == NULL) { int tid = sw->next_table_id++; // add a new table tg->ft = header_make_flow_table(tg->new_spec, tid); msg = msg_flow_table_add(tg->ft); xswitch_send(sw, msg); init_entry(sw, tg->ft); } // insert GOTO_TABLE into orig table a = action(); if(tg->old_spec) move_expr = header_get_length(tg->old_spec); else move_expr = expr_value(0); expr_generate_action(move_expr, tg->old_spec, tg->ft, tg->stack_base, a); match_dump(ma, buf, 128); action_dump(a, buf2, 128); xdebug("tid %d: %2d, %s, %s\n", flow_table_get_tid(ft), priority, buf, buf2); if(tg->index == -1) { tg->index = flow_table_get_entry_index(ft); msg = msg_flow_entry_add(ft, tg->index, priority, ma, a); } else { msg = msg_flow_entry_mod(ft, tg->index, priority, ma, a); } xswitch_send(sw, msg); action_free(a); maa = match(); emit_rule(sw, tg->ft, tg->t, maa, 1, ac_pi); match_free(maa); return priority + 1; case TT_D: td = (struct trace_tree_D *)tree; return emit_rule(sw, ft, td->t, ma, priority, ac_pi); case TT_E: return priority; } assert(0); }
static int json_printer_ft(char *buf, int pos, struct trace_tree *tree, struct match *ma, int *priority, struct action *ac_pi, struct header *h) { int i; struct trace_tree_L *tl; struct trace_tree_V *tv; struct trace_tree_T *tt; struct trace_tree_D *td; struct trace_tree_G *tg; struct match *maa; struct action *a; char buf2[128]; struct expr *move_expr; switch(tree->type) { case TT_L: tl = (struct trace_tree_L *)tree; pos = json_printer_fe(buf, pos, *priority, h, ma, tl->ac); (*priority)++; return pos; case TT_V: tv = (struct trace_tree_V *)tree; for(i = 0; i < tv->num_branches; i++) { maa = match_copy(ma); match_add(maa, tv->name, tv->branches[i].value, value_from_64(0xffffffffffffffffull)); pos = json_printer_ft(buf, pos, tv->branches[i].tree, maa, priority, ac_pi, h); match_free(maa); } return pos; case TT_T: tt = (struct trace_tree_T *)tree; pos = json_printer_ft(buf, pos, tt->f, ma, priority, ac_pi, h); maa = match_copy(ma); match_add(maa, tt->name, tt->value, value_from_64(0xffffffffffffffffull)); pos = json_printer_fe(buf, pos, *priority, h, maa, ac_pi); (*priority)++; pos = json_printer_ft(buf, pos, tt->t, maa, priority, ac_pi, h); match_free(maa); return pos; case TT_G: tg = (struct trace_tree_G *)tree; // insert GOTO_TABLE into orig table a = action(); if(tg->old_spec) move_expr = header_get_length(tg->old_spec); else move_expr = expr_value(0); expr_generate_action(move_expr, tg->old_spec, tg->ft, tg->stack_base, a); action_dump(a, buf2, 128); pos = json_printer_fe(buf, pos, *priority, h, ma, a); action_free(a); (*priority)++; return pos; case TT_D: td = (struct trace_tree_D *)tree; return json_printer_ft(buf, pos, td->t, ma, priority, ac_pi, h); case TT_E: return pos; } assert(0); }