Пример #1
0
void flow_table_rem(flow_table_t *ft, struct flow_keys match) {
    int index = 0;
    unsigned long flags = 0;
    match_stk_t *curr = NULL;
    match_stk_t *last = NULL;

    index = flow_keys_hash(match) % ft->size;

    curr = rcu_dereference_bh(ft->table[index]);

    pr_debug("FT: removing bucket entry at %d\n", index);
    while(curr != NULL && !flow_key_equal(match, curr->match)) {
        last = curr;
        curr = rcu_dereference_bh(curr->next);
    }

    if(curr != NULL && flow_key_equal(match, curr->match)) {
        // entry exists
        ft_lock(flags);
        if(curr == ft->table[index]){
            // if at the beginning of bucket
            rcu_assign_pointer(ft->table[index], curr->next);
        } else {
            // otherwise
            rcu_assign_pointer(last->next, curr->next);
        }
        ft_unlock(flags);
        // free both stk and entry
        free_match_stk_entry(curr);
        atomic_dec(&ft->num_flows);
    }
    // else entry doesn't exist
}
Пример #2
0
void	ft_play(int x[2], int team, char *map, int sem_id)
{
	while (1)
	{
		ft_lock(sem_id);
		ft_putmap(map);
		if (ft_alone(map, team, x, sem_id))
			break ;
		ft_death(map, x, sem_id, team);
		ft_move(map, x, team);
		ft_putmap(map);
		ft_unlock(sem_id);
		sleep(1);
	}
}
Пример #3
0
struct stack flow_table_get( flow_table_t *ft, struct flow_keys match, routing_table_t* routing_table, u32 dst_ip) {
    struct stack no_stack;
    struct stack new_stk;
    struct stack old_stk;
    unsigned long flags = 0;
    match_stk_t *curr = NULL;
    match_stk_t *prev = NULL;
    int index = 0;
    no_stack.num_tags = -1;
    index = flow_keys_hash(match) % ft->size;

    curr = rcu_dereference_bh(ft->table[index]);
    
    while(curr != NULL && !flow_key_equal(match, curr->match)) {
        pr_debug("FT: active non-matching flow\n");
        prev = curr;
        curr = rcu_dereference_bh(curr->next);
    }

    // flow_table returns "no_stack" on miss
    if(curr == NULL || !flow_key_equal(match, curr->match)) {
        pr_debug("FT: no matching flow\n");
        return no_stack;
    }

    // found a matching stack - check idle timeout before returning
    if(flow_idle_time(curr->last_used) > IDLE_TIMEOUT){
        pr_debug("FT: matched flow - timeout.. num_flows %d -> %d\n", 
                atomic_read(&ft->num_flows), atomic_read(&ft->num_flows) - 1);
        // if idle timed-out, remove flow entry and return no_stack
        new_stk = stack_dup(get_random_stack_for_dst(dst_ip, routing_table));
        old_stk = curr->stk;
        ft_lock(flags);
        curr->stk = new_stk;
        ft_unlock(flags);
        stack_free(old_stk);
    }

    pr_debug("FT: matched flow - updating last_used\n");
    // update the last_used value for successful match
    curr->last_used = jiffies;
    return curr->stk;
}
Пример #4
0
void flow_table_set( flow_table_t *ft, struct flow_keys match,
        struct stack orig_stk ) {
    unsigned long flags = 0;
    int index = 0;
    match_stk_t *new_match_stk = NULL;
    match_stk_t *curr = NULL;
    match_stk_t *prev = NULL;
    match_stk_t *tmp = NULL;
    match_stk_t *to_free = NULL;

    // keep separate copies of stack in routing and flow tables
    struct stack stk = stack_dup(orig_stk);

    new_match_stk = flow_table_new_match_stk(match, stk);
    if(new_match_stk == NULL){
        stack_free(stk);
        return;
    }
    index = flow_keys_hash(match) % ft->size;

    pr_debug("FT: setting flow entry %d ... num_flows: %d -> %d\n", index, 
            atomic_read(&ft->num_flows), atomic_read(&ft->num_flows)+1);

    ft_lock(flags);
    curr = rcu_dereference_bh(ft->table[index]);

    while(curr != NULL && !flow_key_equal(match, curr->match)) {
        // ---
        if(flow_idle_time(curr->last_used) > IDLE_TIMEOUT && 0){
            // if idle timed-out, remove flow entry
            pr_debug("FT: non-matching flow timeout remove it %d -> %d flows\n",
                    atomic_read(&ft->num_flows), 
                    atomic_read(&ft->num_flows)-1);
            if(prev == NULL) { 
                // at the beginning of bucket
                tmp = curr->next;
                rcu_assign_pointer(ft->table[index], tmp); 
                curr->next = to_free;
                to_free = curr;
                curr = rcu_dereference_bh(ft->table[index]);
            }
            else { 
                // otherwise
                prev->next = curr->next;
                curr->next = to_free;
                to_free = curr;
                curr = rcu_dereference_bh(prev->next);
            }
            atomic_dec(&ft->num_flows);
        }
        else {
            // Else advance to next entry in bucket
            pr_debug("FT: active non-matching flow\n");
            prev = curr;
            curr = rcu_dereference_bh(curr->next);
        }
    }

    if(curr != NULL && flow_key_equal(match, curr->match)) {
        curr->stk = stk;
        free_match_stk_entry(new_match_stk);
    }
    else {
        tmp = rcu_dereference_bh(ft->table[index]);
        if(curr == tmp) {
          pr_debug("FT: creating new bucket entry at %d\n", index);
          new_match_stk->next = curr;
          rcu_assign_pointer(ft->table[index], new_match_stk);
        } 
        else if (curr == NULL) {
          pr_debug("FT: appending bucket entry at %d\n", index);
          rcu_assign_pointer(prev->next, new_match_stk);
        } 
        else {
          pr_debug("FT: inserting bucket entry at %d\n", index);
          new_match_stk->next = curr;
          rcu_assign_pointer(prev->next, new_match_stk);
        }
       atomic_inc(&ft->num_flows);
    }
    ft_unlock(flags);

}