From a9fa1bd9e281d6c20df7a25da0cc2c6921560f1d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 21 Apr 2014 14:12:39 -0500 Subject: [PATCH] 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]: (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]: [1398107504.807205] [platform/nm-linux-platform.c:1856] link_change(): Netlink error changing link 12: 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 --- src/platform/nm-linux-platform.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 82c2fed26..ee62e4989 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -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);