예제 #1
0
파일: local.c 프로젝트: guinness1/Byzantium
void
local_notify_route(struct route *route, int kind)
{
    char buf[512];
    int rc;

    if(local_socket < 0)
        return;

    rc = snprintf(buf, 512,
                  "%s route %s-%lx prefix %s installed %s "
                  "id %s metric %d refmetric %d via %s if %s\n",
                  local_kind(kind),
                  format_prefix(route->src->prefix, route->src->plen),
                  (unsigned long)route->neigh,
                  format_prefix(route->src->prefix, route->src->plen),
                  route->installed ? "yes" : "no",
                  format_eui64(route->src->id),
                  route_metric(route), route->refmetric,
                  format_address(route->neigh->address),
                  route->neigh->network->ifname);
    
    if(rc < 0 || rc >= 512)
        goto fail;

    rc = write_timeout(local_socket, buf, rc);
    if(rc < 0)
        goto fail;
    return;

 fail:
    shutdown(local_socket, 1);
    return;
}
예제 #2
0
static void
local_notify_route_1(int s, struct babel_route *route, int kind)
{
    char buf[512];
    int rc;
    const char *dst_prefix = format_prefix(route->src->prefix,
                                           route->src->plen);
    const char *src_prefix = format_prefix(route->src->src_prefix,
                                           route->src->src_plen);

    rc = snprintf(buf, 512,
                  "%s route %s-%lx-%s prefix %s from %s installed %s "
                  "id %s metric %d refmetric %d via %s if %s\n",
                  local_kind(kind),
                  dst_prefix, (unsigned long)route->neigh, src_prefix,
                  dst_prefix, src_prefix,
                  route->installed ? "yes" : "no",
                  format_eui64(route->src->id),
                  route_metric(route), route->refmetric,
                  format_address(route->neigh->address),
                  route->neigh->ifp->name);

    if(rc < 0 || rc >= 512)
        goto fail;

    rc = write_timeout(s, buf, rc);
    if(rc < 0)
        goto fail;
    return;

 fail:
    shutdown(s, 1);
    return;
}
예제 #3
0
파일: route.c 프로젝트: boutier/babeld
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);
}
예제 #4
0
static int
del_route(const struct zone *zone, const struct babel_route *route)
{
    int table = find_table(zone->dst_prefix, zone->dst_plen,
                           zone->src_prefix, zone->src_plen);
    return kernel_route(ROUTE_FLUSH, table, zone->dst_prefix, zone->dst_plen,
                        zone->src_prefix, zone->src_plen,
                        route->nexthop,
                        route->neigh->ifp->ifindex,
                        metric_to_kernel(route_metric(route)), NULL, 0, 0, 0);
}
예제 #5
0
파일: route.c 프로젝트: ton31337/frr
void
uninstall_route(struct babel_route *route)
{
    int rc;

    if(!route->installed)
        return;

    rc = kernel_route(ROUTE_FLUSH, route->src->prefix, route->src->plen,
                      route->nexthop,
                      route->neigh->ifp->ifindex,
                      metric_to_kernel(route_metric(route)), NULL, 0, 0);
    if(rc < 0)
        flog_err(EC_BABEL_ROUTE, "kernel_route(FLUSH): %s",
		  safe_strerror(errno));

    route->installed = 0;
}
예제 #6
0
파일: route.c 프로젝트: neevor/babeld
void
uninstall_route(struct route *route)
{
    int rc;

    if(!route->installed)
        return;

    rc = kernel_route(ROUTE_FLUSH, route->src->prefix, route->src->plen,
                      route->nexthop,
                      route->neigh->ifp->ifindex,
                      metric_to_kernel(route_metric(route)), NULL, 0, 0);
    if(rc < 0)
        perror("kernel_route(FLUSH)");

    route->installed = 0;
    local_notify_route(route, LOCAL_CHANGE);
}
예제 #7
0
파일: route.c 프로젝트: ton31337/frr
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);

}
예제 #8
0
파일: route.c 프로젝트: neevor/babeld
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);
}