mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-24 20:40:06 +01:00
core: Merge branch 'th/rh907836_rename_iface'
First set of patches to support renaming of interfaces. This is not yet fully complete, because we need to restart Rdisc too and DHCP6 will disconnect the current active connection. But this already improves the handling a lot, because the device is usable afterwards if re-activating the connection. https://bugzilla.gnome.org/show_bug.cgi?id=726177 https://bugzilla.redhat.com/show_bug.cgi?id=907836 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
commit
a0fc5098b3
4 changed files with 152 additions and 54 deletions
|
|
@ -79,6 +79,7 @@ void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout);
|
|||
void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr);
|
||||
|
||||
gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release);
|
||||
gboolean nm_device_dhcp6_renew (NMDevice *device, gboolean release);
|
||||
|
||||
void nm_device_recheck_available_connections (NMDevice *device);
|
||||
|
||||
|
|
|
|||
|
|
@ -339,6 +339,7 @@ static gboolean spec_match_list (NMDevice *device, const GSList *specs);
|
|||
static void _clear_available_connections (NMDevice *device, gboolean do_signal);
|
||||
|
||||
static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release);
|
||||
static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release);
|
||||
|
||||
static const char *reason_to_string (NMDeviceStateReason reason);
|
||||
|
||||
|
|
@ -1121,32 +1122,96 @@ link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlat
|
|||
{
|
||||
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device);
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
|
||||
int my_ifindex = nm_device_get_ifindex (device);
|
||||
gboolean change_ip_ifname = FALSE;
|
||||
|
||||
/* Ignore other devices. */
|
||||
if (ifindex != nm_device_get_ifindex (device))
|
||||
return;
|
||||
if (ifindex == my_ifindex) {
|
||||
|
||||
/* We don't filter by 'reason' because we are interested in *all* link
|
||||
* changes. For example a call to nm_platform_link_set_up() may result
|
||||
* in an internal carrier change (i.e. we ask the kernel to set IFF_UP
|
||||
* and it results in also setting IFF_LOWER_UP.
|
||||
*/
|
||||
/* We don't filter by 'reason' because we are interested in *all* link
|
||||
* changes. For example a call to nm_platform_link_set_up() may result
|
||||
* in an internal carrier change (i.e. we ask the kernel to set IFF_UP
|
||||
* and it results in also setting IFF_LOWER_UP.
|
||||
*/
|
||||
|
||||
if (info->udi && g_strcmp0 (info->udi, priv->udi)) {
|
||||
/* Update UDI to what udev gives us */
|
||||
g_free (priv->udi);
|
||||
priv->udi = g_strdup (info->udi);
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_UDI);
|
||||
if (info->udi && g_strcmp0 (info->udi, priv->udi)) {
|
||||
/* Update UDI to what udev gives us */
|
||||
g_free (priv->udi);
|
||||
priv->udi = g_strdup (info->udi);
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_UDI);
|
||||
}
|
||||
|
||||
/* Update MTU if it has changed. */
|
||||
if (priv->mtu != info->mtu) {
|
||||
priv->mtu = info->mtu;
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_MTU);
|
||||
}
|
||||
|
||||
if (info->name[0] && strcmp (priv->iface, info->name) != 0) {
|
||||
nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed iface from '%s' to '%s'",
|
||||
priv->iface, my_ifindex, priv->iface, info->name);
|
||||
g_free (priv->iface);
|
||||
priv->iface = g_strdup (info->name);
|
||||
|
||||
change_ip_ifname = !priv->ip_iface;
|
||||
if (change_ip_ifname)
|
||||
g_hash_table_remove_all (priv->ip6_saved_properties);
|
||||
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_IFACE);
|
||||
if (change_ip_ifname)
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE);
|
||||
|
||||
/* Re-match available connections against the new interface name */
|
||||
nm_device_recheck_available_connections (device);
|
||||
|
||||
/* Let any connections that use the new interface name have a chance
|
||||
* to auto-activate on the device.
|
||||
*/
|
||||
nm_device_emit_recheck_auto_activate (device);
|
||||
}
|
||||
|
||||
if (klass->link_changed)
|
||||
klass->link_changed (device, info);
|
||||
|
||||
} else if (priv->ip_iface && ifindex == nm_device_get_ip_ifindex (device)) {
|
||||
if (info->name[0] && strcmp (priv->ip_iface, info->name)) {
|
||||
nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed ip_iface (%d) from '%s' to '%s'",
|
||||
priv->iface, my_ifindex, nm_device_get_ip_ifindex (device),
|
||||
priv->ip_iface, info->name);
|
||||
g_free (priv->ip_iface);
|
||||
priv->ip_iface = g_strdup (info->name);
|
||||
|
||||
g_hash_table_remove_all (priv->ip6_saved_properties);
|
||||
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE);
|
||||
change_ip_ifname = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update MTU if it has changed. */
|
||||
if (priv->mtu != info->mtu) {
|
||||
priv->mtu = info->mtu;
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_MTU);
|
||||
if (change_ip_ifname) {
|
||||
if (priv->dhcp4_client) {
|
||||
if (!nm_device_dhcp4_renew (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (priv->dhcp6_client) {
|
||||
if (!nm_device_dhcp6_renew (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (priv->rdisc) {
|
||||
/* FIXME: todo */
|
||||
}
|
||||
if (priv->dnsmasq_manager) {
|
||||
/* FIXME: todo */
|
||||
}
|
||||
}
|
||||
|
||||
if (klass->link_changed)
|
||||
klass->link_changed (device, info);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3167,6 +3232,31 @@ dhcp6_start (NMDevice *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_dhcp6_renew (NMDevice *self, gboolean release)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMActStageReturn ret;
|
||||
NMDeviceStateReason reason;
|
||||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE);
|
||||
|
||||
nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 lease renewal requested",
|
||||
nm_device_get_iface (self));
|
||||
|
||||
/* Terminate old DHCP instance and release the old lease */
|
||||
dhcp6_cleanup (self, TRUE, release);
|
||||
|
||||
connection = nm_device_get_connection (self);
|
||||
g_assert (connection);
|
||||
|
||||
/* Start DHCP again on the interface */
|
||||
ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason);
|
||||
|
||||
return (ret != NM_ACT_STAGE_RETURN_FAILURE);
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "nm-config.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-glib-compat.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
GQuark
|
||||
nm_dhcp_manager_error_quark (void)
|
||||
|
|
@ -198,41 +199,41 @@ nm_dhcp_manager_handle_event (DBusGProxy *proxy,
|
|||
char *iface = NULL;
|
||||
char *pid_str = NULL;
|
||||
char *reason = NULL;
|
||||
unsigned long temp;
|
||||
long pid;
|
||||
|
||||
iface = get_option (options, "interface");
|
||||
if (iface == NULL) {
|
||||
nm_log_warn (LOGD_DHCP, "DHCP event didn't have associated interface.");
|
||||
nm_log_warn (LOGD_DHCP, "DHCP event: didn't have associated interface.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
pid_str = get_option (options, "pid");
|
||||
if (pid_str == NULL) {
|
||||
nm_log_warn (LOGD_DHCP, "DHCP event didn't have associated PID.");
|
||||
pid = nm_utils_ascii_str_to_int64 (pid_str, 10, 0, LONG_MAX, -1);
|
||||
if (pid == -1 || pid != (GPid)pid) {
|
||||
nm_log_warn (LOGD_DHCP, "DHCP event: couldn't convert PID '%s' to an integer", pid_str ? pid_str : "(null)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
temp = strtoul (pid_str, NULL, 10);
|
||||
if ((temp == ULONG_MAX) && (errno == ERANGE)) {
|
||||
nm_log_warn (LOGD_DHCP, "couldn't convert PID");
|
||||
goto out;
|
||||
}
|
||||
|
||||
client = get_client_for_pid (manager, (GPid) temp);
|
||||
reason = get_option (options, "reason");
|
||||
client = get_client_for_pid (manager, (GPid) pid);
|
||||
if (client == NULL) {
|
||||
nm_log_warn (LOGD_DHCP, "(pid %ld) unhandled DHCP event for interface %s", temp, iface);
|
||||
if (reason && g_ascii_strcasecmp (reason, "RELEASE") == 0) {
|
||||
/* This happens regularly, when the dhcp client gets killed and we receive its last message.
|
||||
* Don't log a warning in this case. */
|
||||
nm_log_dbg (LOGD_DHCP, "(pid %ld) unhandled RELEASE DHCP event for interface %s", pid, iface);
|
||||
} else
|
||||
nm_log_warn (LOGD_DHCP, "(pid %ld) unhandled DHCP event for interface %s", pid, iface);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp (iface, nm_dhcp_client_get_iface (client))) {
|
||||
nm_log_warn (LOGD_DHCP, "(pid %ld) received DHCP event from unexpected interface '%s' (expected '%s')",
|
||||
temp, iface, nm_dhcp_client_get_iface (client));
|
||||
pid, iface, nm_dhcp_client_get_iface (client));
|
||||
goto out;
|
||||
}
|
||||
|
||||
reason = get_option (options, "reason");
|
||||
if (reason == NULL) {
|
||||
nm_log_warn (LOGD_DHCP, "(pid %ld) DHCP event didn't have a reason", temp);
|
||||
nm_log_warn (LOGD_DHCP, "(pid %ld) DHCP event didn't have a reason", pid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -554,11 +554,13 @@ type_to_string (NMLinkType type)
|
|||
} G_STMT_END
|
||||
|
||||
static NMLinkType
|
||||
link_type_from_udev (NMPlatform *platform, int ifindex, int arptype, const char **out_name)
|
||||
link_type_from_udev (NMPlatform *platform, int ifindex, const char *ifname, int arptype, const char **out_name)
|
||||
{
|
||||
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
||||
GUdevDevice *udev_device;
|
||||
const char *prop, *name, *sysfs_path;
|
||||
const char *prop, *sysfs_path;
|
||||
|
||||
g_assert (ifname);
|
||||
|
||||
udev_device = g_hash_table_lookup (priv->udev_devices, GINT_TO_POINTER (ifindex));
|
||||
if (!udev_device)
|
||||
|
|
@ -569,9 +571,8 @@ link_type_from_udev (NMPlatform *platform, int ifindex, int arptype, const char
|
|||
return_type (NM_LINK_TYPE_OLPC_MESH, "olpc-mesh");
|
||||
|
||||
prop = g_udev_device_get_property (udev_device, "DEVTYPE");
|
||||
name = g_udev_device_get_name (udev_device);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (udev_device);
|
||||
if (g_strcmp0 (prop, "wlan") == 0 || wifi_utils_is_wifi (name, sysfs_path))
|
||||
if (g_strcmp0 (prop, "wlan") == 0 || wifi_utils_is_wifi (ifname, sysfs_path))
|
||||
return_type (NM_LINK_TYPE_WIFI, "wifi");
|
||||
else if (g_strcmp0 (prop, "wwan") == 0)
|
||||
return_type (NM_LINK_TYPE_WWAN_ETHERNET, "wwan");
|
||||
|
|
@ -664,26 +665,31 @@ link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, const char
|
|||
if (!type) {
|
||||
int arptype = rtnl_link_get_arptype (rtnllink);
|
||||
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");
|
||||
else if (arptype == 256) {
|
||||
|
||||
ifname = rtnl_link_get_name (rtnllink);
|
||||
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
|
||||
* something other than interface name to detect CTC here.
|
||||
*/
|
||||
if (g_str_has_prefix (rtnl_link_get_name (rtnllink), "ctc"))
|
||||
if (g_str_has_prefix (ifname, "ctc"))
|
||||
return_type (NM_LINK_TYPE_ETHERNET, "ethernet");
|
||||
}
|
||||
|
||||
driver = ethtool_get_driver (rtnl_link_get_name (rtnllink));
|
||||
driver = ethtool_get_driver (ifname);
|
||||
if (!g_strcmp0 (driver, "openvswitch"))
|
||||
return_type (NM_LINK_TYPE_OPENVSWITCH, "openvswitch");
|
||||
|
||||
return link_type_from_udev (platform,
|
||||
rtnl_link_get_ifindex (rtnllink),
|
||||
ifname,
|
||||
arptype,
|
||||
out_name);
|
||||
} else if (!strcmp (type, "dummy"))
|
||||
|
|
@ -827,6 +833,7 @@ hack_empty_master_iff_lower_up (NMPlatform *platform, struct nl_object *object)
|
|||
struct rtnl_link *rtnllink;
|
||||
int ifindex;
|
||||
struct nl_object *slave;
|
||||
const char *type;
|
||||
|
||||
if (!object)
|
||||
return;
|
||||
|
|
@ -837,18 +844,15 @@ hack_empty_master_iff_lower_up (NMPlatform *platform, struct nl_object *object)
|
|||
|
||||
ifindex = rtnl_link_get_ifindex (rtnllink);
|
||||
|
||||
switch (link_extract_type (platform, rtnllink, NULL)) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
case NM_LINK_TYPE_BOND:
|
||||
for (slave = nl_cache_get_first (priv->link_cache); slave; slave = nl_cache_get_next (slave)) {
|
||||
struct rtnl_link *rtnlslave = (struct rtnl_link *) slave;
|
||||
if (rtnl_link_get_master (rtnlslave) == ifindex
|
||||
&& rtnl_link_get_flags (rtnlslave) & IFF_LOWER_UP)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
type = rtnl_link_get_type (rtnllink);
|
||||
if (!type || (strcmp (type, "bridge") != 0 && strcmp (type, "bond") != 0))
|
||||
return;
|
||||
|
||||
for (slave = nl_cache_get_first (priv->link_cache); slave; slave = nl_cache_get_next (slave)) {
|
||||
struct rtnl_link *rtnlslave = (struct rtnl_link *) slave;
|
||||
if (rtnl_link_get_master (rtnlslave) == ifindex
|
||||
&& rtnl_link_get_flags (rtnlslave) & IFF_LOWER_UP)
|
||||
return;
|
||||
}
|
||||
|
||||
rtnl_link_unset_flags (rtnllink, IFF_LOWER_UP);
|
||||
|
|
@ -3032,6 +3036,7 @@ udev_device_added (NMPlatform *platform,
|
|||
auto_nl_object struct rtnl_link *rtnllink = NULL;
|
||||
const char *ifname;
|
||||
int ifindex;
|
||||
gboolean is_changed;
|
||||
|
||||
ifname = g_udev_device_get_name (udev_device);
|
||||
if (!ifname) {
|
||||
|
|
@ -3051,6 +3056,7 @@ udev_device_added (NMPlatform *platform,
|
|||
return;
|
||||
}
|
||||
|
||||
is_changed = g_hash_table_lookup_extended (priv->udev_devices, GINT_TO_POINTER (ifindex), NULL, NULL);
|
||||
g_hash_table_insert (priv->udev_devices, GINT_TO_POINTER (ifindex),
|
||||
g_object_ref (udev_device));
|
||||
|
||||
|
|
@ -3061,7 +3067,7 @@ udev_device_added (NMPlatform *platform,
|
|||
return;
|
||||
}
|
||||
|
||||
announce_object (platform, (struct nl_object *) rtnllink, ADDED, NM_PLATFORM_REASON_EXTERNAL);
|
||||
announce_object (platform, (struct nl_object *) rtnllink, is_changed ? CHANGED : ADDED, NM_PLATFORM_REASON_EXTERNAL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3124,7 +3130,7 @@ handle_udev_event (GUdevClient *client,
|
|||
action, subsys, g_udev_device_get_name (udev_device),
|
||||
ifindex ? ifindex : "unknown", seqnum);
|
||||
|
||||
if (!strcmp (action, "add"))
|
||||
if (!strcmp (action, "add") || !strcmp (action, "move"))
|
||||
udev_device_added (platform, udev_device);
|
||||
if (!strcmp (action, "remove"))
|
||||
udev_device_removed (platform, udev_device);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue