platform: don't crash on link_change() error when ifname is NULL

to_string_link() logs link details and creates a new link to do this,
filling in the various filed in init_link().  init_link() attempts to
fill in the driver name, and might call ethtool to do that.  Well,
ethtool API only accepts an interface name (which we don't have) and
not an ifindex (which we do have), and dies.  Ensure that the ethtool
functions bail out instead of crashing if they don't get an interface
name.

Unfortunately, most callers of link_change() don't bother setting
ifindex or ifname on the link that ends up getting passed to
to_string_link(), because libnl doesn't require that when calling
rtnl_link_change().  Modify all callers to at least set the
ifindex so that to_string_link() has something useful to log.

NetworkManager[10651]: <info> (msh0): device state change: unmanaged -> unavailable (reason 'managed') [10 20 2]
NetworkManager[10651]: (platform/nm-linux-platform.c:684):link_extract_type: runtime check failed: (ifname != NULL)
NetworkManager[10651]: <error> [1398107504.807205] [platform/nm-linux-platform.c:1856] link_change(): Netlink error changing link 12:  <UP> mtu 0 (1) driver 'usb8xxx' udi '/sys/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/net/msh0': Message sequence number mismatch

    at platform/nm-linux-platform.c:691
    at platform/nm-linux-platform.c:1850
    at devices/nm-device.c:5523
    NM_DEVICE_STATE_REASON_NOW_MANAGED) at devices/nm-device.c:6662
    at nm-manager.c:2115
This commit is contained in:
Dan Williams
2014-04-21 14:12:39 -05:00
parent 0171315c78
commit a9fa1bd9e2

View File

@@ -623,6 +623,8 @@ ethtool_get_driver (const char *ifname)
{
struct ethtool_drvinfo drvinfo = { 0 };
g_return_val_if_fail (ifname != NULL, NULL);
drvinfo.cmd = ETHTOOL_GDRVINFO;
if (!ethtool_get (ifname, &drvinfo))
return NULL;
@@ -665,13 +667,15 @@ link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, const char
const char *driver;
const char *ifname;
if (arptype == ARPHRD_LOOPBACK)
return_type (NM_LINK_TYPE_LOOPBACK, "loopback");
else if (arptype == ARPHRD_INFINIBAND)
return_type (NM_LINK_TYPE_INFINIBAND, "infiniband");
ifname = rtnl_link_get_name (rtnllink);
if (!ifname)
return_type (NM_LINK_TYPE_UNKNOWN, type);
if (arptype == 256) {
/* Some s390 CTC-type devices report 256 for the encapsulation type
* for some reason, but we need to call them Ethernet. FIXME: use
@@ -1818,6 +1822,7 @@ link_change (NMPlatform *platform, int ifindex, struct rtnl_link *change)
if (!rtnllink)
return FALSE;
g_return_val_if_fail (rtnl_link_get_ifindex (change) > 0, FALSE);
nle = rtnl_link_change (priv->nlh, rtnllink, change, 0);
@@ -1943,6 +1948,7 @@ link_change_flags (NMPlatform *platform, int ifindex, unsigned int flags, gboole
auto_nl_object struct rtnl_link *change = rtnl_link_alloc ();
g_return_val_if_fail (change != NULL, FALSE);
rtnl_link_set_ifindex (change, ifindex);
if (value)
rtnl_link_set_flags (change, flags);
@@ -2093,6 +2099,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size
change = rtnl_link_alloc ();
g_return_val_if_fail (change, FALSE);
rtnl_link_set_ifindex (change, ifindex);
nladdr = nl_addr_build (AF_LLC, address, length);
g_return_val_if_fail (nladdr, FALSE);
@@ -2129,6 +2136,7 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
auto_nl_object struct rtnl_link *change = rtnl_link_alloc ();
g_return_val_if_fail (change != NULL, FALSE);
rtnl_link_set_ifindex (change, ifindex);
rtnl_link_set_mtu (change, mtu);
debug ("link: change %d: mtu %lu", ifindex, (unsigned long)mtu);
@@ -2240,6 +2248,7 @@ link_enslave (NMPlatform *platform, int master, int slave)
g_return_val_if_fail (change != NULL, FALSE);
rtnl_link_set_ifindex (change, slave);
rtnl_link_set_master (change, master);
debug ("link: change %d: enslave to master %d", slave, master);