connectivity: fix determining the global connectivity state

Since we determine the connectivity state of each device individually,
the global connectivity state is an aggregate of all these states.

I am not sure about considering here devices that don't have the (best)
default route for their respective address family. But anyway.

When we aggregate the best connectivity, we chose the numerical largest
value. That is wrong, because PORTAL is numerically smaller than
LIMITED.

That means, if you have two devices, one with connectivity LIMITED and
one with connectivity PORTAL, then LIMITED wrongly wins.

Fixes: 6b7e9f9b22

https://bugzilla.redhat.com/show_bug.cgi?id=1619873
This commit is contained in:
Thomas Haller 2018-12-03 10:31:51 +01:00
parent 487ee687d5
commit ade753d06f
2 changed files with 8 additions and 3 deletions

View file

@ -3080,7 +3080,9 @@ nm_device_get_connectivity_state (NMDevice *self)
priv = NM_DEVICE_GET_PRIVATE (self);
return NM_MAX (priv->concheck_x[0].state, priv->concheck_x[1].state);
return NM_MAX_WITH_CMP (nm_connectivity_state_cmp,
priv->concheck_x[0].state,
priv->concheck_x[1].state);
}
/*****************************************************************************/

View file

@ -2855,18 +2855,21 @@ device_connectivity_changed (NMDevice *device,
best_state = nm_device_get_connectivity_state (device);
if (best_state < NM_CONNECTIVITY_FULL) {
/* FIXME: is this really correct, to considere devices that don't have
* (the best) default route for connectivity checking? */
c_list_for_each_entry (dev, &priv->devices_lst_head, devices_lst) {
state = nm_device_get_connectivity_state (dev);
if (state <= best_state)
if (nm_connectivity_state_cmp (state, best_state) <= 0)
continue;
best_state = state;
if (best_state >= NM_CONNECTIVITY_FULL) {
if (nm_connectivity_state_cmp (best_state, NM_CONNECTIVITY_FULL) >= 0) {
/* it doesn't get better than this. */
break;
}
}
}
nm_assert (best_state <= NM_CONNECTIVITY_FULL);
nm_assert (nm_connectivity_state_cmp (best_state, NM_CONNECTIVITY_FULL) <= 0);
if (best_state != priv->connectivity_state) {
priv->connectivity_state = best_state;