ppp: merge branch 'bg/ppp-bgo559134'

Support for PPPoE on arbitrary devices.

https://bugzilla.gnome.org/show_bug.cgi?id=559134
This commit is contained in:
Beniamino Galvani 2017-08-05 08:05:14 +02:00
commit 220a329fea
30 changed files with 774 additions and 38 deletions

View file

@ -206,6 +206,8 @@ introspection_sources = \
introspection/org.freedesktop.NetworkManager.Device.Modem.h \
introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.c \
introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.h \
introspection/org.freedesktop.NetworkManager.Device.Ppp.c \
introspection/org.freedesktop.NetworkManager.Device.Ppp.h \
introspection/org.freedesktop.NetworkManager.Device.Statistics.c \
introspection/org.freedesktop.NetworkManager.Device.Statistics.h \
introspection/org.freedesktop.NetworkManager.Device.Team.c \
@ -279,6 +281,7 @@ DBUS_INTERFACE_DOCS = \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Tun.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Bridge.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.OlpcMesh.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Ppp.xml \
docs/api/dbus-org.freedesktop.NetworkManager.DHCP4Config.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Generic.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Infiniband.xml \
@ -326,6 +329,7 @@ dbusinterfaces_DATA = \
introspection/org.freedesktop.NetworkManager.Device.Macvlan.xml \
introspection/org.freedesktop.NetworkManager.Device.Modem.xml \
introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.xml \
introspection/org.freedesktop.NetworkManager.Device.Ppp.xml \
introspection/org.freedesktop.NetworkManager.Device.Statistics.xml \
introspection/org.freedesktop.NetworkManager.Device.Team.xml \
introspection/org.freedesktop.NetworkManager.Device.Tun.xml \
@ -721,6 +725,7 @@ libnm_lib_h_pub_real = \
libnm/nm-device-macvlan.h \
libnm/nm-device-modem.h \
libnm/nm-device-olpc-mesh.h \
libnm/nm-device-ppp.h \
libnm/nm-device-team.h \
libnm/nm-device-tun.h \
libnm/nm-device-vlan.h \
@ -773,6 +778,7 @@ libnm_lib_c_real = \
libnm/nm-device-macvlan.c \
libnm/nm-device-modem.c \
libnm/nm-device-olpc-mesh.c \
libnm/nm-device-ppp.c \
libnm/nm-device-team.c \
libnm/nm-device-tun.c \
libnm/nm-device-vlan.c \
@ -1388,6 +1394,8 @@ src_libNetworkManager_la_SOURCES = \
src/devices/nm-device-macsec.h \
src/devices/nm-device-macvlan.c \
src/devices/nm-device-macvlan.h \
src/devices/nm-device-ppp.c \
src/devices/nm-device-ppp.h \
src/devices/nm-device-tun.c \
src/devices/nm-device-tun.h \
src/devices/nm-device-veth.c \

View file

@ -5789,6 +5789,12 @@ static const NMMetaPropertyInfo *const property_infos_OLPC_MESH[] = {
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PPPOE
static const NMMetaPropertyInfo *const property_infos_PPPOE[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_PARENT,
.is_cli_option = TRUE,
.property_alias = "parent",
.prompt = N_("PPPoE parent device"),
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_SERVICE,
.is_cli_option = TRUE,
.property_alias = "service",

View file

@ -280,6 +280,7 @@
#define DESCRIBE_DOC_NM_SETTING_PPP_REQUIRE_MPPE N_("If TRUE, MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session. If either 64-bit or 128-bit MPPE is not available the session will fail. Note that MPPE is not used on mobile broadband connections.")
#define DESCRIBE_DOC_NM_SETTING_PPP_REQUIRE_MPPE_128 N_("If TRUE, 128-bit MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session, and the \"require-mppe\" property must also be set to TRUE. If 128-bit MPPE is not available the session will fail.")
#define DESCRIBE_DOC_NM_SETTING_PPPOE_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".")
#define DESCRIBE_DOC_NM_SETTING_PPPOE_PARENT N_("If given, specifies the parent interface name on which this PPPoE connection should be created. If this property is not specified, the connection is activated on the interface specified in \"interface-name\" of NMSettingConnection.")
#define DESCRIBE_DOC_NM_SETTING_PPPOE_PASSWORD N_("Password used to authenticate with the PPPoE service.")
#define DESCRIBE_DOC_NM_SETTING_PPPOE_PASSWORD_FLAGS N_("Flags indicating how to handle the \"password\" property.")
#define DESCRIBE_DOC_NM_SETTING_PPPOE_SERVICE N_("If specified, instruct PPPoE to only initiate sessions with access concentrators that provide the specified service. For most providers, this should be left blank. It is only required if there are multiple access concentrators or a specific service is known to be required.")

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<!--
org.freedesktop.NetworkManager.Device.Ppp:
@short_description: PPP Device
-->
<interface name="org.freedesktop.NetworkManager.Device.Ppp">
<!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
DEPRECATED. Use the standard "PropertiesChanged" signal from "org.freedesktop.DBus.Properties" instead which exists since version NetworkManager 1.2.0.
-->
<signal name="PropertiesChanged">
<arg name="properties" type="a{sv}"/>
</signal>
</interface>
</node>

View file

@ -1952,6 +1952,13 @@ nm_connection_is_virtual (NMConnection *connection)
if (nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME))
return !!_nm_connection_get_setting_bluetooth_for_nap (connection);
if (nm_streq (type, NM_SETTING_PPPOE_SETTING_NAME)) {
NMSettingPppoe *s_pppoe;
s_pppoe = nm_connection_get_setting_pppoe (connection);
return !!nm_setting_pppoe_get_parent (s_pppoe);
}
return FALSE;
}

View file

@ -68,6 +68,7 @@
#define NM_DBUS_INTERFACE_DEVICE_TUN NM_DBUS_INTERFACE_DEVICE ".Tun"
#define NM_DBUS_INTERFACE_DEVICE_MACSEC NM_DBUS_INTERFACE_DEVICE ".Macsec"
#define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan"
#define NM_DBUS_INTERFACE_DEVICE_PPP NM_DBUS_INTERFACE_DEVICE ".Ppp"
#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan"
#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre"
#define NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL NM_DBUS_INTERFACE_DEVICE ".IPTunnel"
@ -203,6 +204,7 @@ typedef enum {
* @NM_DEVICE_TYPE_VETH: a VETH interface
* @NM_DEVICE_TYPE_MACSEC: a MACsec interface
* @NM_DEVICE_TYPE_DUMMY: a dummy interface
* @NM_DEVICE_TYPE_PPP: a PPP interface
*
* #NMDeviceType values indicate the type of hardware represented by a
* device object.
@ -231,6 +233,7 @@ typedef enum {
NM_DEVICE_TYPE_VETH = 20,
NM_DEVICE_TYPE_MACSEC = 21,
NM_DEVICE_TYPE_DUMMY = 22,
NM_DEVICE_TYPE_PPP = 23,
} NMDeviceType;
/**

View file

@ -45,6 +45,7 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_PPPOE)
#define NM_SETTING_PPPOE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PPPOE, NMSettingPppoePrivate))
typedef struct {
char *parent;
char *service;
char *username;
char *password;
@ -53,6 +54,7 @@ typedef struct {
enum {
PROP_0,
PROP_PARENT,
PROP_SERVICE,
PROP_USERNAME,
PROP_PASSWORD,
@ -74,6 +76,22 @@ nm_setting_pppoe_new (void)
return (NMSetting *) g_object_new (NM_TYPE_SETTING_PPPOE, NULL);
}
/**
* nm_setting_pppoe_get_parent:
* @setting: the #NMSettingPppoe
*
* Returns: the #NMSettingPppoe:parent property of the setting
*
* Since: 1.10
**/
const char *
nm_setting_pppoe_get_parent (NMSettingPppoe *setting)
{
g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NULL);
return NM_SETTING_PPPOE_GET_PRIVATE (setting)->parent;
}
/**
* nm_setting_pppoe_get_service:
* @setting: the #NMSettingPppoe
@ -134,6 +152,7 @@ static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (setting);
gs_free_error GError *local_error = NULL;
if (!priv->username) {
g_set_error_literal (error,
@ -160,6 +179,16 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
if ( priv->parent
&& !nm_utils_is_valid_iface_name (priv->parent, &local_error)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
"'%s': %s", priv->parent, local_error->message);
g_prefix_error (error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_PARENT);
return FALSE;
}
return TRUE;
}
@ -192,6 +221,10 @@ set_property (GObject *object, guint prop_id,
NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (object);
switch (prop_id) {
case PROP_PARENT:
g_free (priv->parent);
priv->parent = g_value_dup_string (value);
break;
case PROP_SERVICE:
g_free (priv->service);
priv->service = g_value_dup_string (value);
@ -220,6 +253,9 @@ get_property (GObject *object, guint prop_id,
NMSettingPppoe *setting = NM_SETTING_PPPOE (object);
switch (prop_id) {
case PROP_PARENT:
g_value_set_string (value, nm_setting_pppoe_get_parent (setting));
break;
case PROP_SERVICE:
g_value_set_string (value, nm_setting_pppoe_get_service (setting));
break;
@ -266,6 +302,25 @@ nm_setting_pppoe_class_init (NMSettingPppoeClass *setting_class)
parent_class->need_secrets = need_secrets;
/* Properties */
/**
* NMSettingPppoe:parent:
*
* If given, specifies the parent interface name on which this PPPoE
* connection should be created. If this property is not specified,
* the connection is activated on the interface specified in
* #NMSettingConnection:interface-name of #NMSettingConnection.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_PARENT,
g_param_spec_string (NM_SETTING_PPPOE_PARENT, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingPppoe:service:
*

View file

@ -40,6 +40,7 @@ G_BEGIN_DECLS
#define NM_SETTING_PPPOE_SETTING_NAME "pppoe"
#define NM_SETTING_PPPOE_PARENT "parent"
#define NM_SETTING_PPPOE_SERVICE "service"
#define NM_SETTING_PPPOE_USERNAME "username"
#define NM_SETTING_PPPOE_PASSWORD "password"
@ -64,6 +65,8 @@ typedef struct {
GType nm_setting_pppoe_get_type (void);
NMSetting *nm_setting_pppoe_new (void);
NM_AVAILABLE_IN_1_10
const char *nm_setting_pppoe_get_parent (NMSettingPppoe *setting);
const char *nm_setting_pppoe_get_service (NMSettingPppoe *setting);
const char *nm_setting_pppoe_get_username (NMSettingPppoe *setting);
const char *nm_setting_pppoe_get_password (NMSettingPppoe *setting);

View file

@ -1181,7 +1181,9 @@ global:
libnm_1_10_0 {
global:
nm_device_dummy_get_hw_address;
nm_device_ppp_get_type;
nm_setting_bridge_get_group_forward_mask;
nm_setting_pppoe_get_parent;
nm_setting_wireless_security_get_pmf;
nm_setting_wireless_security_get_wps_method;
nm_setting_wireless_security_pmf_get_type;

View file

@ -63,6 +63,7 @@
#include "nm-device-macvlan.h"
#include "nm-device-modem.h"
#include "nm-device-olpc-mesh.h"
#include "nm-device-ppp.h"
#include "nm-device-team.h"
#include "nm-device-tun.h"
#include "nm-device-vlan.h"
@ -2078,6 +2079,8 @@ obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager
type = NM_TYPE_DEVICE_MODEM;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH) == 0)
type = NM_TYPE_DEVICE_OLPC_MESH;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_PPP) == 0)
type = NM_TYPE_DEVICE_PPP;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_TEAM) == 0)
type = NM_TYPE_DEVICE_TEAM;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_TUN) == 0)

39
libnm/nm-device-ppp.c Normal file
View file

@ -0,0 +1,39 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-device-ppp.h"
#include "nm-device.h"
struct _NMDevicePpp {
NMDevice parent;
};
struct _NMDevicePppClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDevicePpp, nm_device_ppp, NM_TYPE_DEVICE)
#define NM_DEVICE_PPP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_PPP, NMDevicePppPrivate))
static void
nm_device_ppp_init (NMDevicePpp *device)
{
}
static void
nm_device_ppp_class_init (NMDevicePppClass *klass)
{
}

36
libnm/nm-device-ppp.h Normal file
View file

@ -0,0 +1,36 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_PPP_H__
#define __NM_DEVICE_PPP_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
G_BEGIN_DECLS
#define NM_TYPE_DEVICE_PPP (nm_device_ppp_get_type ())
#define NM_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_PPP, NMDevicePpp))
#define NM_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_PPP, NMDevicePppClass))
#define NM_IS_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_PPP))
#define NM_IS_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_PPP))
#define NM_DEVICE_PPP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_PPP, NMDevicePppClass))
typedef struct _NMDevicePppClass NMDevicePppClass;
GType nm_device_ppp_get_type (void);
G_END_DECLS
#endif /* __NM_DEVICE_PPP_H__ */

View file

@ -280,6 +280,7 @@ coerce_type (NMDeviceType type)
case NM_DEVICE_TYPE_UNUSED2:
case NM_DEVICE_TYPE_UNKNOWN:
case NM_DEVICE_TYPE_DUMMY:
case NM_DEVICE_TYPE_PPP:
return type;
}
return NM_DEVICE_TYPE_UNKNOWN;
@ -1551,6 +1552,8 @@ get_type_name (NMDevice *device)
return _("MACsec");
case NM_DEVICE_TYPE_DUMMY:
return _("Dummy");
case NM_DEVICE_TYPE_PPP:
return _("PPP");
case NM_DEVICE_TYPE_GENERIC:
case NM_DEVICE_TYPE_UNUSED1:
case NM_DEVICE_TYPE_UNUSED2:

View file

@ -43,6 +43,7 @@ typedef struct _NMDeviceMacsec NMDeviceMacsec;
typedef struct _NMDeviceMacvlan NMDeviceMacvlan;
typedef struct _NMDeviceModem NMDeviceModem;
typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh;
typedef struct _NMDevicePpp NMDevicePpp;
typedef struct _NMDeviceTeam NMDeviceTeam;
typedef struct _NMDeviceTun NMDeviceTun;
typedef struct _NMDeviceVlan NMDeviceVlan;

View file

@ -26,6 +26,7 @@
#include <gmodule.h>
#include "devices/nm-device-factory.h"
#include "devices/nm-device-bridge.h"
#include "nm-setting-bluetooth.h"
#include "settings/nm-settings.h"
#include "nm-bluez4-manager.h"
@ -417,6 +418,21 @@ create_device (NMDeviceFactory *factory,
return NULL;
}
static gboolean
match_connection (NMDeviceFactory *factory,
NMConnection *connection)
{
const char *type = nm_connection_get_connection_type (connection);
nm_assert (nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME));
if ( nm_bt_vtable_network_server
&& _nm_connection_get_setting_bluetooth_for_nap (connection))
return FALSE; /* handled by the bridge factory */
return TRUE;
}
/*****************************************************************************/
static void
@ -461,5 +477,6 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass)
factory_class->get_supported_types = get_supported_types;
factory_class->create_device = create_device;
factory_class->match_connection = match_connection;
factory_class->start = start;
}

View file

@ -538,8 +538,24 @@ create_device (NMDeviceFactory *factory,
NULL);
}
static gboolean
match_connection (NMDeviceFactory *factory,
NMConnection *connection)
{
const char *type = nm_connection_get_connection_type (connection);
if (nm_streq (type, NM_SETTING_BRIDGE_SETTING_NAME))
return TRUE;
nm_assert (nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME));
return nm_bt_vtable_network_server
&& _nm_connection_get_setting_bluetooth_for_nap (connection);
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL (BRIDGE, Bridge, bridge,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_BRIDGE)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BRIDGE_SETTING_NAME),
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BLUETOOTH_SETTING_NAME),
factory_class->create_device = create_device;
factory_class->match_connection = match_connection;
);

View file

@ -108,7 +108,6 @@ typedef struct _NMDeviceEthernetPrivate {
/* PPPoE */
NMPPPManager *ppp_manager;
NMIP4Config *pending_ip4_config;
gint32 last_pppoe_time;
guint pppoe_wait_id;
@ -1353,11 +1352,6 @@ deactivate (NMDevice *device)
nm_clear_g_source (&priv->pppoe_wait_id);
if (priv->pending_ip4_config) {
g_object_unref (priv->pending_ip4_config);
priv->pending_ip4_config = NULL;
}
if (priv->ppp_manager) {
nm_ppp_manager_stop_sync (priv->ppp_manager);
g_clear_object (&priv->ppp_manager);
@ -1802,8 +1796,24 @@ create_device (NMDeviceFactory *factory,
NULL);
}
static gboolean
match_connection (NMDeviceFactory *factory, NMConnection *connection)
{
const char *type = nm_connection_get_connection_type (connection);
NMSettingPppoe *s_pppoe;
if (nm_streq (type, NM_SETTING_WIRED_SETTING_NAME))
return TRUE;
nm_assert (nm_streq (type, NM_SETTING_PPPOE_SETTING_NAME));
s_pppoe = nm_connection_get_setting_pppoe (connection);
return !nm_setting_pppoe_get_parent (s_pppoe);
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL (ETHERNET, Ethernet, ethernet,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_ETHERNET)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_PPPOE_SETTING_NAME),
factory_class->create_device = create_device;
factory_class->match_connection = match_connection;
);

View file

@ -235,34 +235,24 @@ nm_device_factory_manager_find_factory_for_link_type (NMLinkType link_type)
NMDeviceFactory *
nm_device_factory_manager_find_factory_for_connection (NMConnection *connection)
{
NMDeviceFactoryClass *klass;
NMDeviceFactory *factory;
const char *type;
GSList *list;
g_return_val_if_fail (factories_by_setting, NULL);
type = nm_connection_get_connection_type (connection);
list = g_hash_table_lookup (factories_by_setting, type);
if ( nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME)
&& _nm_connection_get_setting_bluetooth_for_nap (connection)) {
/* for Bluetooth NAP connections, we return the bridge factory
* instead of the bluetooth factory.
*
* In a way, this is a hack. The more orthodox solution would
* be that device factories don't only announce supported setting
* types, but instead match on a full fledged NMConnection.
*
* However, our device-factories are known at compile time.
* There is no need to keep this generic. We *know* which
* factory to choose. Making this generic would not make it
* cleaner. */
if (!g_hash_table_lookup (factories_by_setting, type)) {
/* we need both the bluetooth and the bridge factory
* to make this work. */
return NULL;
}
type = NM_SETTING_BRIDGE_SETTING_NAME;
for (; list; list = g_slist_next (list)) {
factory = list->data;
klass = NM_DEVICE_FACTORY_GET_CLASS (factory);
if (!klass->match_connection || klass->match_connection (factory, connection))
return factory;
}
return g_hash_table_lookup (factories_by_setting, type);
return NULL;
}
void
@ -283,9 +273,11 @@ nm_device_factory_manager_for_each_factory (NMDeviceFactoryManagerFactoryFunc ca
if (factories_by_setting) {
g_hash_table_iter_init (&iter, factories_by_setting);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &factory)) {
if (!g_slist_find (list, factory))
list = g_slist_prepend (list, factory);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &list_iter)) {
for (; list_iter; list_iter = g_slist_next (list_iter)) {
if (!g_slist_find (list, list_iter->data))
list = g_slist_prepend (list, list_iter->data);
}
}
}
@ -303,6 +295,7 @@ _add_factory (NMDeviceFactory *factory,
{
const NMLinkType *link_types = NULL;
const char *const*setting_types = NULL;
GSList *list;
int i;
g_return_val_if_fail (factories_by_link, FALSE);
@ -313,8 +306,15 @@ _add_factory (NMDeviceFactory *factory,
g_object_set_qdata_full (G_OBJECT (factory), plugin_path_quark (), g_strdup (path), g_free);
for (i = 0; link_types && link_types[i] > NM_LINK_TYPE_UNKNOWN; i++)
g_hash_table_insert (factories_by_link, GUINT_TO_POINTER (link_types[i]), g_object_ref (factory));
for (i = 0; setting_types && setting_types[i]; i++)
g_hash_table_insert (factories_by_setting, (char *) setting_types[i], g_object_ref (factory));
for (i = 0; setting_types && setting_types[i]; i++) {
list = g_hash_table_lookup (factories_by_setting, (char *) setting_types[i]);
if (list)
list = g_slist_append (list, g_object_ref (factory));
else {
list = g_slist_append (list, g_object_ref (factory));
g_hash_table_insert (factories_by_setting, (char *) setting_types[i], list);
}
}
callback (factory, user_data);
@ -333,6 +333,12 @@ _load_internal_factory (GType factory_gtype,
_add_factory (factory, "internal", callback, user_data);
}
static void
factories_list_unref (GSList *list)
{
g_slist_free_full (list, g_object_unref);
}
void
nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc callback,
gpointer user_data)
@ -345,7 +351,7 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call
g_return_if_fail (factories_by_setting == NULL);
factories_by_link = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
factories_by_setting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
factories_by_setting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) factories_list_unref);
#define _ADD_INTERNAL(get_type_fcn) \
G_STMT_START { \
@ -362,6 +368,7 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call
_ADD_INTERNAL (nm_ip_tunnel_device_factory_get_type);
_ADD_INTERNAL (nm_macsec_device_factory_get_type);
_ADD_INTERNAL (nm_macvlan_device_factory_get_type);
_ADD_INTERNAL (nm_ppp_device_factory_get_type);
_ADD_INTERNAL (nm_tun_device_factory_get_type);
_ADD_INTERNAL (nm_veth_device_factory_get_type);
_ADD_INTERNAL (nm_vlan_device_factory_get_type);

View file

@ -71,6 +71,14 @@ typedef struct {
*/
void (*start) (NMDeviceFactory *factory);
/**
* match_connection:
* @connection: the #NMConnection
*
* Check if the factory supports the given connection.
*/
gboolean (*match_connection) (NMDeviceFactory *factory, NMConnection *connection);
/**
* get_connection_parent:
* @factory: the #NMDeviceFactory

337
src/devices/nm-device-ppp.c Normal file
View file

@ -0,0 +1,337 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-device-ppp.h"
#include "nm-act-request.h"
#include "nm-device-factory.h"
#include "nm-device-private.h"
#include "nm-manager.h"
#include "nm-setting-pppoe.h"
#include "platform/nm-platform.h"
#include "ppp/nm-ppp-manager.h"
#include "ppp/nm-ppp-manager-call.h"
#include "ppp/nm-ppp-status.h"
#include "introspection/org.freedesktop.NetworkManager.Device.Ppp.h"
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDevicePpp);
/*****************************************************************************/
typedef struct _NMDevicePppPrivate {
NMPPPManager *ppp_manager;
NMIP4Config *pending_ip4_config;
char *pending_ifname;
} NMDevicePppPrivate;
struct _NMDevicePpp {
NMDevice parent;
NMDevicePppPrivate _priv;
};
struct _NMDevicePppClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDevicePpp, nm_device_ppp, NM_TYPE_DEVICE)
#define NM_DEVICE_PPP_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDevicePpp, NM_IS_DEVICE_PPP)
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMSettingPppoe *s_pppoe;
if (!NM_DEVICE_CLASS (nm_device_ppp_parent_class)->check_connection_compatible (device, connection))
return FALSE;
if (!nm_streq0 (nm_connection_get_connection_type (connection),
NM_SETTING_PPPOE_SETTING_NAME))
return FALSE;
s_pppoe = nm_connection_get_setting_pppoe (connection);
nm_assert (s_pppoe);
return !!nm_setting_pppoe_get_parent (s_pppoe);
}
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *device)
{
return NM_DEVICE_CAP_IS_SOFTWARE;
}
static void
ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
switch (status) {
case NM_PPP_STATUS_DISCONNECT:
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
break;
case NM_PPP_STATUS_DEAD:
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
break;
case NM_PPP_STATUS_RUNNING:
nm_device_activate_schedule_stage3_ip_config_start (device);
break;
default:
break;
}
}
static void
ppp_ip4_config (NMPPPManager *ppp_manager,
const char *iface,
NMIP4Config *config,
gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDevicePpp *self = NM_DEVICE_PPP (device);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
_LOGT (LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd");
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
if (nm_device_activate_ip4_state_in_conf (device)) {
if (!nm_device_take_over_link (device, iface)) {
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
return;
}
nm_manager_remove_device (nm_manager_get (), iface);
nm_device_activate_schedule_ip4_config_result (device, config);
return;
}
} else {
if (priv->pending_ip4_config)
g_object_unref (priv->pending_ip4_config);
priv->pending_ip4_config = g_object_ref (config);
g_free (priv->pending_ifname);
priv->pending_ifname = g_strdup (iface);
}
}
static NMActStageReturn
act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDevicePpp *self = NM_DEVICE_PPP (device);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
NMSettingPppoe *s_pppoe;
NMActRequest *req;
GError *err = NULL;
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
s_pppoe = (NMSettingPppoe *) nm_device_get_applied_setting ((NMDevice *) self, NM_TYPE_SETTING_PPPOE);
g_return_val_if_fail (s_pppoe, NM_ACT_STAGE_RETURN_FAILURE);
g_clear_object (&priv->pending_ip4_config);
nm_clear_g_free (&priv->pending_ifname);
priv->ppp_manager = nm_ppp_manager_create (nm_setting_pppoe_get_parent (s_pppoe), &err);
if ( !priv->ppp_manager
|| !nm_ppp_manager_start (priv->ppp_manager, req,
nm_setting_pppoe_get_username (s_pppoe),
30, 0, &err)) {
_LOGW (LOGD_DEVICE | LOGD_PPP, "PPPoE failed to start: %s", err->message);
g_error_free (err);
g_clear_object (&priv->ppp_manager);
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED);
return NM_ACT_STAGE_RETURN_FAILURE;
}
g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATE_CHANGED,
G_CALLBACK (ppp_state_changed),
self);
g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
G_CALLBACK (ppp_ip4_config),
self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
static NMActStageReturn
act_stage3_ip4_config_start (NMDevice *device,
NMIP4Config **out_config,
NMDeviceStateReason *out_failure_reason)
{
NMDevicePpp *self = NM_DEVICE_PPP (device);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
if (priv->pending_ip4_config) {
if (!nm_device_take_over_link (device, priv->pending_ifname))
return NM_ACT_STAGE_RETURN_FAILURE;
nm_manager_remove_device (nm_manager_get (), priv->pending_ifname);
if (out_config)
*out_config = g_steal_pointer (&priv->pending_ip4_config);
else
g_clear_object (&priv->pending_ip4_config);
return NM_ACT_STAGE_RETURN_SUCCESS;
}
/* Wait IPCP termination */
return NM_ACT_STAGE_RETURN_POSTPONE;
}
static gboolean
create_and_realize (NMDevice *device,
NMConnection *connection,
NMDevice *parent,
const NMPlatformLink **out_plink,
GError **error)
{
int parent_ifindex;
if (!parent) {
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
"PPP devices can not be created without a parent interface");
return FALSE;
}
parent_ifindex = nm_device_get_ifindex (parent);
g_warn_if_fail (parent_ifindex > 0);
nm_device_parent_set_ifindex (device, parent_ifindex);
/* The interface is created later */
return TRUE;
}
static void
deactivate (NMDevice *device)
{
NMDevicePpp *self = NM_DEVICE_PPP (device);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
if (priv->ppp_manager) {
nm_ppp_manager_stop_sync (priv->ppp_manager);
g_clear_object (&priv->ppp_manager);
}
}
static void
nm_device_ppp_init (NMDevicePpp *self)
{
}
static void
dispose (GObject *object)
{
NMDevicePpp *self = NM_DEVICE_PPP (object);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
g_clear_object (&priv->pending_ip4_config);
nm_clear_g_free (&priv->pending_ifname);
G_OBJECT_CLASS (nm_device_ppp_parent_class)->dispose (object);
}
static void
nm_device_ppp_class_init (NMDevicePppClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass);
NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_PPPOE_SETTING_NAME, NM_LINK_TYPE_PPP)
object_class->dispose = dispose;
parent_class->act_stage2_config = act_stage2_config;
parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->create_and_realize = create_and_realize;
parent_class->deactivate = deactivate;
parent_class->get_generic_capabilities = get_generic_capabilities;
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_PPP_SKELETON,
NULL);
}
/*****************************************************************************/
#define NM_TYPE_PPP_DEVICE_FACTORY (nm_ppp_device_factory_get_type ())
#define NM_PPP_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PPP_DEVICE_FACTORY, NMPppDeviceFactory))
static NMDevice *
create_device (NMDeviceFactory *factory,
const char *iface,
const NMPlatformLink *plink,
NMConnection *connection,
gboolean *out_ignore)
{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_PPP,
NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Ppp",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_PPP,
NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_PPP,
NULL);
}
static gboolean
match_connection (NMDeviceFactory *factory, NMConnection *connection)
{
NMSettingPppoe *s_pppoe;
s_pppoe = nm_connection_get_setting_pppoe (connection);
nm_assert (s_pppoe);
return !!nm_setting_pppoe_get_parent (s_pppoe);
}
static const char *
get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
{
NMSettingPppoe *s_pppoe;
nm_assert (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME));
s_pppoe = nm_connection_get_setting_pppoe (connection);
nm_assert (s_pppoe);
return nm_setting_pppoe_get_parent (s_pppoe);
}
static char *
get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
nm_assert (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME));
if (!parent_iface)
return NULL;
return g_strdup (nm_connection_get_interface_name (connection));
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL (PPP, Ppp, ppp,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_PPP)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_PPPOE_SETTING_NAME),
factory_class->get_connection_parent = get_connection_parent;
factory_class->get_connection_iface = get_connection_iface;
factory_class->create_device = create_device;
factory_class->match_connection = match_connection;
);

View file

@ -0,0 +1,30 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2017 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_DEVICE_PPP_H__
#define __NETWORKMANAGER_DEVICE_PPP_H__
#define NM_TYPE_DEVICE_PPP (nm_device_ppp_get_type ())
#define NM_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_PPP, NMDevicePpp))
#define NM_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_PPP, NMDevicePppClass))
#define NM_IS_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_PPP))
#define NM_IS_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_PPP))
#define NM_DEVICE_PPP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_PPP, NMDevicePppClass))
typedef struct _NMDevicePpp NMDevicePpp;
typedef struct _NMDevicePppClass NMDevicePppClass;
GType nm_device_ppp_get_type (void);
#endif /* __NETWORKMANAGER_DEVICE_PPP_H__ */

View file

@ -57,6 +57,8 @@ gboolean nm_device_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmwar
void nm_device_take_down (NMDevice *self, gboolean block);
gboolean nm_device_take_over_link (NMDevice *self, const char *ifname);
gboolean nm_device_hw_addr_set (NMDevice *device,
const char *addr,
const char *detail,

View file

@ -1001,6 +1001,40 @@ nm_device_get_iface (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->iface;
}
gboolean
nm_device_take_over_link (NMDevice *self, const char *ifname)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
const NMPlatformLink *plink;
NMPlatform *platform;
gboolean up, success;
int ifindex;
g_return_val_if_fail (priv->ifindex <= 0, FALSE);
platform = nm_device_get_platform (self);
plink = nm_platform_link_get_by_ifname (platform, ifname);
if (!plink)
return FALSE;
ifindex = plink->ifindex;
up = NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP);
/* Rename the link to the device ifname */
if (up)
nm_platform_link_set_down (platform, ifindex);
success = nm_platform_link_set_name (platform, ifindex, nm_device_get_iface (self));
if (up)
nm_platform_link_set_up (platform, ifindex, NULL);
if (success) {
priv->ifindex = ifindex;
_notify (self, PROP_IFINDEX);
}
return success;
}
int
nm_device_get_ifindex (NMDevice *self)
{
@ -1555,6 +1589,8 @@ nm_device_get_priority (NMDevice *self)
return 425;
case NM_DEVICE_TYPE_TUN:
return 450;
case NM_DEVICE_TYPE_PPP:
return 460;
case NM_DEVICE_TYPE_VXLAN:
return 500;
case NM_DEVICE_TYPE_DUMMY:
@ -2909,8 +2945,10 @@ nm_device_create_and_realize (NMDevice *self,
if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error))
return FALSE;
plink_copy = *plink;
plink = &plink_copy;
if (plink) {
plink_copy = *plink;
plink = &plink_copy;
}
}
realize_start_setup (self, plink,

View file

@ -1258,6 +1258,24 @@ nm_manager_iface_for_uuid (NMManager *self, const char *uuid)
return nm_connection_get_interface_name (NM_CONNECTION (connection));
}
gboolean
nm_manager_remove_device (NMManager *self, const char *ifname)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
GSList *iter;
NMDevice *d;
for (iter = priv->devices; iter; iter = iter->next) {
d = iter->data;
if (nm_streq0 (nm_device_get_iface (d), ifname)) {
remove_device (self, d, FALSE, FALSE);
return TRUE;
}
}
return FALSE;
}
/**
* system_create_virtual_device:
* @self: the #NMManager

View file

@ -124,4 +124,6 @@ gboolean nm_manager_deactivate_connection (NMManager *manager,
void nm_manager_set_capability (NMManager *self, NMCapability cap);
gboolean nm_manager_remove_device (NMManager *self, const char *ifname);
#endif /* __NETWORKMANAGER_MANAGER_H__ */

View file

@ -142,7 +142,8 @@ typedef enum {
NM_LINK_TYPE_WIMAX,
/* Software types */
NM_LINK_TYPE_DUMMY = 0x10000,
NM_LINK_TYPE_BNEP = 0x10000, /* Bluetooth Ethernet emulation */
NM_LINK_TYPE_DUMMY,
NM_LINK_TYPE_GRE,
NM_LINK_TYPE_GRETAP,
NM_LINK_TYPE_IFB,
@ -153,13 +154,13 @@ typedef enum {
NM_LINK_TYPE_MACVLAN,
NM_LINK_TYPE_MACVTAP,
NM_LINK_TYPE_OPENVSWITCH,
NM_LINK_TYPE_PPP,
NM_LINK_TYPE_SIT,
NM_LINK_TYPE_TAP,
NM_LINK_TYPE_TUN,
NM_LINK_TYPE_VETH,
NM_LINK_TYPE_VLAN,
NM_LINK_TYPE_VXLAN,
NM_LINK_TYPE_BNEP, /* Bluetooth Ethernet emulation */
/* Software types with slaves */
NM_LINK_TYPE_BRIDGE = 0x10000 | 0x20000,

View file

@ -380,6 +380,7 @@ static const LinkDesc linktypes[] = {
{ NM_LINK_TYPE_WWAN_NET, "wwan", NULL, "wwan" },
{ NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" },
{ NM_LINK_TYPE_BNEP, "bluetooth", NULL, "bluetooth" },
{ NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL },
{ NM_LINK_TYPE_GRE, "gre", "gre", NULL },
{ NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL },
@ -391,13 +392,13 @@ static const LinkDesc linktypes[] = {
{ NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL },
{ NM_LINK_TYPE_MACVTAP, "macvtap", "macvtap", NULL },
{ NM_LINK_TYPE_OPENVSWITCH, "openvswitch", "openvswitch", NULL },
{ NM_LINK_TYPE_PPP, "ppp", NULL, "ppp" },
{ NM_LINK_TYPE_SIT, "sit", "sit", NULL },
{ NM_LINK_TYPE_TAP, "tap", NULL, NULL },
{ NM_LINK_TYPE_TUN, "tun", NULL, NULL },
{ NM_LINK_TYPE_VETH, "veth", "veth", NULL },
{ NM_LINK_TYPE_VLAN, "vlan", "vlan", "vlan" },
{ NM_LINK_TYPE_VXLAN, "vxlan", "vxlan", "vxlan" },
{ NM_LINK_TYPE_BNEP, "bluetooth", NULL, "bluetooth" },
{ NM_LINK_TYPE_BRIDGE, "bridge", "bridge", "bridge" },
{ NM_LINK_TYPE_BOND, "bond", "bond", "bond" },
@ -696,6 +697,8 @@ _linktype_get_type (NMPlatform *platform,
return NM_LINK_TYPE_SIT;
else if (arptype == ARPHRD_TUNNEL6)
return NM_LINK_TYPE_IP6TNL;
else if (arptype == ARPHRD_PPP)
return NM_LINK_TYPE_PPP;
{
NMPUtilsEthtoolDriverInfo driver_info;
@ -4463,6 +4466,29 @@ nla_put_failure:
g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED);
}
static NMPlatformError
link_set_name (NMPlatform *platform, int ifindex, const char *name)
{
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
_LOGD ("link: change %d: name: %s", ifindex, name);
nlmsg = _nl_msg_new_link (RTM_NEWLINK,
0,
ifindex,
NULL,
0,
0);
if (!nlmsg)
g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED);
NLA_PUT (nlmsg, IFLA_IFNAME, strlen (name) + 1, name);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
nla_put_failure:
g_return_val_if_reached (FALSE);
}
static gboolean
link_get_permanent_address (NMPlatform *platform,
int ifindex,
@ -6461,6 +6487,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->link_set_address = link_set_address;
platform_class->link_get_permanent_address = link_get_permanent_address;
platform_class->link_set_mtu = link_set_mtu;
platform_class->link_set_name = link_set_name;
platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs;
platform_class->link_get_physical_port_id = link_get_physical_port_id;

View file

@ -1461,6 +1461,30 @@ nm_platform_link_get_mtu (NMPlatform *self, int ifindex)
return pllink ? pllink->mtu : 0;
}
/**
* nm_platform_link_set_name:
* @self: platform instance
* @ifindex: Interface index
* @name: The new interface name
*
* Set interface name.
*/
gboolean
nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name)
{
_CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (ifindex >= 0, FALSE);
g_return_val_if_fail (name, FALSE);
_LOGD ("link: setting '%s' (%d) name %s", nm_platform_link_get_name (self, ifindex), ifindex, name);
if (strlen (name) + 1 > IFNAMSIZ)
return FALSE;
return klass->link_set_name (self, ifindex, name);
}
/**
* nm_platform_link_get_physical_port_id:
* @self: platform instance

View file

@ -682,6 +682,7 @@ typedef struct {
size_t *length);
NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name);
gboolean (*link_set_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs);
char * (*link_get_physical_port_id) (NMPlatform *, int ifindex);
@ -946,6 +947,7 @@ gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtils
gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length);
NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name);
gboolean nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs);
char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex);

View file

@ -678,6 +678,7 @@ create_pppd_cmd_line (NMPPPManager *self,
const char *pppd_binary = NULL;
NMCmdLine *cmd;
gboolean ppp_debug;
static int unit;
g_return_val_if_fail (setting != NULL, NULL);
@ -842,6 +843,15 @@ create_pppd_cmd_line (NMPPPManager *self,
nm_cmd_line_add_string (cmd, "plugin");
nm_cmd_line_add_string (cmd, NM_PPPD_PLUGIN);
if (pppoe && nm_setting_pppoe_get_parent (pppoe)) {
/* The PPP interface is going to be renamed, so pass a
* different unit each time so that activations don't
* race with each others. */
nm_cmd_line_add_string (cmd, "unit");
nm_cmd_line_add_int (cmd, unit);
unit = unit < G_MAXINT ? unit + 1 : 0;
}
return cmd;
}