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 }
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); } }
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; }
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); }