Exemple #1
0
/**
 * Clone a match object, preparing it to continue from where it left off
 * @param mt the match to copy
 * @param log the log to report errors to
 * @return a copy of mt or NULL on failure
 */
match *match_clone( match *mt, plugin_log *log )
{
    match *mt2 = NULL;
    if ( mt->end.current != NULL )
    {
        mt2 = match_copy( mt, log );
        if ( mt2 != NULL )
        {
            // pick up where our parent left off
            mt2->start = mt->end;
            mt2->end = mt->end;
            mt2->len = 0;
            mt2->maximal = 0;
            // reset because we are starting again
            mt2->freq = 0;
            mt->end = mt->prev; 
            match_pop_versions( mt );
            // the queue belongs to mt, not to us
            if ( mt2->queue != NULL )
            {
                match_state_dispose( mt2->queue );
                mt2->queue = NULL;
            }// this should probably be deleted
            //mt2->text_off = match_text_end(mt);
        }
    }
    return mt2;
}
Exemple #2
0
/**
 * Make an exact deep copy of a match
 * @param mt the match to copy
 * @param log the log to report errors to
 * @return a copy of mt or NULL on failure
 */
match *match_copy( match *mt, plugin_log *log )
{
    match *mt2 = calloc( 1, sizeof(match) );
    if ( mt2 != NULL )
    {
        mt2->start = mt->start;
        mt2->end = mt->end;
        mt2->prev = mt->prev;
        if ( mt->prev_bs != NULL )
            mt2->prev_bs = bitset_clone( mt->prev_bs );
        if ( mt->bs != NULL )
            mt2->bs = bitset_clone( mt->bs );
        mt2->st_off = mt->st_off;
        //mt2->text_off = 0;
        mt2->text_off = mt->text_off;
        mt2->len = mt->len;
        mt2->maximal = mt->maximal;
        mt2->freq = mt->freq;
        mt2->cards = mt->cards;
        mt2->st = mt->st;
        if ( mt->next != NULL )
            mt2->next = match_copy( mt->next, log );
        if ( mt->queue != NULL )
            mt2->queue = match_state_copy(mt->queue,log);
        mt2->loc = mt->loc;
    }
    else
        plugin_log_add( log, "match: failed to duplicate match object\n");
    return mt2;
}
Exemple #3
0
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);
}
Exemple #4
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);
}