From: Laine Stump <laine(a)redhat.com>
This is in response to:
https://bugzilla.redhat.com/show_bug.cgi?id=844578
If an interface's cable is unplugged and it is configured to use dhcp
(or if NetworkManager is running), attempts to ifup will fail, but
netcf will later report that the interface is active. This is because
netcf only checks the IFF_UP flag in the interface status.
It makes more sense for the interface to be counted as active only if
ifup has been successful, so this patch changes the if_is_active()
utility function to require both IFF_UP and IFF_RUNNING be set before
counting the interface as active.
However, if an interface is configured for a static IP address *and
NetworkManager isn't running*, ifup will succeed even when the cable
is unplugged. So again the active status of the interface is not
consistent with the result of ifup. To resolve this inconsistency,
this patch makes na additional check for if_is_active() after the
system's ifup utility successfully completes.
The result is consistency between the result of ifup and the
interface's flags in all cases.
Note that the 2nd change needed to be done separately in all three
linux drivers, because if_is_active() is a linux-specific function, so
it can't be called from the platform-agnostic netcf.c (yet each
platform's drv_if_up() is different, so they can't all call a common
util_if_up())..
---
src/drv_debian.c | 3 +++
src/drv_redhat.c | 3 +++
src/drv_suse.c | 3 +++
src/dutil_linux.c | 2 +-
4 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/src/drv_debian.c b/src/drv_debian.c
index dcf35eb..04953e3 100644
--- a/src/drv_debian.c
+++ b/src/drv_debian.c
@@ -1050,6 +1050,9 @@ int drv_if_up(struct netcf_if *nif) {
run1(ncf, ifup, nif->name);
ERR_BAIL(ncf);
+ ERR_THROW(!if_is_active(ncf, nif->name), ncf, EOTHER,
+ "interface %s failed to become active - "
+ "possible disconnected cable.", nif->name);
result = 0;
error:
return result;
diff --git a/src/drv_redhat.c b/src/drv_redhat.c
index 9bdcef0..06ad42a 100644
--- a/src/drv_redhat.c
+++ b/src/drv_redhat.c
@@ -1031,6 +1031,9 @@ int drv_if_up(struct netcf_if *nif) {
}
run1(ncf, ifup, nif->name);
ERR_BAIL(ncf);
+ ERR_THROW(!if_is_active(ncf, nif->name), ncf, EOTHER,
+ "interface %s failed to become active - "
+ "possible disconnected cable.", nif->name);
result = 0;
error:
free_matches(nslaves, &slaves);
diff --git a/src/drv_suse.c b/src/drv_suse.c
index 02f4ee4..7b3aa20 100644
--- a/src/drv_suse.c
+++ b/src/drv_suse.c
@@ -1174,6 +1174,9 @@ int drv_if_up(struct netcf_if *nif) {
}
run1(ncf, ifup, nif->name);
ERR_BAIL(ncf);
+ ERR_THROW(!if_is_active(ncf, nif->name), ncf, EOTHER,
+ "interface %s failed to become active - "
+ "possible disconnected cable.", nif->name);
result = 0;
error:
free_matches(nslaves, &slaves);
diff --git a/src/dutil_linux.c b/src/dutil_linux.c
index bf6d13f..3cefb9e 100644
--- a/src/dutil_linux.c
+++ b/src/dutil_linux.c
@@ -692,7 +692,7 @@ int if_is_active(struct netcf *ncf, const char *intf) {
if (ioctl(ncf->driver->ioctl_fd, SIOCGIFFLAGS, &ifr)) {
return 0;
}
- return ((ifr.ifr_flags & IFF_UP) == IFF_UP);
+ return ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING));
}
netcf_if_type_t if_type(struct netcf *ncf, const char *intf) {
--
1.7.7.6