#include "env-file.h"
#include "fd-util.h"
#include "fileio.h"
+#include "missing_network.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "networkd-ipv6-proxy-ndp.h"
DEFINE_TRIVIAL_REF_UNREF_FUNC(Link, link, link_free);
-void link_netlink_destroy_callback(void *userdata) {
- Link *link = userdata;
-
- assert(userdata);
-
- link_unref(link);
-}
-
int link_get(Manager *m, int ifindex, Link **ret) {
Link *link;
assert(link);
assert(link->network);
- if (link->state != LINK_STATE_SETTING_ROUTES)
+ if (link->state != LINK_STATE_CONFIGURING)
return;
log_link_info(link, "Configured");
if (!link->network)
return;
+ if (!link->addresses_configured)
+ return;
+
if (!link->static_routes_configured)
return;
continue;
}
- r = routing_policy_rule_configure(rule, link, link_routing_policy_rule_handler, false);
+ r = routing_policy_rule_configure(rule, link, NULL, false);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set routing policy rules: %m");
link_enter_failed(link);
return 0;
}
-static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
assert(link->route_messages > 0);
- assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
- LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
- LINK_STATE_LINGER));
+ assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
+ LINK_STATE_FAILED, LINK_STATE_LINGER));
link->route_messages--;
return 1;
}
-static int link_enter_set_routes(Link *link) {
+static int link_request_set_routes(Link *link) {
enum {
PHASE_NON_GATEWAY, /* First phase: Routes without a gateway */
PHASE_GATEWAY, /* Second phase: Routes with a gateway */
assert(link);
assert(link->network);
- assert(link->state == LINK_STATE_SETTING_ADDRESSES);
+ assert(link->addresses_configured);
+ assert(link->address_messages == 0);
+ assert(link->state != _LINK_STATE_INVALID);
- (void) link_set_routing_policy_rule(link);
+ link_set_state(link, LINK_STATE_CONFIGURING);
- link_set_state(link, LINK_STATE_SETTING_ROUTES);
+ (void) link_set_routing_policy_rule(link);
/* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
for (phase = 0; phase < _PHASE_MAX; phase++)
return 0;
}
-int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
- int r;
-
- assert(m);
- assert(link);
- assert(link->ifname);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -ESRCH)
- log_link_warning_errno(link, r, "Could not drop route: %m");
-
- return 1;
-}
-
-static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(rtnl);
assert(link);
assert(link->ifname);
assert(link->address_messages > 0);
- assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
+ assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
LINK_STATE_FAILED, LINK_STATE_LINGER));
link->address_messages--;
if (link->address_messages == 0) {
log_link_debug(link, "Addresses set");
- link_enter_set_routes(link);
+ link->addresses_configured = true;
+ link_request_set_routes(link);
}
return 1;
}
-static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
- int r;
-
- assert(rtnl);
- assert(m);
- assert(link);
- assert(link->ifname);
- assert(link->address_label_messages > 0);
-
- link->address_label_messages--;
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST)
- log_link_warning_errno(link, r, "could not set address label: %m");
- else if (r >= 0)
- manager_rtnl_process_address(rtnl, m, link->manager);
-
- if (link->address_label_messages == 0)
- log_link_debug(link, "Addresses label set");
-
- return 1;
-}
-
static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
return 0;
}
-static int link_enter_set_addresses(Link *link) {
+static int link_request_set_addresses(Link *link) {
AddressLabel *label;
Address *ad;
int r;
if (r < 0)
return r;
- link_set_state(link, LINK_STATE_SETTING_ADDRESSES);
+ link_set_state(link, LINK_STATE_CONFIGURING);
LIST_FOREACH(addresses, ad, link->network->static_addresses) {
r = address_configure(ad, link, address_handler, false);
}
LIST_FOREACH(labels, label, link->network->address_labels) {
- r = address_label_configure(label, link, address_label_handler, false);
+ r = address_label_configure(label, link, NULL, false);
if (r < 0) {
log_link_warning_errno(link, r, "Could not set address label: %m");
link_enter_failed(link);
log_link_debug(link, "Offering DHCPv4 leases");
}
- if (link->address_messages == 0)
- link_enter_set_routes(link);
- else
+ if (link->address_messages == 0) {
+ link->addresses_configured = true;
+ link_request_set_routes(link);
+ } else
log_link_debug(link, "Setting addresses");
return 0;
}
-int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
- int r;
-
- assert(m);
- assert(link);
- assert(link->ifname);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EADDRNOTAVAIL)
- log_link_warning_errno(link, r, "Could not drop address: %m");
-
- return 1;
-}
-
static int link_set_bridge_vlan(Link *link) {
int r = 0;
return 0;
}
-static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
static int link_configure_after_setting_mtu(Link *link);
-static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(m);
if (r < 0)
return log_link_error_errno(link, r, "Could not append MTU: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, set_mtu_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, set_mtu_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
return 0;
}
-static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(m);
if (r < 0)
return log_link_error_errno(link, r, "Could not set link flags: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
+ }
+ if (link->network->multicast_to_unicast >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_TO_UCAST, link->network->multicast_to_unicast);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_TO_UCAST attribute: %m");
}
if (link->network->cost != 0) {
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
}
+
if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) {
r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority);
if (r < 0)
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_set_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
return false;
}
-static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
if (r < 0)
return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not set link flags: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Failed to close netlink container: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, m, link_set_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, m, link_set_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
return r;
}
-static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
if (r < 0)
return log_link_error_errno(link, r, "Could not set link flags: %m");
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_down_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, link_down_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
return 0;
- return link_enter_set_addresses(link);
+ return link_request_set_addresses(link);
}
-static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- Link *link = userdata;
+static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(link);
assert(link->network);
assert(link->state == LINK_STATE_PENDING);
- link_set_state(link, LINK_STATE_ENSLAVING);
+ link_set_state(link, LINK_STATE_CONFIGURING);
link_dirty(link);
if (r < 0)
return log_link_error_errno(link, r, "Failed to add address: %m");
} else {
- r = address_remove(address, link, link_address_remove_handler);
+ r = address_remove(address, link, NULL);
if (r < 0)
return r;
}
if (r < 0)
return r;
} else {
- r = route_remove(route, link, link_route_remove_handler);
+ r = route_remove(route, link, NULL);
if (r < 0)
return r;
}
if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
continue;
- r = address_remove(address, link, link_address_remove_handler);
+ r = address_remove(address, link, NULL);
if (r < 0)
return r;
if (route->protocol == RTPROT_KERNEL)
continue;
- r = route_remove(route, link, link_route_remove_handler);
+ r = route_remove(route, link, NULL);
if (r < 0)
return r;
}
return 1;
}
-static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- (void) link_initialized_and_synced(userdata);
+static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+ (void) link_initialized_and_synced(link);
return 1;
}
if (r < 0)
return r;
- r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_initialized_handler,
- link_netlink_destroy_callback, link, 0, __func__);
+ r = netlink_call_async(link->manager->rtnl, NULL, req, link_initialized_handler,
+ link_netlink_destroy_callback, link);
if (r < 0)
return r;
return r;
}
- r = link_enter_set_addresses(link);
+ r = link_request_set_addresses(link);
if (r < 0)
return r;
}
if (link->state == LINK_STATE_LINGER) {
log_link_info(link, "Link readded");
- link_set_state(link, LINK_STATE_ENSLAVING);
+ link_set_state(link, LINK_STATE_CONFIGURING);
r = link_new_carrier_maps(link);
if (r < 0)
static const char* const link_state_table[_LINK_STATE_MAX] = {
[LINK_STATE_PENDING] = "pending",
- [LINK_STATE_ENSLAVING] = "configuring",
- [LINK_STATE_SETTING_ADDRESSES] = "configuring",
- [LINK_STATE_SETTING_ROUTES] = "configuring",
+ [LINK_STATE_CONFIGURING] = "configuring",
[LINK_STATE_CONFIGURED] = "configured",
[LINK_STATE_UNMANAGED] = "unmanaged",
[LINK_STATE_FAILED] = "failed",