}
static int link_drop_foreign_config(Link *link) {
- int r;
+ int k, r;
+
+ assert(link);
+ assert(link->manager);
r = link_drop_foreign_addresses(link);
- if (r < 0)
- return r;
- r = link_drop_foreign_neighbors(link);
- if (r < 0)
- return r;
+ k = link_drop_foreign_neighbors(link);
+ if (k < 0 && r >= 0)
+ r = k;
+
+ k = link_drop_foreign_routes(link);
+ if (k < 0 && r >= 0)
+ r = k;
- return link_drop_foreign_routes(link);
+ k = manager_drop_foreign_routing_policy_rules(link->manager);
+ if (k < 0 && r >= 0)
+ r = k;
+
+ return r;
}
static int link_drop_config(Link *link) {
- int r;
+ int k, r;
+
+ assert(link);
+ assert(link->manager);
r = link_drop_addresses(link);
- if (r < 0)
- return r;
- r = link_drop_neighbors(link);
- if (r < 0)
- return r;
+ k = link_drop_neighbors(link);
+ if (k < 0 && r >= 0)
+ r = k;
- r = link_drop_routes(link);
- if (r < 0)
- return r;
+ k = link_drop_routes(link);
+ if (k < 0 && r >= 0)
+ r = k;
+
+ k = manager_drop_routing_policy_rules(link->manager, link);
+ if (k < 0 && r >= 0)
+ r = k;
ndisc_flush(link);
- return 0;
+ return r;
}
int link_configure(Link *link) {
return 0;
}
-static bool manager_links_have_routing_policy_rule(Manager *m, RoutingPolicyRule *rule) {
+static bool links_have_routing_policy_rule(const Manager *m, const RoutingPolicyRule *rule, const Link *except) {
Link *link;
assert(m);
HASHMAP_FOREACH(link, m->links) {
RoutingPolicyRule *link_rule;
+ if (link == except)
+ continue;
+
if (!link->network)
continue;
return false;
}
+int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except) {
+ RoutingPolicyRule *rule;
+ int k, r = 0;
+ Set *rules;
+
+ assert(m);
+
+ rules = foreign ? m->rules_foreign : m->rules;
+ SET_FOREACH(rule, rules) {
+ /* Do not touch rules managed by kernel. */
+ if (rule->protocol == RTPROT_KERNEL)
+ continue;
+
+ /* The rule will be configured later, or already configured by a link. */
+ if (links_have_routing_policy_rule(m, rule, except))
+ continue;
+
+ k = routing_policy_rule_remove(rule, m);
+ if (k < 0 && r >= 0)
+ r = k;
+ }
+
+ return r;
+}
+
static void routing_policy_rule_purge(Manager *m) {
RoutingPolicyRule *rule;
int r;
if (!existing)
continue; /* Saved rule does not exist anymore. */
- if (manager_links_have_routing_policy_rule(m, existing))
+ if (links_have_routing_policy_rule(m, existing, NULL))
continue; /* Existing links have the saved rule. */
/* Existing links do not have the saved rule. Let's drop the rule now, and re-configure it
int link_set_routing_policy_rules(Link *link);
int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
+int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except);
+static inline int manager_drop_foreign_routing_policy_rules(Manager *m) {
+ return manager_drop_routing_policy_rules_internal(m, true, NULL);
+}
+static inline int manager_drop_routing_policy_rules(Manager *m, const Link *except) {
+ return manager_drop_routing_policy_rules_internal(m, false, except);
+}
int routing_policy_serialize_rules(Set *rules, FILE *f);
int routing_policy_load_rules(const char *state_file, Set **rules);