return false;
}
+static bool link_is_static_route_configured(Link *link, Route *route) {
+ Route *net_route;
+
+ assert(link);
+ assert(route);
+
+ if (!link->network)
+ return false;
+
+ LIST_FOREACH(routes, net_route, link->network->static_routes)
+ if (route_equal(net_route, route))
+ return true;
+
+ return false;
+}
+
static int link_drop_foreign_config(Link *link) {
Address *address;
Route *route;
if (route->protocol == RTPROT_KERNEL)
continue;
- r = route_remove(route, link, link_route_remove_handler);
- if (r < 0)
- return r;
+ if (link_is_static_route_configured(link, route)) {
+ r = route_add(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, NULL);
+ if (r < 0)
+ return r;
+ } else {
+ r = route_remove(route, link, link_route_remove_handler);
+ if (r < 0)
+ return r;
+ }
}
return 0;
.compare = route_compare_func
};
+bool route_equal(Route *r1, Route *r2) {
+ if (r1 == r2)
+ return true;
+
+ if (!r1 || !r2)
+ return false;
+
+ return route_compare_func(r1, r2) == 0;
+}
+
int route_get(Link *link,
int family,
const union in_addr_union *dst,
int route_add(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
int route_add_foreign(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
void route_update(Route *route, const union in_addr_union *src, unsigned char src_prefixlen, const union in_addr_union *gw, const union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol, unsigned char type);
+bool route_equal(Route *r1, Route *r2);
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);