+ uint8_t pref, pref_original = route->pref;
+ FOREACH_ARGUMENT(pref, SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_MEDIUM, SD_NDISC_PREFERENCE_HIGH) {
+ Route *existing;
+ Request *req;
+
+ /* If the preference is specified by the user config (that is, for semi-static routes),
+ * rather than RA, then only search conflicting routes that have the same preference. */
+ if (route->pref_set && pref != pref_original)
+ continue;
+
+ route->pref = pref;
+ ndisc_set_route_priority(link, route);
+
+ /* 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. */
+ 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.");
+ 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);
+ 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.");
+ r = route_remove_and_cancel(existing, link->manager);
+ if (r < 0)
+ return r;
+ }
+ }
+ }
+
+ /* The preference (and priority) may be changed in the above loop. Restore it. */
+ route->pref = pref_original;
+ ndisc_set_route_priority(link, route);
+