void trace_tree_emit_rule(struct xswitch *sw, struct trace_tree *tree) { struct match *ma = match(); struct action *ac_pi = action(); action_add(ac_pi, AC_PACKET_IN, 0); emit_rule(sw, sw->table0, tree, ma, 1, ac_pi); action_free(ac_pi); match_free(ma); }
void emit_ast(struct ast_s * n) { struct rule_list_s * r; if (n->list) { int count = 0; for (r = n->list; r; r = r->list) count++; if (count > 1) { nest(); /* semicolons are OR */ printf("or\n"); } for (r = n->list; r; r = r->list) { if (r->rule) { emit_rule(r->rule); } } if (count > 1) unnest(); } }
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); }