Exemple #1
0
int
vr_fragment_table_init(struct vrouter *router)
{
    int num_entries, ret;

    if (!router->vr_fragment_table) {
        num_entries = FRAG_TABLE_ENTRIES * FRAG_TABLE_BUCKETS;
        router->vr_fragment_table = vr_btable_alloc(num_entries,
                sizeof(struct vr_fragment));
        if (!router->vr_fragment_table)
            return vr_module_error(-ENOMEM, __FUNCTION__,
                    __LINE__, num_entries);
    }

    if (!router->vr_fragment_otable) {
        num_entries = FRAG_OTABLE_ENTRIES;
        router->vr_fragment_otable = vr_btable_alloc(num_entries,
                sizeof(struct vr_fragment));
        if (!router->vr_fragment_otable)
            return vr_module_error(-ENOMEM, __FUNCTION__,
                    __LINE__, num_entries);
    }

    if ((ret = vr_fragment_table_scanner_init(router)))
        return ret;

    return 0;
}
Exemple #2
0
static int
inet_rtb_family_init(struct rtable_fspec *fs, struct vrouter *router)
{
    int ret;
    struct vr_rtable *table = NULL;
    unsigned int i;

    for (i = 0; i < RT_MAX; i++) {

        if (!fs->algo_init[i])
            continue;

        if (vr_get_inet_table(router, i))
            continue;

        table = vr_zalloc(sizeof(struct vr_rtable));
        if (!table) 
            return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, i);

        ret = fs->algo_init[i](table, fs);
        if (ret)
            return vr_module_error(ret, __FUNCTION__, __LINE__, i);

        vr_put_inet_table(router, i, table);
    }

    return 0;
}
Exemple #3
0
static int
inet_rtb_family_init(struct rtable_fspec *fs, struct vrouter *router)
{
    int ret;
    struct vr_rtable *table = NULL;
    unsigned int i;

    if (router->vr_inet_rtable || router->vr_inet_mcast_rtable)
        return vr_module_error(-EEXIST, __FUNCTION__, __LINE__, 0);

    for (i = 0; i < RT_MAX; i++) {
        if (fs->algo_init[i]) {

            table = vr_zalloc(sizeof(struct vr_rtable));
            if (!table) 
                return vr_module_error(-ENOMEM, __FUNCTION__,
                        __LINE__, i);

            ret = fs->algo_init[i](table, fs);
            if (ret)
                return vr_module_error(ret, __FUNCTION__, __LINE__, i);

            if (i == RT_UCAST) 
                router->vr_inet_rtable = table;

            if (i == RT_MCAST)
                router->vr_inet_mcast_rtable = table;
        }
    }

    return 0;
}
static int
mtrie_stats_init(struct vr_rtable *rtable)
{
    int ret = 0, i = 0;
    unsigned int stats_memory;

    if (!mtrie_vrf_stats) {
        stats_memory = sizeof(void *) * rtable->algo_max_vrfs;
        mtrie_vrf_stats = vr_zalloc(stats_memory, VR_MTRIE_STATS_OBJECT);
        if (!mtrie_vrf_stats)
            return vr_module_error(-ENOMEM, __FUNCTION__,
                    __LINE__, stats_memory);
        for (i = 0; i < rtable->algo_max_vrfs; i++) {
            stats_memory = sizeof(struct vr_vrf_stats) * vr_num_cpus;
            mtrie_vrf_stats[i] = vr_zalloc(stats_memory,
                    VR_MTRIE_STATS_OBJECT);
            if (!mtrie_vrf_stats[i] && (ret = -ENOMEM)) {
                vr_module_error(ret, __FUNCTION__, __LINE__, i);
                goto cleanup;
            }
        }

        rtable->vrf_stats = mtrie_vrf_stats;
    }

    if (!invalid_vrf_stats) {
        invalid_vrf_stats = vr_zalloc(sizeof(struct vr_vrf_stats) *
                vr_num_cpus, VR_MTRIE_STATS_OBJECT);
        if (!invalid_vrf_stats && (ret = -ENOMEM)) {
            vr_module_error(ret, __FUNCTION__, __LINE__, -1);
            goto cleanup;
        }

    }

    return 0;

cleanup:
    if (!i)
        return ret;

    for (--i; i >= 0; i--) {
        if (mtrie_vrf_stats[i]) {
            vr_free(mtrie_vrf_stats[i], VR_MTRIE_STATS_OBJECT);
            mtrie_vrf_stats[i] = NULL;
        }
    }

    if (mtrie_vrf_stats) {
        vr_free(mtrie_vrf_stats, VR_MTRIE_STATS_OBJECT);
        mtrie_vrf_stats = NULL;
    }

    if (invalid_vrf_stats) {
        vr_free(invalid_vrf_stats, VR_MTRIE_STATS_OBJECT);
        invalid_vrf_stats = NULL;
    }

    return ret;
}
static int
vr_pkt_drop_stats_init(struct vrouter *router)
{
    unsigned int i = 0;
    unsigned int size = 0;

    if (router->vr_pdrop_stats)
        return 0;

    size = sizeof(void *) * vr_num_cpus;
    router->vr_pdrop_stats = vr_zalloc(size);
    if (!router->vr_pdrop_stats) {
        vr_module_error(-ENOMEM, __FUNCTION__,
                        __LINE__, size);
        goto cleanup;
    }

    size = VP_DROP_MAX * sizeof(uint64_t);
    for (i = 0; i < vr_num_cpus; i++) {
        router->vr_pdrop_stats[i] = vr_zalloc(size);
        if (!router->vr_pdrop_stats[i]) {
            vr_module_error(-ENOMEM, __FUNCTION__,
                            __LINE__, i);
            goto cleanup;
        }
    }

    return 0;

cleanup:
    vr_pkt_drop_stats_exit(router);
    return -ENOMEM;
}
Exemple #6
0
static int
vr_flow_table_init(struct vrouter *router)
{
    if (!router->vr_flow_table) {
        if (vr_flow_entries % VR_FLOW_ENTRIES_PER_BUCKET)
            return vr_module_error(-EINVAL, __FUNCTION__,
                    __LINE__, vr_flow_entries);

        router->vr_flow_table = vr_btable_alloc(vr_flow_entries,
                sizeof(struct vr_flow_entry));
        if (!router->vr_flow_table) {
            return vr_module_error(-ENOMEM, __FUNCTION__,
                    __LINE__, vr_flow_entries);
        }
    }

    if (!router->vr_oflow_table) {
        router->vr_oflow_table = vr_btable_alloc(vr_oflow_entries,
                sizeof(struct vr_flow_entry));
        if (!router->vr_oflow_table) {
            return vr_module_error(-ENOMEM, __FUNCTION__,
                    __LINE__, vr_oflow_entries);
        }
    }

    return vr_flow_table_info_init(router);
}
Exemple #7
0
int
vr_fib_init(struct vrouter *router)
{
    int i = 0, ret, size;
    struct rtable_fspec *fs;

    if (vr_vrfs > VR_MAX_VRFS) {
        return vr_module_error(-EINVAL, __FUNCTION__, __LINE__, vr_vrfs);
    }

    router->vr_max_vrfs = vr_vrfs;

    size = (int)ARRAYSIZE(rtable_families);
    for (i = 0; i < size; i++) {
        fs = &rtable_families[i];
        fs->rtb_max_vrfs = router->vr_max_vrfs;
        ret = fs->rtb_family_init(fs, router);
        if (ret) {
            vr_module_error(ret, __FUNCTION__, __LINE__, 0);
            goto exit_init;
        }
    }

    return 0;

exit_init:
    if (!i)
        return ret;

    for (--i, --fs; i >= 0; i--) {
        fs->rtb_family_deinit(fs, router, false);
    }

    return ret;
}
int
mtrie_algo_init(struct vr_rtable *rtable, struct rtable_fspec *fs)
{
    int ret = 0;
    unsigned int table_memory;

    if (algo_init_done)
        return 0;

    if (!rtable->algo_data) {
        table_memory = 2 * sizeof(void *) * fs->rtb_max_vrfs;
        rtable->algo_data = vr_zalloc(table_memory, VR_MTRIE_TABLE_OBJECT);
        if (!rtable->algo_data)
            return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, table_memory);
    }

    rtable->algo_max_vrfs = fs->rtb_max_vrfs;
    if ((ret = mtrie_stats_init(rtable))) {
        vr_module_error(ret, __FUNCTION__, __LINE__, 0);
        goto init_fail;
    }

    rtable->algo_add = mtrie_add;
    rtable->algo_del = mtrie_delete;
    rtable->algo_lookup = mtrie_lookup;
    rtable->algo_get = mtrie_get;
    rtable->algo_dump = mtrie_dump;
    rtable->algo_stats_get = mtrie_stats_get;
    rtable->algo_stats_dump = mtrie_stats_dump;

    vr_inet_vrf_stats = mtrie_stats;
    /* local cache */
    /* ipv4 table */
    vn_rtable[0] = (struct ip_mtrie **)rtable->algo_data;
    /* ipv6 table */
    vn_rtable[1] = (struct ip_mtrie **)((unsigned char **)rtable->algo_data
                                                 + fs->rtb_max_vrfs);

    mtrie_ip_bkt_info_init(ip4_bkt_info, IP4_PREFIX_LEN);
    mtrie_ip_bkt_info_init(ip6_bkt_info, IP6_PREFIX_LEN);

    algo_init_done = 1;
    return 0;

init_fail:
    if (rtable->algo_data) {
        vr_free(rtable->algo_data, VR_MTRIE_TABLE_OBJECT);
        rtable->algo_data = NULL;
    }

    return ret;
}
Exemple #9
0
int
bridge_table_init(struct vr_rtable *rtable, struct rtable_fspec *fs)
{

    /* If table already exists, dont create again */
    if (rtable->algo_data)
        return 0;

    if (!vr_bridge_oentries)
        vr_bridge_oentries = ((vr_bridge_entries / 5) + 1023) & ~1023;

    rtable->algo_data = vr_htable_attach(vrouter_get(0), vr_bridge_entries,
                vr_bridge_table, vr_bridge_oentries, vr_bridge_otable,
                sizeof(struct vr_bridge_entry),
                sizeof(struct vr_bridge_entry_key), 0, bridge_entry_key);

    if (!rtable->algo_data)
        return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__,
                vr_bridge_entries);

    /* Max VRF's does not matter as Bridge table is not per VRF. But
     * still this can be maintained in table
     */
    rtable->algo_max_vrfs = fs->rtb_max_vrfs;
    rtable->algo_add = bridge_table_add;
    rtable->algo_del = bridge_table_delete;
    rtable->algo_lookup = bridge_table_lookup;
    rtable->algo_get = bridge_table_get;
    rtable->algo_dump = bridge_table_dump;

    vr_bridge_lookup = bridge_table_lookup;
    vn_rtable = rtable->algo_data;

    return 0;
}
Exemple #10
0
int 
vr_fib_init(struct vrouter *router)
{
    int i;
    int ret;
    int size;
    struct rtable_fspec *fs;

    size = (int)ARRAYSIZE(rtable_families);
    for (i = 0; i < size; i++) {
        fs = &rtable_families[i];
        ret = fs->rtb_family_init(fs, router);
        if (ret) {
            vr_module_error(ret, __FUNCTION__, __LINE__, i);
            goto exit_init;
        }
    }

    return 0;

exit_init:
    if (!i)
        return ret;

    for (--i, --fs; i >= 0; i--) {
        fs->rtb_family_deinit(fs, router);
    }

    return ret;
}
Exemple #11
0
int
bridge_table_init(struct vr_rtable *rtable, struct rtable_fspec *fs)
{

    /* If table already exists, dont create again */
    if (rtable->algo_data)
        return 0;

    rtable->algo_data = vr_htable_create(vr_bridge_entries,
            vr_bridge_oentries, sizeof(struct vr_bridge_entry),
            sizeof(struct vr_bridge_entry_key), bridge_entry_valid);  

    if (!rtable->algo_data)
        return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, 
                vr_bridge_entries);

    /* Max VRF's does not matter as Bridge table is not per VRF. But
     * still this can be maintained in table 
     */
    rtable->algo_max_vrfs = fs->rtb_max_vrfs;
    rtable->algo_add = bridge_table_add;
    rtable->algo_del = bridge_table_delete;
    rtable->algo_lookup = bridge_table_lookup;
    rtable->algo_get = bridge_table_get;
    rtable->algo_dump = bridge_table_dump;

    /* Add the shortcut to lookup routine */
    vr_bridge_lookup = bridge_table_lookup;
    vn_rtable = rtable->algo_data;

    return 0;
}
Exemple #12
0
static struct vr_timer *
fragment_table_scanner_init(struct vrouter *router, struct vr_btable *table)
{
    unsigned int num_entries;
    struct vr_timer *vtimer;
    struct scanner_params *scanner;

    if (!table)
        return NULL;

    num_entries = vr_btable_entries(table);

    scanner = vr_zalloc(sizeof(*scanner), VR_FRAGMENT_SCANNER_OBJECT);
    if (!scanner) {
        vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, num_entries);
        return NULL;
    }

    scanner->sp_router = router;
    scanner->sp_fragment_table = table;
    scanner->sp_num_entries = num_entries;
    scanner->sp_last_scanned_entry = -1;

    vtimer = vr_malloc(sizeof(*vtimer), VR_TIMER_OBJECT);
    if (!vtimer) {
        vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, num_entries);
        goto fail_init;
    }

    vtimer->vt_timer = fragment_table_scanner;
    vtimer->vt_vr_arg = scanner;
    vtimer->vt_msecs = 1000;

    if (vr_create_timer(vtimer)) {
        vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, num_entries);
        goto fail_init;
    }

    return vtimer;

fail_init:
    if (scanner)
        vr_free(scanner, VR_FRAGMENT_SCANNER_OBJECT);

    return NULL;
}
Exemple #13
0
static int
inet_rtb_family_init(struct rtable_fspec *fs, struct vrouter *router)
{
    int ret;

    if (!fs->algo_init)
        return 1;

    if (!router->vr_inet_rtable) {
        router->vr_inet_rtable = vr_zalloc(sizeof(struct vr_rtable));
        if (!router->vr_inet_rtable)
            return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, 0);
    }

    ret = fs->algo_init(router->vr_inet_rtable, fs);
    if (ret)
        return vr_module_error(ret, __FUNCTION__, __LINE__, 0);

    return 0;
}
Exemple #14
0
static int
bridge_rtb_family_init(struct rtable_fspec *fs, struct vrouter *router)
{
    int ret;
    struct vr_rtable *table = NULL;

    if (router->vr_bridge_rtable)
        return 0;

    if (fs->algo_init) {
        table = vr_zalloc(sizeof(struct vr_rtable));
        if (!table)
            return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, 0);

        ret = fs->algo_init(table, fs);
        if (ret)
            return vr_module_error(ret, __FUNCTION__, __LINE__, 0);
    }

    router->vr_bridge_rtable = table;
    return 0;
}
Exemple #15
0
int
vr_qos_init(struct vrouter *router)
{
    unsigned long size;

    if (!router->vr_qos_map) {
        size = vr_qos_map_entries * sizeof(struct vr_forwarding_class *);
        router->vr_qos_map = vr_zalloc(size, VR_QOS_MAP_OBJECT);
        if (!router->vr_qos_map) {
            return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, size);
        }
    }

    if (!router->vr_fc_table) {
        size = vr_fc_map_entries * sizeof(struct vr_forwarding_class);
        router->vr_fc_table = vr_zalloc(size, VR_FC_OBJECT);
        if (!router->vr_fc_table) {
            return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, size);
        }
    }

    return 0;
}
Exemple #16
0
int
vr_mirror_init(struct vrouter *router)
{
    int ret = 0;
    unsigned int size;

    if (!router->vr_mirrors) {
        router->vr_max_mirror_indices = VR_MAX_MIRROR_INDICES;
        size = sizeof(struct vr_mirror_entry *) * router->vr_max_mirror_indices;
        router->vr_mirrors = vr_zalloc(size, VR_MIRROR_TABLE_OBJECT);
        if (!router->vr_mirrors)
            return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, size);
    }

    if (!router->vr_mirror_md) {
        router->vr_mirror_md = vr_itable_create(32, 4, 8, 8, 8, 8);
        if (!router->vr_mirror_md && (ret = -ENOMEM)) {
            vr_module_error(ret, __FUNCTION__, __LINE__, 0);
            goto cleanup;
        }
    }

    return 0;

cleanup:
    if (router->vr_mirrors) {
        vr_free(router->vr_mirrors, VR_MIRROR_TABLE_OBJECT);
        router->vr_mirrors = NULL;
    }

    if (router->vr_mirror_md) {
        vr_itable_delete(router->vr_mirror_md, vr_mirror_meta_entry_destroy);
        router->vr_mirror_md = NULL;
    }

    return ret;
}
int
vr_mpls_init(struct vrouter *router)
{
    int ilm_memory;

    if (!router->vr_ilm) {
        router->vr_max_labels = VR_MAX_LABELS;
        ilm_memory = sizeof(struct vr_nexthop *) * router->vr_max_labels;
        router->vr_ilm = vr_zalloc(ilm_memory);
        if (!router->vr_ilm)
            return vr_module_error(-ENOMEM, __FUNCTION__,
                    __LINE__, ilm_memory);
    }

    return 0;
}
Exemple #18
0
static int
vr_flow_table_info_init(struct vrouter *router)
{
    unsigned int size;
    struct vr_flow_table_info *infop;

    if (router->vr_flow_table_info)
        return 0;

    size = sizeof(struct vr_flow_table_info) + sizeof(uint32_t) * vr_num_cpus;
    infop = (struct vr_flow_table_info *)vr_zalloc(size);
    if (!infop)
        return vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, size);

    router->vr_flow_table_info = infop;
    router->vr_flow_table_info_size = size;

    return 0;
}
Exemple #19
0
vr_htable_t
__vr_htable_create(struct vrouter *router, unsigned int entries,
        void *htable, unsigned int oentries, void *otable,
        unsigned int entry_size, unsigned int key_size,
        unsigned int bucket_size, get_hentry_key get_entry_key)
{
    int i;
    struct vr_htable *table;
    vr_hentry_t *ent, *prev;
    struct iovec iov;

    if (!entry_size || !entries || !get_entry_key)
        return NULL;

    if (!bucket_size)
        bucket_size = VR_HENTRIES_PER_BUCKET;

    /* Ceil to near upper number, which is dividable by bucket_size */
    entries = ((entries + bucket_size -1) / bucket_size) * bucket_size;

    table = vr_zalloc(sizeof(struct vr_htable), VR_HTABLE_OBJECT);
    if (!table) {
        vr_module_error(-ENOMEM, __FUNCTION__, __LINE__,
                                       sizeof(struct vr_htable));
        goto exit;
    }

    if (!htable) {
        table->ht_htable = vr_btable_alloc(entries, entry_size);
    } else {
        iov.iov_base = htable;
        iov.iov_len = entry_size * entries;
        table->ht_htable = vr_btable_attach(&iov, 1, entry_size);
    }

    if (!table->ht_htable) {
        vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, entries);
        goto exit;
    }

    if (oentries) {

        if (!otable) {
            table->ht_otable = vr_btable_alloc(oentries, entry_size);
        } else {
            iov.iov_base = otable;
            iov.iov_len = entry_size * oentries;
            table->ht_otable = vr_btable_attach(&iov, 1, entry_size);
        }

        if (!table->ht_otable) {
            vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, oentries);
            goto exit;
        }

        /*
         * If there is an over flow table, create the delete data for
         * main flow table
         */
        i = entries / bucket_size;
        table->ht_dtable = vr_btable_alloc(i,
                sizeof(struct vr_hentry_delete_data));
        if (!table->ht_dtable) {
            vr_module_error(-ENOMEM, __FUNCTION__, __LINE__, i);
            goto exit;
        }
    }

    for (i = 0; i < entries; i++) {
        ent = vr_btable_get(table->ht_htable, i);
        ent->hentry_index = i;
        ent->hentry_next_index = VR_INVALID_HENTRY_INDEX;
    }


    prev = NULL;
    for (i = 0; i < oentries; i++) {
        ent = vr_btable_get(table->ht_otable, i);
        ent->hentry_index = entries + i;
        ent->hentry_next_index = VR_INVALID_HENTRY_INDEX;
        if (i == 0)
            table->ht_free_oentry_head = ent;
        else
            prev->hentry_next = ent;

        ent->hentry_flags |= VR_HENTRY_FLAG_IN_FREE_LIST;
        prev = ent;
    }

    table->ht_hentries = entries;
    table->ht_oentries = oentries;
    table->ht_entry_size = entry_size;
    table->ht_key_size = key_size;
    table->ht_get_key = get_entry_key;
    table->ht_bucket_size = bucket_size;
    table->ht_router = router;
    table->ht_used_oentries = 0;

    return (vr_htable_t)table;

exit:
    vr_htable_delete((vr_htable_t)table);

    return NULL;
}