Beispiel #1
0
/* Insert a route into the table.  If successful, retains the route.
   On failure, caller must free the route. */
static struct babel_route *
insert_route(struct babel_route *route)
{
    int i, n;

    assert(!route->installed);

    i = find_route_slot(route->src->prefix, route->src->plen,
                        route->src->src_prefix, route->src->src_plen, &n);

    if(i < 0) {
        if(route_slots >= max_route_slots)
            resize_route_table(max_route_slots < 1 ? 8 : 2 * max_route_slots);
        if(route_slots >= max_route_slots)
            return NULL;
        route->next = NULL;
        if(n < route_slots)
            memmove(routes + n + 1, routes + n,
                    (route_slots - n) * sizeof(struct babel_route*));
        route_slots++;
        routes[n] = route;
    } else {
        struct babel_route *r;
        r = routes[i];
        while(r->next)
            r = r->next;
        r->next = route;
        route->next = NULL;
    }

    return route;
}
Beispiel #2
0
void
install_route(struct babel_route *route)
{
    int i, rc;

    if(route->installed)
        return;

    if(!route_feasible(route))
        fprintf(stderr, "WARNING: installing unfeasible route "
                "(this shouldn't happen).");

    i = find_route_slot(route->src->prefix, route->src->plen,
                        route->src->src_prefix, route->src->src_plen, NULL);
    assert(i >= 0 && i < route_slots);

    if(routes[i] != route && routes[i]->installed) {
        fprintf(stderr, "WARNING: attempting to install duplicate route "
                "(this shouldn't happen).");
        return;
    }

    rc = kinstall_route(route);
    if(rc < 0 && errno != EEXIST)
        return;

    route->installed = 1;
    move_installed_route(route, i);

    local_notify_route(route, LOCAL_CHANGE);
}
Beispiel #3
0
struct babel_route *
find_installed_route(const unsigned char *prefix, unsigned char plen)
{
    int i = find_route_slot(prefix, plen, NULL);

    if(i >= 0 && routes[i]->installed)
        return routes[i];

    return NULL;
}
Beispiel #4
0
void
flush_route(struct babel_route *route)
{
    int i;
    struct source *src;
    unsigned oldmetric;
    int lost = 0;

    oldmetric = route_metric(route);
    src = route->src;

    if(route->installed) {
        uninstall_route(route);
        lost = 1;
    }

    i = find_route_slot(route->src->prefix, route->src->plen,
                        route->src->src_prefix, route->src->src_plen, NULL);
    assert(i >= 0 && i < route_slots);

    local_notify_route(route, LOCAL_FLUSH);

    if(route == routes[i]) {
        routes[i] = route->next;
        route->next = NULL;
        destroy_route(route);

        if(routes[i] == NULL) {
            if(i < route_slots - 1)
                memmove(routes + i, routes + i + 1,
                        (route_slots - i - 1) * sizeof(struct babel_route*));
            routes[route_slots - 1] = NULL;
            route_slots--;
            VALGRIND_MAKE_MEM_UNDEFINED(routes + route_slots, sizeof(struct route *));
        }

        if(route_slots == 0)
            resize_route_table(0);
        else if(max_route_slots > 8 && route_slots < max_route_slots / 4)
            resize_route_table(max_route_slots / 2);
    } else {
        struct babel_route *r = routes[i];
        while(r->next != route)
            r = r->next;
        r->next = route->next;
        route->next = NULL;
        destroy_route(route);
    }

    if(lost)
        route_lost(src, oldmetric);

    release_source(src);
}
Beispiel #5
0
struct babel_route *
find_route(const unsigned char *prefix, unsigned char plen,
           struct neighbour *neigh, const unsigned char *nexthop)
{
    struct babel_route *route;
    int i = find_route_slot(prefix, plen, NULL);

    if(i < 0)
        return NULL;

    route = routes[i];

    while(route) {
        if(route->neigh == neigh && memcmp(route->nexthop, nexthop, 16) == 0)
            return route;
        route = route->next;
    }

    return NULL;
}
Beispiel #6
0
void
install_route(struct babel_route *route)
{
    int i, rc;

    if(route->installed)
        return;

    if(!route_feasible(route))
        flog_err(EC_BABEL_ROUTE, "WARNING: installing unfeasible route "
                  "(this shouldn't happen).");

    i = find_route_slot(route->src->prefix, route->src->plen, NULL);
    assert(i >= 0 && i < route_slots);

    if(routes[i] != route && routes[i]->installed) {
        flog_err(EC_BABEL_ROUTE,
		  "WARNING: attempting to install duplicate route "
                  "(this shouldn't happen).");
        return;
    }

    rc = kernel_route(ROUTE_ADD, route->src->prefix, route->src->plen,
                      route->nexthop,
                      route->neigh->ifp->ifindex,
                      metric_to_kernel(route_metric(route)), NULL, 0, 0);
    if(rc < 0) {
        int save = errno;
        flog_err(EC_BABEL_ROUTE, "kernel_route(ADD): %s",
		  safe_strerror(errno));
        if(save != EEXIST)
            return;
    }
    route->installed = 1;
    move_installed_route(route, i);

}
Beispiel #7
0
void
install_route(struct route *route)
{
    int i, rc;

    if(route->installed)
        return;

    if(!route_feasible(route))
        fprintf(stderr, "WARNING: installing unfeasible route "
                "(this shouldn't happen).");

    i = find_route_slot(route->src->prefix, route->src->plen, NULL);
    assert(i >= 0 && i < route_slots);

    if(routes[i] != route && routes[i]->installed) {
        fprintf(stderr, "WARNING: attempting to install duplicate route "
                "(this shouldn't happen).");
        return;
    }

    rc = kernel_route(ROUTE_ADD, route->src->prefix, route->src->plen,
                      route->nexthop,
                      route->neigh->ifp->ifindex,
                      metric_to_kernel(route_metric(route)), NULL, 0, 0);
    if(rc < 0) {
        int save = errno;
        perror("kernel_route(ADD)");
        if(save != EEXIST)
            return;
    }
    route->installed = 1;
    move_installed_route(route, i);

    local_notify_route(route, LOCAL_CHANGE);
}