コード例 #1
0
ファイル: mul_route_servlet.c プロジェクト: mxfgit/openmul
/**
 * mul_route_select_single_and_purge_list -
 * @route_list : A route list
 * @rt_select_hint : The route number to select
 *
 * Grabs a route from route list as denoted by rt_select_hint and return to caller
 * If rt_select_hint > number of routes in route list it will return NULL    
 */
static GSList *
mul_route_select_single_and_purge_list(rt_list_t *route_list, size_t rt_select_hint)
{
    GSList *route = NULL;
    rt_list_t *tmp;
    size_t rt_count = 0;

    if (!route_list) {
        return route;
    }

    while (route_list) {
        tmp = route_list;
        route_list = route_list->next;

        if (rt_count++ == rt_select_hint) {
            route = tmp->route;
        } else {
            mul_destroy_route(tmp->route);
        }

        free(tmp);
    }

    return route;
}
コード例 #2
0
ファイル: mul_route_servlet.c プロジェクト: mxfgit/openmul
/**
 * mul_route_list_free -
 *
 * Free a route list
 */
static void
mul_route_list_free(rt_list_t *path_head, bool free_route)
{
    rt_list_t *cur_path = path_head, *prev_path = NULL;

    while (cur_path) {
        prev_path = cur_path;
        cur_path = cur_path->next;
        if (free_route) {
            mul_destroy_route(prev_path->route);
        }
        free(prev_path);
    }
}
コード例 #3
0
ファイル: mul_fabric_route.c プロジェクト: ashang/openmul
/**
 * @name fab_route_get
 *
 * @brief Get a fabric route
 */
GSList *
fab_route_get(void *rt_service, int src_sw, int dst_sw,
              fab_route_t *froute)
{
    GSList *route = NULL;

    if (!fab_ctx->use_ecmp || !froute) {
        if (!(route = mul_route_get(rt_service, src_sw, dst_sw))) {
            return NULL;
        }
    } else {
        if (!(route = mul_route_get_mp(rt_service, src_sw, dst_sw,
                                       froute, fab_mp_select))) {
            return NULL;
        }
    }

    if (!g_slist_find_custom(route, froute, (GCompareFunc)fab_route_elem_valid)) {
        mul_destroy_route(route);
        return NULL;
    }
    
    return route;
}
コード例 #4
0
ファイル: mul_route_servlet.c プロジェクト: mxfgit/openmul
/**
 * mul_route_apsp_get_mp_sp -
 *
 * Get shortest path between src_sw and dest_sw. If multiple paths exists
 * it will select a path based of user provided mp_select function or the
 * first avaialbe route if mp_select is not provided
 */ 
static GSList *
mul_route_apsp_get_mp_sp(void *rt_service, int src_sw, int dest_sw, void *u_arg,
                         size_t (*mp_select)(void *u_arg, size_t max_routes))
{
    unsigned int lock, max_retries = 0;
    rt_apsp_t *rt_apsp_info = rt_service;
    GSList *route = NULL;
    rt_list_t *route_list = NULL;
    size_t mp_rt_hint = 0, num_mp_routes = 0; 
    lweight_pair_t last_hop = { NEIGH_NO_LINK, NEIGH_NO_LINK, 
                                NEIGH_NO_PATH, false };


    if (src_sw == dest_sw) {
        goto route_same_node;
    }

retry:
    if (max_retries++ >= RT_MAX_GET_RETRIES) {
        c_log_err("Too much writer contention or service died");
        return NULL;
    }

    lock = c_seq_rd_lock(&rt_apsp_info->state_info->lock);
    if (!rt_apsp_converged(rt_apsp_info)) {
        if (c_seq_rd_unlock(&rt_apsp_info->state_info->lock,
                            lock))  {
            goto retry;
        }
        c_log_err("%s: Routes not yet converged", FN);
        return NULL;
    }

    if (rt_apsp_get_weight(rt_apsp_info, src_sw, dest_sw) == NEIGH_NO_PATH) {
        if (c_seq_rd_unlock(&rt_apsp_info->state_info->lock,
                            lock))  {
            goto retry;
        }
        c_log_err("%s: Not a neigbour (%d:%d) %d", FN, src_sw, dest_sw, 
                  rt_apsp_get_weight(rt_apsp_info, src_sw, dest_sw));
        return NULL;
    }

    route_list = mul_route_apsp_get_subp(rt_apsp_info, src_sw, dest_sw);
    if (mp_select) {
        num_mp_routes = mul_route_list_size(route_list);
        mp_rt_hint = mp_select(u_arg, num_mp_routes); 
        if (mp_rt_hint >= num_mp_routes) {
            /* Silently ignore any user advice on multi-path selection */
            mp_rt_hint = 0;
        }
    }
    route = mul_route_select_single_and_purge_list(route_list, mp_rt_hint);

    if (c_seq_rd_unlock(&rt_apsp_info->state_info->lock, lock)) {
        mul_destroy_route(route);
        goto retry;
    }

route_same_node:
    add_route_path_elem(&route, dest_sw, &last_hop, true);

    mul_route_prep_out(route);

    return route;
}
コード例 #5
0
ファイル: mul_tr.c プロジェクト: jaehwanlee/open-mul
/**
 * tr_destroy_route -
 *
 * Destroy route. Utility wrapper over mul_destroy_route() 
 */
void
tr_destroy_route(GSList *route)
{
    return mul_destroy_route(route);
}