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; }
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; }
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); }
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); }
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; }
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); }
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); }
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); }