if (r < 0)
return log_error_errno(r, "Failed to initialize device monitor: %m");
- r = sd_device_monitor_set_receive_buffer_size(m->device_monitor, RCVBUF_SIZE);
- if (r < 0)
- log_warning_errno(r, "Failed to increase buffer size for device monitor, ignoring: %m");
-
r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "net", NULL);
if (r < 0)
return log_error_errno(r, "Could not add device monitor filter for net subsystem: %m");
.online_state = _LINK_ONLINE_STATE_INVALID,
.manage_foreign_routes = true,
.manage_foreign_rules = true,
+ .manage_foreign_nexthops = true,
.ethtool_fd = -EBADF,
.dhcp_duid.type = DUID_TYPE_EN,
.dhcp6_duid.type = DUID_TYPE_EN,
* by the upstream link. And the links may be referenced by netlink slots. Hence, two
* set_free() must be called after the above sd_netlink_unref(). */
m->routes = set_free(m->routes);
- m->routes_foreign = set_free(m->routes_foreign);
- m->nexthops = set_free(m->nexthops);
m->nexthops_by_id = hashmap_free(m->nexthops_by_id);
sd_event_source_unref(m->speed_meter_event_source);
log_warning_errno(r, "Failed to update state file %s, ignoring: %m", m->state_file);
HASHMAP_FOREACH(link, m->links_by_index) {
- r = link_save(link);
+ r = link_save_and_clean(link);
if (r < 0)
log_link_warning_errno(link, r, "Failed to update link state file %s, ignoring: %m", link->state_file);
}
return manager_build_dhcp_pd_subnet_ids(m);
}
-static int manager_enumerate_internal(
+int manager_enumerate_internal(
Manager *m,
sd_netlink *nl,
sd_netlink_message *req,
int (*process)(sd_netlink *, sd_netlink_message *, Manager *)) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *reply = NULL;
- int k, r;
+ int r;
assert(m);
assert(nl);
return r;
m->enumerating = true;
- for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one)) {
- k = process(nl, reply_one, m);
- if (k < 0 && r >= 0)
- r = k;
- }
+ for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one))
+ RET_GATHER(r, process(nl, reply_one, m));
m->enumerating = false;
return r;
if (r < 0)
return r;
+ r = manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link);
+ if (r < 0)
+ return r;
+
+ req = sd_netlink_message_unref(req);
+
+ r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_link_set_family(req, AF_BRIDGE);
+ if (r < 0)
+ return r;
+
return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link);
}
}
static int manager_enumerate_tclass(Manager *m) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
+ Link *link;
+ int r = 0;
assert(m);
assert(m->rtnl);
- r = sd_rtnl_message_new_traffic_control(m->rtnl, &req, RTM_GETTCLASS, 0, 0, 0);
- if (r < 0)
- return r;
+ /* TC class can be enumerated only per link. See tc_dump_tclass() in net/sched/sched_api.c. */
+
+ HASHMAP_FOREACH(link, m->links_by_index)
+ RET_GATHER(r, link_enumerate_tclass(link, 0));
- return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_tclass);
+ return r;
}
static int manager_enumerate_addresses(Manager *m) {
assert(m);
assert(m->rtnl);
+ if (!m->manage_foreign_nexthops)
+ return 0;
+
r = sd_rtnl_message_new_nexthop(m->rtnl, &req, RTM_GETNEXTHOP, 0, 0);
if (r < 0)
return r;