return 0;
}
-static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- 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) {
- log_link_warning_errno(link, r, "Could not set bonding interface: %m");
- return 1;
- }
-
- return 1;
-}
-
-int link_set_bond(Link *link) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
-
- assert(link);
- assert(link->network);
-
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
-
- r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set netlink flags: %m");
-
- r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
-
- r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond");
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
-
- if (link->network->active_slave) {
- r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m");
- }
-
- if (link->network->primary_slave) {
- r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m");
- }
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
-
- r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
-
- link_ref(link);
-
- return r;
-}
-
int config_parse_arp_ip_target_address(
const char *unit,
const char *filename,
DEFINE_NETDEV_CAST(BOND, Bond);
extern const NetDevVTable bond_vtable;
-int link_set_bond(Link *link);
-
CONFIG_PARSER_PROTOTYPE(config_parse_bond_mode);
CONFIG_PARSER_PROTOTYPE(config_parse_bond_xmit_hash_policy);
CONFIG_PARSER_PROTOTYPE(config_parse_bond_lacp_rate);
return r;
}
-static int link_set_bridge_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- 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) {
- log_link_warning_errno(link, r, "Could not set bridge interface: %m");
- return 1;
- }
-
- return 1;
-}
-
-int link_set_bridge(Link *link) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
-
- assert(link);
- assert(link->network);
-
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
-
- r = sd_rtnl_message_link_set_family(req, AF_BRIDGE);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set message family: %m");
-
- r = sd_netlink_message_open_container(req, IFLA_PROTINFO);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
-
- if (link->network->use_bpdu >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, link->network->use_bpdu);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
- }
-
- if (link->network->hairpin >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
- }
-
- if (link->network->fast_leave >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
- }
-
- if (link->network->allow_port_to_be_root >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
- }
-
- if (link->network->unicast_flood >= 0) {
- 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_flood >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_FLOOD, link->network->multicast_flood);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_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->neighbor_suppression >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_NEIGH_SUPPRESS, link->network->neighbor_suppression);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_NEIGH_SUPPRESS attribute: %m");
- }
-
- if (link->network->learning >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_LEARNING, link->network->learning);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_LEARNING attribute: %m");
- }
-
- if (link->network->bridge_proxy_arp >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP, link->network->bridge_proxy_arp);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP attribute: %m");
- }
-
- if (link->network->bridge_proxy_arp_wifi >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP_WIFI, link->network->bridge_proxy_arp_wifi);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP_WIFI attribute: %m");
- }
-
- if (link->network->cost != 0) {
- r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
- 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)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m");
- }
-
- if (link->network->multicast_router != _MULTICAST_ROUTER_INVALID) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MULTICAST_ROUTER, link->network->multicast_router);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MULTICAST_ROUTER attribute: %m");
- }
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
-
- r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bridge_handler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
-
- link_ref(link);
-
- return r;
-}
-
int config_parse_bridge_igmp_version(
const char *unit,
const char *filename,
DEFINE_NETDEV_CAST(BRIDGE, Bridge);
extern const NetDevVTable bridge_vtable;
-int link_set_bridge(Link *link);
-
const char* multicast_router_to_string(MulticastRouter i) _const_;
MulticastRouter multicast_router_from_string(const char *s) _pure_;
return 0;
}
-static void netdev_callbacks_clear(NetDev *netdev) {
- netdev_join_callback *callback;
-
- if (!netdev)
- return;
-
- while ((callback = netdev->callbacks)) {
- LIST_REMOVE(callbacks, netdev->callbacks, callback);
- link_unref(callback->link);
- free(callback);
- }
-}
-
bool netdev_is_managed(NetDev *netdev) {
if (!netdev || !netdev->manager || !netdev->ifname)
return false;
static NetDev *netdev_free(NetDev *netdev) {
assert(netdev);
- netdev_callbacks_clear(netdev);
-
netdev_detach_from_manager(netdev);
free(netdev->filename);
log_netdev_debug(netdev, "netdev removed");
- netdev_callbacks_clear(netdev);
-
netdev_detach_from_manager(netdev);
-
netdev_unref(netdev);
-
return;
}
static int netdev_enter_failed(NetDev *netdev) {
netdev->state = NETDEV_STATE_FAILED;
-
- netdev_callbacks_clear(netdev);
-
- return 0;
-}
-
-static int netdev_enslave_ready(NetDev *netdev, Link* link, link_netlink_message_handler_t callback) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
-
- assert(netdev);
- assert(netdev->state == NETDEV_STATE_READY);
- assert(netdev->manager);
- assert(netdev->manager->rtnl);
- assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF, NETDEV_KIND_BATADV));
- assert(link);
- assert(callback);
-
- if (link->flags & IFF_UP && netdev->kind == NETDEV_KIND_BOND) {
- log_netdev_debug(netdev, "Link '%s' was up when attempting to enslave it. Bringing link down.", link->ifname);
- r = link_down(link);
- if (r < 0)
- return log_netdev_error_errno(netdev, r, "Could not bring link down: %m");
- }
-
- r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
- if (r < 0)
- return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
-
- r = sd_netlink_message_append_u32(req, IFLA_MASTER, netdev->ifindex);
- if (r < 0)
- return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m");
-
- r = netlink_call_async(netdev->manager->rtnl, NULL, req, callback,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
-
- link_ref(link);
-
- log_netdev_debug(netdev, "Enslaving link '%s'", link->ifname);
-
return 0;
}
static int netdev_enter_ready(NetDev *netdev) {
- netdev_join_callback *callback, *callback_next;
- int r;
-
assert(netdev);
assert(netdev->ifname);
log_netdev_info(netdev, "netdev ready");
- LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks) {
- /* enslave the links that were attempted to be enslaved before the
- * link was ready */
- r = netdev_enslave_ready(netdev, callback->link, callback->callback);
- if (r < 0)
- return r;
-
- LIST_REMOVE(callbacks, netdev->callbacks, callback);
- link_unref(callback->link);
- free(callback);
- }
-
if (NETDEV_VTABLE(netdev)->post_create)
NETDEV_VTABLE(netdev)->post_create(netdev, NULL, NULL);
return 1;
}
-static int netdev_enslave(NetDev *netdev, Link *link, link_netlink_message_handler_t callback) {
- int r;
-
- assert(netdev);
- assert(netdev->manager);
- assert(netdev->manager->rtnl);
- assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF, NETDEV_KIND_BATADV));
-
- if (netdev->state == NETDEV_STATE_READY) {
- r = netdev_enslave_ready(netdev, link, callback);
- if (r < 0)
- return r;
- } else if (IN_SET(netdev->state, NETDEV_STATE_LINGER, NETDEV_STATE_FAILED)) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
-
- r = rtnl_message_new_synthetic_error(netdev->manager->rtnl, -ENODEV, 0, &m);
- if (r >= 0)
- callback(netdev->manager->rtnl, m, link);
- } else {
- /* the netdev is not yet ready, save this request for when it is */
- netdev_join_callback *cb;
-
- cb = new(netdev_join_callback, 1);
- if (!cb)
- return log_oom();
-
- *cb = (netdev_join_callback) {
- .callback = callback,
- .link = link_ref(link),
- };
-
- LIST_PREPEND(callbacks, netdev->callbacks, cb);
-
- log_netdev_debug(netdev, "Will enslave '%s', when ready", link->ifname);
- }
-
- return 0;
-}
-
int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
uint16_t type;
const char *kind;
return NETDEV_VTABLE(netdev)->create_after_configured(netdev, link);
}
-/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t callback) {
int r;
assert(netdev->manager->rtnl);
switch (netdev_get_create_type(netdev)) {
- case NETDEV_CREATE_MASTER:
- r = netdev_enslave(netdev, link, callback);
- if (r < 0)
- return r;
-
- break;
case NETDEV_CREATE_STACKED:
r = netdev_create(netdev, link, callback);
if (r < 0)
if (r < 0)
return r;
- LIST_HEAD_INIT(netdev->callbacks);
-
log_netdev_debug(netdev, "loaded %s", netdev_kind_to_string(netdev->kind));
if (IN_SET(netdev_get_create_type(netdev), NETDEV_CREATE_MASTER, NETDEV_CREATE_INDEPENDENT)) {
"-WireGuardPeer\0" \
"-Xfrm\0"
-typedef struct netdev_join_callback netdev_join_callback;
-
-struct netdev_join_callback {
- link_netlink_message_handler_t callback;
- Link *link;
-
- LIST_FIELDS(netdev_join_callback, callbacks);
-};
-
typedef enum NetDevKind {
NETDEV_KIND_BRIDGE,
NETDEV_KIND_BOND,
struct ether_addr *mac;
uint32_t mtu;
int ifindex;
-
- LIST_HEAD(netdev_join_callback, callbacks);
} NetDev;
typedef struct NetDevVTable {
int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
int netdev_get_mac(const char *ifname, struct ether_addr **ret);
int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb);
-int netdev_join_after_configured(NetDev *netdev, Link *link, link_netlink_message_handler_t callback);
int request_process_create_stacked_netdev(Request *req);
int link_request_to_crate_stacked_netdev(Link *link, NetDev *netdev);
return cnt;
}
-static int set_brvlan_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- int r;
-
- assert(link);
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0 && r != -EEXIST)
- log_link_message_warning_errno(link, m, r, "Could not add VLAN to bridge port");
-
- return 1;
-}
-
-int link_set_bridge_vlan(Link *link) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
-
- assert(link);
- assert(link->manager);
- assert(link->network);
-
- if (!link->network->use_br_vlan)
- return 0;
-
- if (!link->network->bridge && !streq_ptr(link->kind, "bridge"))
- return 0;
-
- /* create new RTM message */
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
-
- r = sd_rtnl_message_link_set_family(req, AF_BRIDGE);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set message family: %m");
-
- r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
-
- /* master needs flag self */
- if (!link->network->bridge) {
- uint16_t flags = BRIDGE_FLAGS_SELF;
- r = sd_netlink_message_append_data(req, IFLA_BRIDGE_FLAGS, &flags, sizeof(flags));
- if (r < 0)
- return log_link_error_errno(link, r, "Could not open IFLA_BRIDGE_FLAGS: %m");
- }
-
- /* add vlan info */
- r = bridge_vlan_append_info(link, req, link->network->pvid, link->network->br_vid_bitmap, link->network->br_untagged_bitmap);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append VLANs: %m");
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
-
- /* send message to the kernel */
- r = netlink_call_async(link->manager->rtnl, NULL, req, set_brvlan_handler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
-
- link_ref(link);
-
- return 0;
-}
-
void network_adjust_bridge_vlan(Network *network) {
assert(network);
const uint32_t *br_vid_bitmap,
const uint32_t *br_untagged_bitmap);
-int link_set_bridge_vlan(Link *link);
-
CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_pvid);
CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_vlan);
CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_untagged);
log_link_debug(link, "Link set");
- r = link_activate(link);
+ r = link_request_to_activate(link);
if (r < 0) {
link_enter_failed(link);
return 1;
return link_set_can(link);
}
- r = link_activate(link);
+ r = link_request_to_activate(link);
if (r < 0)
return r;
if (link->set_link_messages > 0)
return false;
- /* TODO: enable this check when link_request_to_create_stacked_netdev() is used.
if (!link->stacked_netdevs_created)
return false;
- */
- /* TODO: enable this check when link_request_to_activate() is used.
if (!link->activated)
return false;
- */
return true;
}
(void) link_stop_engines(link, false);
}
-static int link_join_netdevs_after_configured(Link *link) {
- NetDev *netdev;
- int r;
-
- HASHMAP_FOREACH(netdev, link->network->stacked_netdevs) {
- if (netdev->ifindex > 0)
- /* Assume already enslaved. */
- continue;
-
- if (netdev_get_create_type(netdev) != NETDEV_CREATE_AFTER_CONFIGURED)
- continue;
-
- log_struct(LOG_DEBUG,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(netdev),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
-
- r = netdev_join(netdev, link, NULL);
- if (r < 0)
- return log_struct_errno(LOG_WARNING, r,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(netdev),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
- }
-
- return 0;
-}
-
static void link_enter_configured(Link *link) {
assert(link);
assert(link->network);
return;
link_set_state(link, LINK_STATE_CONFIGURED);
-
- (void) link_join_netdevs_after_configured(link);
}
void link_check_ready(Link *link) {
return 0;
}
-static int link_nomaster_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- int r;
-
- assert(link);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0)
- log_link_message_warning_errno(link, m, r, "Could not set nomaster, ignoring");
- else
- log_link_debug(link, "Setting nomaster done.");
-
- return 1;
-}
-
-static int link_set_nomaster(Link *link) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+static int link_request_stacked_netdevs(Link *link) {
+ NetDev *netdev;
int r;
assert(link);
- assert(link->network);
- assert(link->manager);
- assert(link->manager->rtnl);
- /* set it free if not enslaved with networkd */
- if (link->network->batadv || link->network->bridge || link->network->bond || link->network->vrf)
- return 0;
-
- log_link_debug(link, "Setting nomaster");
-
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
+ link->stacked_netdevs_created = false;
+ link->stacked_netdevs_after_configured_created = false;
- r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m");
-
- r = netlink_call_async(link->manager->rtnl, NULL, req, link_nomaster_handler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+ HASHMAP_FOREACH(netdev, link->network->stacked_netdevs) {
+ r = link_request_to_crate_stacked_netdev(link, netdev);
+ if (r < 0)
+ return r;
+ }
- link_ref(link);
+ if (link->create_stacked_netdev_messages == 0)
+ link->stacked_netdevs_created = true;
+ if (link->create_stacked_netdev_after_configured_messages == 0)
+ link->stacked_netdevs_after_configured_created = true;
return 0;
}
return link_unref(link);
}
-int link_activate(Link *link) {
- int r;
-
- assert(link);
- assert(link->network);
-
- switch (link->network->activation_policy) {
- case ACTIVATION_POLICY_BOUND:
- r = link_handle_bound_to_list(link);
- if (r < 0)
- return r;
- break;
- case ACTIVATION_POLICY_UP:
- if (link->activated)
- break;
- _fallthrough_;
- case ACTIVATION_POLICY_ALWAYS_UP:
- r = link_up(link);
- if (r < 0)
- return r;
- break;
- case ACTIVATION_POLICY_DOWN:
- if (link->activated)
- break;
- _fallthrough_;
- case ACTIVATION_POLICY_ALWAYS_DOWN:
- r = link_down(link);
- if (r < 0)
- return r;
- break;
- default:
- break;
- }
- link->activated = true;
-
- return 0;
-}
-
-static int link_joined(Link *link) {
- int r;
-
- assert(link);
- assert(link->network);
-
- r = link_activate(link);
- if (r < 0)
- return r;
-
- link_set_state(link, LINK_STATE_CONFIGURING);
-
- if (link->network->bridge) {
- r = link_set_bridge(link);
- if (r < 0)
- log_link_error_errno(link, r, "Could not set bridge message: %m");
- }
-
- if (link->network->bond) {
- r = link_set_bond(link);
- if (r < 0)
- log_link_error_errno(link, r, "Could not set bond message: %m");
- }
-
- r = link_set_bridge_vlan(link);
- if (r < 0)
- log_link_error_errno(link, r, "Could not set bridge vlan: %m");
-
- r = link_append_to_master(link);
- if (r < 0)
- return log_link_error_errno(link, r, "Failed to add to master interface's slave list: %m");
-
- r = link_request_static_configs(link);
- if (r < 0)
- return r;
-
- if (!link_has_carrier(link))
- return 0;
-
- return link_acquire_dynamic_conf(link);
-}
-
-static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- int r;
-
- assert(link);
- assert(link->network);
- assert(link->enslaving > 0);
-
- link->enslaving--;
-
- 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_message_warning_errno(link, m, r, "Could not join netdev");
- link_enter_failed(link);
- return 1;
- }
-
- log_link_debug(link, "Joined netdev");
-
- if (link->enslaving == 0) {
- r = link_joined(link);
- if (r < 0)
- link_enter_failed(link);
- }
-
- return 1;
-}
-
-int link_enter_join_netdev(Link *link) {
- NetDev *netdev;
- Request req;
- int r;
-
- assert(link);
- assert(link->network);
- assert(link->state == LINK_STATE_INITIALIZED);
-
- req = (Request) {
- .link = link,
- .type = REQUEST_TYPE_SET_LINK,
- .set_link_operation = SET_LINK_MTU,
- };
-
- if (ordered_set_contains(link->manager->request_queue, &req)) {
- link->entering_to_join_netdev = true;
- return 0;
- }
-
- link->entering_to_join_netdev = false;
-
- link_set_state(link, LINK_STATE_CONFIGURING);
-
- link->enslaving = 0;
-
- if (link->network->bond) {
- if (link->network->bond->state == NETDEV_STATE_READY &&
- link->network->bond->ifindex == link->master_ifindex)
- return link_joined(link);
-
- log_struct(LOG_DEBUG,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->bond),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname));
-
- link->enslaving++;
-
- r = netdev_join(link->network->bond, link, netdev_join_handler);
- if (r < 0) {
- log_struct_errno(LOG_WARNING, r,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->bond),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname));
- link_enter_failed(link);
- return r;
- }
- }
-
- if (link->network->batadv) {
- log_struct(LOG_DEBUG,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->batadv),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->batadv->ifname));
-
- link->enslaving++;
-
- r = netdev_join(link->network->batadv, link, netdev_join_handler);
- if (r < 0) {
- log_struct_errno(LOG_WARNING, r,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->batadv),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->batadv->ifname));
- link_enter_failed(link);
- return r;
- }
- }
-
- if (link->network->bridge) {
- log_struct(LOG_DEBUG,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->bridge),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname));
-
- link->enslaving++;
-
- r = netdev_join(link->network->bridge, link, netdev_join_handler);
- if (r < 0) {
- log_struct_errno(LOG_WARNING, r,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->bridge),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname));
- link_enter_failed(link);
- return r;
- }
- }
-
- if (link->network->vrf) {
- log_struct(LOG_DEBUG,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->vrf),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname));
-
- link->enslaving++;
-
- r = netdev_join(link->network->vrf, link, netdev_join_handler);
- if (r < 0) {
- log_struct_errno(LOG_WARNING, r,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(link->network->vrf),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname));
- link_enter_failed(link);
- return r;
- }
- }
-
- HASHMAP_FOREACH(netdev, link->network->stacked_netdevs) {
-
- if (netdev->ifindex > 0)
- /* Assume already enslaved. */
- continue;
-
- if (netdev_get_create_type(netdev) != NETDEV_CREATE_STACKED)
- continue;
-
- log_struct(LOG_DEBUG,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(netdev),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
-
- link->enslaving++;
-
- r = netdev_join(netdev, link, netdev_join_handler);
- if (r < 0) {
- log_struct_errno(LOG_WARNING, r,
- LOG_LINK_INTERFACE(link),
- LOG_NETDEV_INTERFACE(netdev),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
- link_enter_failed(link);
- return r;
- }
- }
-
- if (link->enslaving == 0)
- return link_joined(link);
-
- return 0;
-}
-
static int link_drop_foreign_config(Link *link) {
int k, r;
assert(link->network);
assert(link->state == LINK_STATE_INITIALIZED);
+ link_set_state(link, LINK_STATE_CONFIGURING);
+
r = link_configure_traffic_control(link);
if (r < 0)
return r;
if (r < 0)
return r;
- r = link_set_nomaster(link);
+ r = link_request_to_set_flags(link);
if (r < 0)
return r;
- r = link_request_to_set_flags(link);
+ r = link_request_to_set_group(link);
if (r < 0)
return r;
- r = link_request_to_set_group(link);
+ r = link_configure_mtu(link);
+ if (r < 0)
+ return r;
+
+ r = link_request_to_set_addrgen_mode(link);
+ if (r < 0)
+ return r;
+
+ r = link_request_to_set_master(link);
+ if (r < 0)
+ return r;
+
+ r = link_request_stacked_netdevs(link);
+ if (r < 0)
+ return r;
+
+ r = link_request_to_set_bond(link);
+ if (r < 0)
+ return r;
+
+ r = link_request_to_set_bridge(link);
+ if (r < 0)
+ return r;
+
+ r = link_request_to_set_bridge_vlan(link);
+ if (r < 0)
+ return r;
+
+ r = link_request_to_activate(link);
if (r < 0)
return r;
if (r < 0)
return r;
- r = link_configure_mtu(link);
- if (r < 0)
- return r;
-
- r = link_request_to_set_addrgen_mode(link);
- if (r < 0)
- return r;
-
/* Drop foreign config, but ignore loopback or critical devices.
* We do not want to remove loopback address or addresses used for root NFS. */
if (!(link->flags & IFF_LOOPBACK) &&
return r;
}
- return link_enter_join_netdev(link);
+ r = link_request_static_configs(link);
+ if (r < 0)
+ return r;
+
+ if (!link_has_carrier(link))
+ return 0;
+
+ return link_acquire_dynamic_conf(link);
}
static int link_get_network(Link *link, Network **ret) {
unsigned route_remove_messages;
unsigned tc_messages;
unsigned sr_iov_messages;
- unsigned enslaving;
unsigned set_link_messages;
unsigned create_stacked_netdev_messages;
unsigned create_stacked_netdev_after_configured_messages;
bool can_configured:1;
bool activated:1;
bool master_set:1;
- bool entering_to_join_netdev:1;
bool stacked_netdevs_created:1;
bool stacked_netdevs_after_configured_created:1;
int link_getlink_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
int link_call_getlink(Link *link, link_netlink_message_handler_t callback);
-int link_activate(Link *link);
int link_handle_bound_to_list(Link *link);
-int link_enter_join_netdev(Link *link);
void link_enter_failed(Link *link);
-
void link_set_state(Link *link, LinkState state);
void link_check_ready(Link *link);
if (r < 0)
log_link_warning_errno(link, r, "Failed to set IPv6 MTU, ignoring: %m");
- if (link->entering_to_join_netdev) {
- r = link_enter_join_netdev(link);
- if (r < 0)
- link_enter_failed(link);
- }
-
return 0;
}