return r;
}
+void link_foreignize_addresses(Link *link) {
+ Address *address;
+
+ assert(link);
+
+ SET_FOREACH(address, link->addresses)
+ address->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+}
+
static int address_acquire(Link *link, const Address *original, Address **ret) {
_cleanup_(address_freep) Address *na = NULL;
union in_addr_union in_addr;
int link_drop_addresses(Link *link);
int link_drop_foreign_addresses(Link *link);
int link_drop_ipv6ll_addresses(Link *link);
+void link_foreignize_addresses(Link *link);
bool link_address_is_dynamic(const Link *link, const Address *address);
int link_get_ipv6_address(Link *link, const struct in6_addr *address, Address **ret);
int link_get_ipv4_address(Link *link, const struct in_addr *address, unsigned char prefixlen, Address **ret);
return r;
}
+static void link_foreignize_config(Link *link) {
+ assert(link);
+ assert(link->manager);
+
+ link_foreignize_routes(link);
+ link_foreignize_nexthops(link);
+ link_foreignize_addresses(link);
+ link_foreignize_neighbors(link);
+ link_foreignize_routing_policy_rules(link);
+}
+
static int link_configure(Link *link) {
int r;
link_drop_requests(link);
- r = link_drop_config(link);
- if (r < 0)
- return r;
+ if (network && !force)
+ /* When a new/updated .network file is assigned, first make all configs (addresses,
+ * routes, and so on) foreign, and then drop unnecessary configs later by
+ * link_drop_foreign_config() in link_configure(). */
+ link_foreignize_config(link);
+ else {
+ r = link_drop_config(link);
+ if (r < 0)
+ return r;
+ }
link_free_carrier_maps(link);
link_free_engines(link);
return r;
}
+void link_foreignize_neighbors(Link *link) {
+ Neighbor *neighbor;
+
+ assert(link);
+
+ SET_FOREACH(neighbor, link->neighbors)
+ neighbor->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+}
+
int request_process_neighbor(Request *req) {
int r;
int link_drop_neighbors(Link *link);
int link_drop_foreign_neighbors(Link *link);
+void link_foreignize_neighbors(Link *link);
int link_request_static_neighbors(Link *link);
int request_process_neighbor(Request *req);
return 0;
}
-static int manager_drop_nexthops(Manager *manager, bool foreign, const Link *except) {
+static void manager_mark_nexthops(Manager *manager, bool foreign, const Link *except) {
NextHop *nexthop;
Link *link;
- int k, r = 0;
assert(manager);
nexthop_unmark(existing);
}
}
+}
+
+static int manager_drop_nexthops(Manager *manager) {
+ NextHop *nexthop;
+ int k, r = 0;
+
+ assert(manager);
- /* Finally, remove all marked nexthops. */
SET_FOREACH(nexthop, manager->nexthops) {
if (!nexthop_is_marked(nexthop))
continue;
r = k;
}
- k = manager_drop_nexthops(link->manager, /* foreign = */ true, NULL);
+ manager_mark_nexthops(link->manager, /* foreign = */ true, NULL);
+
+ k = manager_drop_nexthops(link->manager);
if (k < 0 && r >= 0)
r = k;
r = k;
}
- k = manager_drop_nexthops(link->manager, /* foreign = */ false, link);
+ manager_mark_nexthops(link->manager, /* foreign = */ false, link);
+
+ k = manager_drop_nexthops(link->manager);
if (k < 0 && r >= 0)
r = k;
return r;
}
+void link_foreignize_nexthops(Link *link) {
+ NextHop *nexthop;
+
+ assert(link);
+
+ SET_FOREACH(nexthop, link->nexthops)
+ nexthop->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+
+ manager_mark_nexthops(link->manager, /* foreign = */ false, link);
+
+ SET_FOREACH(nexthop, link->manager->nexthops) {
+ if (!nexthop_is_marked(nexthop))
+ continue;
+
+ nexthop->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+ }
+}
+
static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
struct nexthop_grp *nhg;
int link_drop_nexthops(Link *link);
int link_drop_foreign_nexthops(Link *link);
+void link_foreignize_nexthops(Link *link);
int link_request_static_nexthops(Link *link, bool only_ipv4);
int request_process_nexthop(Request *req);
return 0;
}
-static int manager_drop_routes(Manager *manager, bool foreign, const Link *except) {
+static void manager_mark_routes(Manager *manager, bool foreign, const Link *except) {
Route *route;
Link *link;
- int k, r;
+ int r;
assert(manager);
route_unmark(existing);
}
}
+}
+
+static int manager_drop_routes(Manager *manager) {
+ Route *route;
+ int k, r = 0;
+
+ assert(manager);
- /* Finally, remove all marked routes. */
- r = 0;
SET_FOREACH(route, manager->routes) {
if (!route_is_marked(route))
continue;
r = k;
}
- k = manager_drop_routes(link->manager, /* foreign = */ true, NULL);
+ manager_mark_routes(link->manager, /* foreign = */ true, NULL);
+
+ k = manager_drop_routes(link->manager);
if (k < 0 && r >= 0)
r = k;
r = k;
}
- k = manager_drop_routes(link->manager, /* foreign = */ false, link);
+ manager_mark_routes(link->manager, /* foreign = */ false, link);
+
+ k = manager_drop_routes(link->manager);
if (k < 0 && r >= 0)
r = k;
return r;
}
+void link_foreignize_routes(Link *link) {
+ Route *route;
+
+ assert(link);
+
+ SET_FOREACH(route, link->routes)
+ route->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+
+ manager_mark_routes(link->manager, /* foreign = */ false, link);
+
+ SET_FOREACH(route, link->manager->routes) {
+ if (!route_is_marked(route))
+ continue;
+
+ route->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+ }
+}
+
static int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) {
Route *route = userdata;
int r;
int link_drop_routes(Link *link);
int link_drop_foreign_routes(Link *link);
+void link_foreignize_routes(Link *link);
void route_cancel_request(Route *route);
int link_request_route(
return r;
}
-int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except) {
+static void manager_mark_routing_policy_rules(Manager *m, bool foreign, const Link *except) {
RoutingPolicyRule *rule;
Link *link;
- int k, r;
assert(m);
}
}
}
+}
+
+int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except) {
+ RoutingPolicyRule *rule;
+ int k, r = 0;
+
+ assert(m);
+
+ manager_mark_routing_policy_rules(m, foreign, except);
- /* Finally, remove all marked rules. */
- r = 0;
SET_FOREACH(rule, m->rules) {
if (!routing_policy_rule_is_marked(rule))
continue;
return r;
}
+void link_foreignize_routing_policy_rules(Link *link) {
+ RoutingPolicyRule *rule;
+
+ assert(link);
+ assert(link->manager);
+
+ manager_mark_routing_policy_rules(link->manager, /* foreign = */ false, link);
+
+ SET_FOREACH(rule, link->manager->rules) {
+ if (!routing_policy_rule_is_marked(rule))
+ continue;
+
+ rule->source = NETWORK_CONFIG_SOURCE_FOREIGN;
+ }
+}
+
static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
return manager_drop_routing_policy_rules_internal(link->manager, false, link);
}
+void link_foreignize_routing_policy_rules(Link *link);
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(RoutingPolicyRule, routing_policy_rule);