コード例 #1
0
ファイル: route.c プロジェクト: F0rth/pimd
void calc_oifs(mrtentry_t *mrtentry_ptr, vifbitmap_t *oifs_ptr)
{
    vifbitmap_t oifs;
    mrtentry_t *grp_route;
    mrtentry_t *rp_route;

    /*
     * oifs =
     * (((copied_outgoing + my_join) - my_prune) + my_leaves)
     *              - my_asserted_oifs - incoming_interface,
     * i.e. `leaves` have higher priority than `prunes`, but lower priority
     * than `asserted`. The incoming interface is always deleted from the oifs
     */

    if (mrtentry_ptr == (mrtentry_t *)NULL) {
        VIFM_CLRALL(*oifs_ptr);
        return;
    }
    VIFM_CLRALL(oifs);
    if (!(mrtentry_ptr->flags & MRTF_PMBR)) {
        /* Either (*,G) or (S,G). Merge with the oifs from the (*,*,RP) */
        if ((rp_route =
             mrtentry_ptr->group->active_rp_grp->rp->rpentry->mrtlink)
            != (mrtentry_t *)NULL) {
            VIFM_MERGE(oifs, rp_route->joined_oifs, oifs);
            VIFM_CLR_MASK(oifs, rp_route->pruned_oifs);
            VIFM_MERGE(oifs, rp_route->leaves, oifs);
            VIFM_CLR_MASK(oifs, rp_route->asserted_oifs);
        }
    }
    if (mrtentry_ptr->flags & MRTF_SG) {
        /* (S,G) entry. Merge with the oifs from (*,G) */
        if ((grp_route = mrtentry_ptr->group->grp_route)
            != (mrtentry_t *)NULL) {
            VIFM_MERGE(oifs, grp_route->joined_oifs, oifs);
            VIFM_CLR_MASK(oifs, grp_route->pruned_oifs);
            VIFM_MERGE(oifs, grp_route->leaves, oifs);
            VIFM_CLR_MASK(oifs, grp_route->asserted_oifs);
        }
    }

    /* Calculate my own stuff */
    VIFM_MERGE(oifs, mrtentry_ptr->joined_oifs, oifs);
    VIFM_CLR_MASK(oifs, mrtentry_ptr->pruned_oifs);
    VIFM_MERGE(oifs, mrtentry_ptr->leaves, oifs);
    VIFM_CLR_MASK(oifs, mrtentry_ptr->asserted_oifs);

    VIFM_COPY(oifs, *oifs_ptr);
}
コード例 #2
0
/*
 * Initialize the children and leaf bits for route 'r', along with the
 * associated dominant, subordinate, and leaf timing data structures.
 * Return TRUE if this changes the value of either the children or
 * leaf bitmaps for 'r'.
 */
static int
init_children_and_leaves(struct rtentry *r, vifi_t parent)
{
    register vifi_t vifi;
    register struct uvif *v;
    vifbitmap_t old_children, old_leaves;

    VIFM_COPY(r->rt_children, old_children);
    VIFM_COPY(r->rt_leaves,   old_leaves  );

    VIFM_CLRALL(r->rt_children);
    VIFM_CLRALL(r->rt_leaves);
    r->rt_flags &= ~RTF_LEAF_TIMING;

    for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
        r->rt_dominants   [vifi] = 0;
        r->rt_subordinates[vifi] = 0;

        if (vifi != parent && !(v->uv_flags & (VIFF_DOWN|VIFF_DISABLED))) {
            VIFM_SET(vifi, r->rt_children);
            if (v->uv_neighbors == NULL) {
                VIFM_SET(vifi, r->rt_leaves);
                r->rt_leaf_timers[vifi] = 0;
            }
            else {
                r->rt_leaf_timers[vifi] = LEAF_CONFIRMATION_TIME;
                r->rt_flags |= RTF_LEAF_TIMING;
            }
        }
        else {
            r->rt_leaf_timers[vifi] = 0;
        }
    }

    return (!VIFM_SAME(r->rt_children, old_children) ||
            !VIFM_SAME(r->rt_leaves,   old_leaves));
}
コード例 #3
0
ファイル: mrt.c プロジェクト: CameronNemo/pimd
static mrtentry_t *alloc_mrtentry(srcentry_t *src, grpentry_t *grp)
{
    mrtentry_t *mrt;
    u_int16 i, *timer;
    u_int8  vif_numbers;

    mrt = calloc(1, sizeof(mrtentry_t));
    if (!mrt) {
	logit(LOG_WARNING, 0, "alloc_mrtentry(): out of memory");
	return NULL;
    }

    /*
     * grpnext, grpprev, srcnext, srcprev will be setup when we link the
     * mrtentry to the source and group chains
     */
    mrt->source  = src;
    mrt->group   = grp;
    mrt->incoming = NO_VIF;
    VIFM_CLRALL(mrt->joined_oifs);
    VIFM_CLRALL(mrt->leaves);
    VIFM_CLRALL(mrt->pruned_oifs);
    VIFM_CLRALL(mrt->asserted_oifs);
    VIFM_CLRALL(mrt->oifs);
    mrt->upstream = NULL;
    mrt->metric = 0;
    mrt->preference = 0;
    mrt->pmbr_addr = INADDR_ANY_N;
#ifdef RSRR
    mrt->rsrr_cache = NULL;
#endif /* RSRR */

    /* XXX: TODO: if we are short in memory, we can reserve as few as possible
     * space for vif timers (per group and/or routing entry), but then everytime
     * when a new interfaces is configured, the router will be restarted and
     * will delete the whole routing table. The "memory is cheap" solution is
     * to reserve timer space for all potential vifs in advance and then no
     * need to delete the routing table and disturb the forwarding.
     */
#ifdef SAVE_MEMORY
    mrt->vif_timers	    = (u_int16 *)calloc(1, sizeof(u_int16) * numvifs);
    mrt->vif_deletion_delay = (u_int16 *)calloc(1, sizeof(u_int16) * numvifs);
    vif_numbers = numvifs;
#else
    mrt->vif_timers	    = (u_int16 *)calloc(1, sizeof(u_int16) * total_interfaces);
    mrt->vif_deletion_delay = (u_int16 *)calloc(1, sizeof(u_int16) * total_interfaces);
    vif_numbers = total_interfaces;
#endif /* SAVE_MEMORY */
    if (!mrt->vif_timers || !mrt->vif_deletion_delay) {
	logit(LOG_WARNING, 0, "alloc_mrtentry(): out of memory");
	FREE_MRTENTRY(mrt);
	return NULL;
    }

    /* Reset the timers */
    for (i = 0, timer = mrt->vif_timers; i < vif_numbers; i++, timer++)
	RESET_TIMER(*timer);

    for (i = 0, timer = mrt->vif_deletion_delay; i < vif_numbers; i++, timer++)
	RESET_TIMER(*timer);

    mrt->flags = MRTF_NEW;
    RESET_TIMER(mrt->timer);
    RESET_TIMER(mrt->jp_timer);
    RESET_TIMER(mrt->rs_timer);
    RESET_TIMER(mrt->assert_timer);
    RESET_TIMER(mrt->assert_rate_timer);
    mrt->kernel_cache = NULL;

    return mrt;
}