mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-19 02:00:45 +02:00
core: add compat function for determining interface type
libnl2 and earlier do not implement rtnl_link_get_kernel() and thus we need compat code to determine whether an interface is a bond or a VLAN. Previously, the VLAN code would simply assert and cause NM to exit when running with libnl2 or earlier because the interface type could not be determined.
This commit is contained in:
parent
54dd265001
commit
82f4fd6545
2 changed files with 70 additions and 3 deletions
|
|
@ -636,7 +636,11 @@ nm_device_vlan_new (const char *udi, const char *iface, NMDevice *parent)
|
|||
int vlan_id;
|
||||
|
||||
itype = nm_system_get_iface_type (ifindex, iface);
|
||||
g_assert (itype == NM_IFACE_TYPE_VLAN);
|
||||
if (itype != NM_IFACE_TYPE_VLAN) {
|
||||
nm_log_err (LOGD_DEVICE, "(%s): failed to get VLAN interface type.", iface);
|
||||
g_object_unref (device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!nm_system_get_iface_vlan_info (ifindex, &parent_ifindex, &vlan_id)) {
|
||||
nm_log_warn (LOGD_DEVICE, "(%s): failed to get VLAN interface info.", iface);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2004 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2004 - 2012 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
|
||||
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
#include <linux/if.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/if_bonding.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
#include "nm-system.h"
|
||||
#include "nm-device.h"
|
||||
|
|
@ -1733,6 +1734,63 @@ nm_system_iface_release (gint master_ifindex,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_system_get_iface_type_compat:
|
||||
* @ifindex: interface index
|
||||
* @name: name of interface
|
||||
*
|
||||
* Lookup the type of an interface. At least one of @ifindex or @name must
|
||||
* be provided.
|
||||
*
|
||||
* Returns: Interface type (NM_IFACE_TYPE_*) or NM_IFACE_TYPE_UNSPEC.
|
||||
**/
|
||||
static int
|
||||
nm_system_compat_get_iface_type (int ifindex, const char *name)
|
||||
{
|
||||
int res = NM_IFACE_TYPE_UNSPEC;
|
||||
char *ifname = NULL;
|
||||
struct vlan_ioctl_args ifv;
|
||||
struct ifreq ifr;
|
||||
struct ifbond ifb;
|
||||
int fd;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0 || name, NM_IFACE_TYPE_UNSPEC);
|
||||
|
||||
if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
nm_log_err (LOGD_DEVICE, "couldn't open control socket.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
g_assert (ifindex > 0);
|
||||
ifname = nm_netlink_index_to_iface (ifindex);
|
||||
}
|
||||
|
||||
/* Check VLAN */
|
||||
memset (&ifv, 0, sizeof (ifv));
|
||||
ifv.cmd = GET_VLAN_VID_CMD;
|
||||
strncpy (ifv.device1, ifname ? ifname : name, sizeof (ifv.device1) - 1);
|
||||
if (ioctl (fd, SIOCGIFVLAN, &ifv) == 0) {
|
||||
res = NM_IFACE_TYPE_VLAN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* and bond */
|
||||
memset (&ifr, 0, sizeof (ifr));
|
||||
strncpy (ifr.ifr_name, ifname ? ifname : name, sizeof (ifr.ifr_name) - 1);
|
||||
memset (&ifb, 0, sizeof (ifb));
|
||||
ifr.ifr_data = (caddr_t) &ifb;
|
||||
if (ioctl (fd, SIOCBONDINFOQUERY, &ifr) == 0) {
|
||||
res = NM_IFACE_TYPE_BOND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
close (fd);
|
||||
g_free (ifname);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_system_get_iface_type:
|
||||
* @ifindex: interface index
|
||||
|
|
@ -1750,6 +1808,7 @@ nm_system_get_iface_type (int ifindex, const char *name)
|
|||
struct nl_sock *nlh;
|
||||
char *type;
|
||||
int res = NM_IFACE_TYPE_UNSPEC;
|
||||
int err;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0 || name, NM_IFACE_TYPE_UNSPEC);
|
||||
|
||||
|
|
@ -1758,8 +1817,12 @@ nm_system_get_iface_type (int ifindex, const char *name)
|
|||
goto out;
|
||||
|
||||
/* Prefer interface indexes to names */
|
||||
if (rtnl_link_get_kernel (nlh, ifindex, ifindex < 0 ? name : NULL, &result) < 0)
|
||||
err = rtnl_link_get_kernel (nlh, ifindex, ifindex < 0 ? name : NULL, &result);
|
||||
if (err < 0) {
|
||||
if (err == -NLE_OPNOTSUPP)
|
||||
res = nm_system_compat_get_iface_type (ifindex, name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
type = rtnl_link_get_type (result);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue