network: extend 'enslaved' state to bridge slave interfaces

Currently, the interface's operstate is set to 'enslaved' only when
it is managed by networkd.
This commit is contained in:
Yu Watanabe 2019-02-15 12:35:30 +09:00
parent 8f1918016f
commit 34bf3c0051
2 changed files with 39 additions and 16 deletions

View File

@ -328,6 +328,24 @@ static int link_enable_ipv6(Link *link) {
return 0;
}
static bool link_is_enslaved(Link *link) {
if (link->flags & IFF_SLAVE)
/* Even if the link is not managed by networkd, honor IFF_SLAVE flag. */
return true;
if (!link->enslaved_raw)
return false;
if (!link->network)
return false;
if (link->network->bridge)
/* TODO: support the case when link is not managed by networkd. */
return true;
return false;
}
void link_update_operstate(Link *link, bool also_update_bond_master) {
LinkOperationalState operstate;
@ -373,7 +391,7 @@ void link_update_operstate(Link *link, bool also_update_bond_master) {
operstate = LINK_OPERSTATE_OFF;
if (IN_SET(operstate, LINK_OPERSTATE_DEGRADED, LINK_OPERSTATE_CARRIER) &&
link->flags & IFF_SLAVE)
link_is_enslaved(link))
operstate = LINK_OPERSTATE_ENSLAVED;
if (IN_SET(operstate, LINK_OPERSTATE_CARRIER, LINK_OPERSTATE_ENSLAVED, LINK_OPERSTATE_ROUTABLE) &&
@ -2514,6 +2532,8 @@ static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
assert(link);
assert(link->network);
assert(link->enslaving > 0);
assert(!link->enslaved_raw);
link->enslaving--;
@ -2528,8 +2548,10 @@ static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
} else
log_link_debug(link, "Joined netdev");
if (link->enslaving <= 0)
if (link->enslaving == 0) {
link->enslaved_raw = true;
link_joined(link);
}
return 1;
}
@ -2546,12 +2568,8 @@ static int link_enter_join_netdev(Link *link) {
link_set_state(link, LINK_STATE_CONFIGURING);
link_dirty(link);
if (!link->network->bridge &&
!link->network->bond &&
!link->network->vrf &&
hashmap_isempty(link->network->stacked_netdevs))
return link_joined(link);
link->enslaving = 0;
link->enslaved_raw = false;
if (link->network->bond) {
if (link->network->bond->state == NETDEV_STATE_READY &&
@ -2563,6 +2581,8 @@ static int link_enter_join_netdev(Link *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,
@ -2572,8 +2592,6 @@ static int link_enter_join_netdev(Link *link) {
link_enter_failed(link);
return r;
}
link->enslaving++;
}
if (link->network->bridge) {
@ -2582,6 +2600,8 @@ static int link_enter_join_netdev(Link *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,
@ -2591,8 +2611,6 @@ static int link_enter_join_netdev(Link *link) {
link_enter_failed(link);
return r;
}
link->enslaving++;
}
if (link->network->vrf) {
@ -2601,6 +2619,8 @@ static int link_enter_join_netdev(Link *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,
@ -2610,8 +2630,6 @@ static int link_enter_join_netdev(Link *link) {
link_enter_failed(link);
return r;
}
link->enslaving++;
}
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
@ -2626,6 +2644,8 @@ static int link_enter_join_netdev(Link *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,
@ -2635,10 +2655,11 @@ static int link_enter_join_netdev(Link *link) {
link_enter_failed(link);
return r;
}
link->enslaving++;
}
if (link->enslaving == 0)
return link_joined(link);
return 0;
}

View File

@ -76,6 +76,8 @@ typedef struct Link {
unsigned routing_policy_rule_messages;
unsigned routing_policy_rule_remove_messages;
unsigned enslaving;
/* link_is_enslaved() has additional checks. So, it is named _raw. */
bool enslaved_raw;
Set *addresses;
Set *addresses_foreign;