/* Note, here do not call route_remove_and_cancel() with 'route' directly, otherwise
* existing route(s) may be removed needlessly. */
- if (route_get(link->manager, route, &existing) >= 0) {
- /* Found an existing route that may conflict with this route. */
+ /* First, check if a conflicting route is already requested. If there is an existing route,
+ * and also an existing pending request, then the source may be updated by the request. So,
+ * we first need to check the source of the requested route. */
+ if (route_get_request(link->manager, route, &req) >= 0) {
+ existing = ASSERT_PTR(req->userdata);
if (!route_can_update(existing, route)) {
- log_link_debug(link, "Found an existing route that conflicts with new route based on a received RA, removing.");
+ if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) {
+ log_link_debug(link, "Found a pending route request that conflicts with new request based on a received RA, ignoring request.");
+ return 0;
+ }
+
+ log_link_debug(link, "Found a pending route request that conflicts with new request based on a received RA, cancelling.");
r = route_remove_and_cancel(existing, link->manager);
if (r < 0)
return r;
}
}
- if (route_get_request(link->manager, route, &req) >= 0) {
- existing = ASSERT_PTR(req->userdata);
+ /* Then, check if a conflicting route exists. */
+ if (route_get(link->manager, route, &existing) >= 0) {
if (!route_can_update(existing, route)) {
- log_link_debug(link, "Found a pending route request that conflicts with new request based on a received RA, cancelling.");
+ if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) {
+ log_link_debug(link, "Found an existing route that conflicts with new route based on a received RA, ignoring request.");
+ return 0;
+ }
+
+ log_link_debug(link, "Found an existing route that conflicts with new route based on a received RA, removing.");
r = route_remove_and_cancel(existing, link->manager);
if (r < 0)
return r;