On Tue, 2011-05-17 at 21:38 +0300, Pantelis Koukousoulas wrote: > This is a first cut at experimental PPPoE support for ADSL devices. > There are several shortcuts and the code is ugly, but it works so > it can be used as a strawman to improve upon. > > Happily waiting for comments / testing / suggestions :) > > With this code and a system keyfile connection like the following:
Pushed this to the 'adsl' branch too, thanks! Dan > [connection] > id=OTENETPPPOE > uuid=34d04e69-fdd9-4231-af2c-25ed1f34dc2e > type=adsl > timestamp=1304621332 > > [adsl] > [email protected] > password=mypassword > vpi=8 > vci=35 > encapsulation=llc > protocol=pppoe > > [ipv6] > method=ignore > > [ipv4] > method=auto > > I can connect successfully via pppoe, as evidenced by the following > extract from the logs: > > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 1 of 5 (Device > Prepare) scheduled... > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 1 of 5 (Device > Prepare) started... > NetworkManager[1495]: <info> starting RFC 2684 Bridge > NetworkManager[1495]: <debug> [1305654571.49055] [nm-br2684-manager.c:403] > nm_br2684_manager_start(): command line: /usr/sbin/br2684ctl -c 0 -e 0 -p 1 > -a 8.35 > NetworkManager[1495]: <info> br2684ctl started with pid 1721 > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 1 of 5 (Device > Prepare) complete. > NetworkManager[1495]: <debug> [1305654571.62289] [nm-udev-manager.c:622] > handle_uevent(): UDEV event: action 'add' subsys 'net' device 'nas0' > NetworkManager[1495]: <warn> /sys/devices/virtual/net/nas0: couldn't > determine device driver; ignoring... > NetworkManager[1495]: <debug> [1305654571.63491] [nm-netlink-monitor.c:117] > link_msg_handler(): netlink link message: iface idx 62 flags 0x1002 > br2684ctl[1721]: Interface "nas0" created sucessfully > br2684ctl[1721]: Communicating over ATM 0.8.35, encapsulation: LLC > br2684ctl[1721]: Interface configured > br2684ctl[1721]: RFC 1483/2684 bridge daemon started > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 2 of 5 (Device > Configure) scheduled... > NetworkManager[1495]: <debug> [1305654576.48874] [nm-netlink-monitor.c:117] > link_msg_handler(): netlink link message: iface idx 62 flags 0x11043 > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 2 of 5 (Device > Configure) starting... > NetworkManager[1495]: <info> (ueagle-atm0): device state change: prepare -> > config (reason 'none') [40 50 0] > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 2 of 5 (Device > Configure) successful. > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 3 of 5 (IP > Configure Start) scheduled. > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 2 of 5 (Device > Configure) complete. > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 3 of 5 (IP > Configure Start) started... > NetworkManager[1495]: <info> (ueagle-atm0): device state change: config -> > ip-config (reason 'none') [50 70 0] > NetworkManager[1495]: <info> starting PPP connection > NetworkManager[1495]: <debug> [1305654576.59215] [nm-ppp-manager.c:1056] > nm_ppp_manager_start(): command line: /usr/sbin/pppd nodetach lock > nodefaultroute debug user [email protected] plugin rp-pppoe.so nas0 > noipdefault noauth usepeerdns lcp-echo-failure 0 lcp-echo-interval 0 ipparam > /org/freedesktop/NetworkManager/PPP/2 plugin > /opt/nmadsl/lib/pppd/2.4.5/nm-pppd-plugin.so > NetworkManager[1495]: <info> pppd started with pid 1733 > NetworkManager[1495]: <debug> [1305654576.62016] [NetworkManagerUtils.c:848] > nm_utils_get_proc_sys_net_value(): (ueagle-atm0): error reading > /proc/sys/net/ipv6/conf/ueagle-atm0/accept_ra: (4) Failed to open file > '/proc/sys/net/ipv6/conf/ueagle-atm0/accept_ra': No such file or directory > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 3 of 5 (IP > Configure Start) complete. > Plugin rp-pppoe.so loaded. > Plugin /opt/nmadsl/lib/pppd/2.4.5/nm-pppd-plugin.so loaded. > ** Message: nm-ppp-plugin: (plugin_init): initializing > ** Message: nm-ppp-plugin: (nm_phasechange): status 3 / phase 'serial > connection' > Send PPPOE Discovery V1T1 PADI session 0x0 length 12 > dst ff:ff:ff:ff:ff:ff src 0:60:4c:8c:5b:d6 > [service-name] [host-uniq c5 06 00 00] > Recv PPPOE Discovery V1T1 PADO session 0x0 length 50 > dst 0:60:4c:8c:5b:d6 src 0:90:1a:41:65:24 > [AC-name bras-ari1-1440] [host-uniq c5 06 00 00] [service-name] [AC-cookie > cc d1 10 3e 4b c8 e9 de b3 c9 73 c7 1d b4 4d 30] > Send PPPOE Discovery V1T1 PADR session 0x0 length 32 > dst 0:90:1a:41:65:24 src 0:60:4c:8c:5b:d6 > [service-name] [host-uniq c5 06 00 00] [AC-cookie cc d1 10 3e 4b c8 e9 de > b3 c9 73 c7 1d b4 4d 30] > Recv PPPOE Discovery V1T1 PADS session 0x130d length 50 > dst 0:60:4c:8c:5b:d6 src 0:90:1a:41:65:24 > [service-name] [host-uniq c5 06 00 00] [AC-name bras-ari1-1440] [AC-cookie > cc d1 10 3e 4b c8 e9 de b3 c9 73 c7 1d b4 4d 30] > PADS: Service-Name: '' > PPP session is 4877 > Connected to 00:90:1a:41:65:24 via interface nas0 > using channel 32 > Using interface ppp0 > Connect: ppp0 <--> nas0 > ** Message: nm-ppp-plugin: (nm_phasechange): status 5 / phase 'establish' > sent [LCP ConfReq id=0x1 <mru 1492> <magic 0x2de132c2>] > NetworkManager[1495]: <debug> [1305654576.314811] [nm-netlink-monitor.c:117] > link_msg_handler(): netlink link message: iface idx 63 flags 0x1090 > NetworkManager[1495]: <debug> [1305654576.314939] [nm-udev-manager.c:622] > handle_uevent(): UDEV event: action 'add' subsys 'net' device 'ppp0' > NetworkManager[1495]: <debug> [1305654576.314991] [nm-udev-manager.c:525] > net_add(): ignoring interface with type 512 > rcvd [LCP ConfReq id=0x11 <mru 1492> <auth pap> <magic 0x701d0b64>] > sent [LCP ConfAck id=0x11 <mru 1492> <auth pap> <magic 0x701d0b64>] > rcvd [LCP ConfAck id=0x1 <mru 1492> <magic 0x2de132c2>] > ** Message: nm-ppp-plugin: (nm_phasechange): status 6 / phase 'authenticate' > ** Message: nm-ppp-plugin: (get_credentials): passwd-hook, requesting > credentials... > NetworkManager[1495]: <debug> [1305654576.420633] [nm-agent-manager.c:1044] > nm_agent_manager_get_secrets(): Secrets requested for connection > /org/freedesktop/NetworkManager/Settings/0 (adsl) > NetworkManager[1495]: <debug> [1305654576.420743] > [nm-settings-connection.c:717] nm_settings_connection_get_secrets(): > (34d04e69-fdd9-4231-af2c-25ed1f34dc2e/adsl:1) secrets requested flags 0x1 > hint 'password' > NetworkManager[1495]: <debug> [1305654576.421675] [nm-agent-manager.c:959] > get_start(): (0x91fde80/adsl) system settings secrets sufficient > NetworkManager[1495]: <debug> [1305654576.422178] > [nm-settings-connection.c:573] agent_secrets_done_cb(): > (34d04e69-fdd9-4231-af2c-25ed1f34dc2e/adsl:1) existing secrets returned > NetworkManager[1495]: <debug> [1305654576.422419] > [nm-settings-connection.c:579] agent_secrets_done_cb(): > (34d04e69-fdd9-4231-af2c-25ed1f34dc2e/adsl:1) secrets request completed > NetworkManager[1495]: <debug> [1305654576.424015] > [nm-settings-connection.c:618] agent_secrets_done_cb(): > (34d04e69-fdd9-4231-af2c-25ed1f34dc2e/adsl:1) new agent secrets processed > ** Message: nm-ppp-plugin: (get_credentials): got credentials from > NetworkManager > sent [PAP AuthReq id=0x1 user="[email protected]" password=<hidden>] > rcvd [PAP AuthAck id=0x1 ""] > PAP authentication succeeded > peer from calling number 00:90:1A:41:65:24 authorized > ** Message: nm-ppp-plugin: (nm_phasechange): status 8 / phase 'network' > sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>] > rcvd [IPCP ConfNak id=0x1 <addr 94.70.77.249> <ms-dns1 195.170.0.1> <ms-dns2 > 195.170.2.2>] > sent [IPCP ConfReq id=0x2 <addr 94.70.77.249> <ms-dns1 195.170.0.1> <ms-dns2 > 195.170.2.2>] > rcvd [IPCP ConfAck id=0x2 <addr 94.70.77.249> <ms-dns1 195.170.0.1> <ms-dns2 > 195.170.2.2>] > rcvd [IPCP ConfReq id=0x40 <addr 80.106.108.12>] > sent [IPCP ConfAck id=0x40 <addr 80.106.108.12>] > NetworkManager[1495]: <debug> [1305654576.812559] [nm-netlink-monitor.c:117] > link_msg_handler(): netlink link message: iface idx 63 flags 0x110D1 > local IP address 94.70.77.249 > remote IP address 80.106.108.12 > primary DNS address 195.170.0.1 > secondary DNS address 195.170.2.2 > ** Message: nm-ppp-plugin: (nm_phasechange): status 9 / phase 'running' > ** Message: nm-ppp-plugin: (nm_ip_up): ip-up event > ** Message: nm-ppp-plugin: (nm_ip_up): sending Ip4Config to NetworkManager... > NetworkManager[1495]: <info> PPP manager(IP Config Get) reply received. > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 4 of 5 (IP4 > Configure Get) scheduled... > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 4 of 5 (IP4 > Configure Get) started... > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 5 of 5 (IP > Configure Commit) scheduled... > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 4 of 5 (IP4 > Configure Get) complete. > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 5 of 5 (IP > Configure Commit) started... > NetworkManager[1495]: <debug> [1305654576.818828] [nm-system.c:222] > sync_addresses(): (ppp0): syncing addresses (family 2) > Script /etc/ppp/ip-up started (pid 1736) > Script /etc/ppp/ip-up finished (pid 1736), status = 0x0 > NetworkManager[1495]: <info> (ueagle-atm0): device state change: ip-config -> > activated (reason 'none') [70 100 0] > NetworkManager[1495]: <info> Policy set 'CONNPPPOE' (ppp0) as default for > IPv4 routing and DNS. > NetworkManager[1495]: <info> Activation (ueagle-atm0) successful, device > activated. > NetworkManager[1495]: <info> Activation (ueagle-atm0) Stage 5 of 5 (IP > Configure Commit) complete. > > Signed-off-by: Pantelis Koukousoulas <[email protected]> > --- > configure.ac | 1 + > include/NetworkManager.h | 3 + > src/Makefile.am | 2 + > src/br2684-manager/Makefile.am | 25 ++ > src/br2684-manager/nm-br2684-manager.c | 427 > ++++++++++++++++++++++++++++++++ > src/br2684-manager/nm-br2684-manager.h | 64 +++++ > src/logging/nm-logging.c | 3 +- > src/logging/nm-logging.h | 1 + > src/nm-device-adsl.c | 47 ++++- > src/nm-device.c | 2 + > src/ppp-manager/nm-ppp-manager.c | 47 ++-- > 11 files changed, 599 insertions(+), 23 deletions(-) > create mode 100644 src/br2684-manager/Makefile.am > create mode 100644 src/br2684-manager/nm-br2684-manager.c > create mode 100644 src/br2684-manager/nm-br2684-manager.h > > diff --git a/configure.ac b/configure.ac > index b18ccc0..1679828 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -603,6 +603,7 @@ src/ip6-manager/Makefile > src/supplicant-manager/Makefile > src/supplicant-manager/tests/Makefile > src/ppp-manager/Makefile > +src/br2684-manager/Makefile > src/dnsmasq-manager/Makefile > src/modem-manager/Makefile > src/bluez-manager/Makefile > diff --git a/include/NetworkManager.h b/include/NetworkManager.h > index f2e4727..5c9ffc3 100644 > --- a/include/NetworkManager.h > +++ b/include/NetworkManager.h > @@ -415,6 +415,9 @@ typedef enum { > /* The Bluetooth connection failed or timed out */ > NM_DEVICE_STATE_REASON_BT_FAILED = 44, > > + /* Problem with the RFC 2684 Ethernet over ADSL bridge */ > + NM_DEVICE_STATE_REASON_BR2684_FAILED = 45, > + > /* Unused */ > NM_DEVICE_STATE_REASON_LAST = 0xFFFF > } NMDeviceStateReason; > diff --git a/src/Makefile.am b/src/Makefile.am > index 50b52d6..f0bc6d7 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -6,6 +6,7 @@ SUBDIRS= \ > ip6-manager \ > supplicant-manager \ > ppp-manager \ > + br2684-manager \ > backends \ > dnsmasq-manager \ > modem-manager \ > @@ -267,6 +268,7 @@ NetworkManager_LDADD = \ > ./supplicant-manager/libsupplicant-manager.la \ > ./dnsmasq-manager/libdnsmasq-manager.la \ > ./ppp-manager/libppp-manager.la \ > + ./br2684-manager/libbr2684-manager.la \ > ./modem-manager/libmodem-manager.la \ > ./bluez-manager/libbluez-manager.la \ > ./settings/libsettings.la \ > diff --git a/src/br2684-manager/Makefile.am b/src/br2684-manager/Makefile.am > new file mode 100644 > index 0000000..9a6bb03 > --- /dev/null > +++ b/src/br2684-manager/Makefile.am > @@ -0,0 +1,25 @@ > +INCLUDES = \ > + -I${top_srcdir} \ > + -I${top_srcdir}/include \ > + -I${top_srcdir}/libnm-util \ > + -I${top_srcdir}/src \ > + -I${top_srcdir}/src/logging \ > + -I${top_builddir}/marshallers > + > +noinst_LTLIBRARIES = libbr2684-manager.la > + > +libbr2684_manager_la_SOURCES = \ > + nm-br2684-manager.c \ > + nm-br2684-manager.h > + > +$(libbr2684_manager_la_OBJECTS): > + > +libbr2684_manager_la_CPPFLAGS = \ > + $(GLIB_CFLAGS) \ > + -DG_DISABLE_DEPRECATED \ > + -DSYSCONFDIR=\"$(sysconfdir)\" \ > + -DLIBDIR=\"$(libdir)\" > + > +libbr2684_manager_la_LIBADD = \ > + $(top_builddir)/src/logging/libnm-logging.la \ > + $(GLIB_LIBS) > diff --git a/src/br2684-manager/nm-br2684-manager.c > b/src/br2684-manager/nm-br2684-manager.c > new file mode 100644 > index 0000000..68c83a6 > --- /dev/null > +++ b/src/br2684-manager/nm-br2684-manager.c > @@ -0,0 +1,427 @@ > +/* -*- 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. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + * > + * Author: Pantelis Koukousoulas <[email protected]> > + */ > + > +#include <config.h> > +#include <unistd.h> > +#include <string.h> > +#include <sys/wait.h> > + > +#include "nm-br2684-manager.h" > +#include "nm-setting-adsl.h" > +#include "nm-logging.h" > + > +typedef struct { > + gboolean disposed; > + > + gboolean iface_up; > + guint32 iface_poll_id; > + guint32 br2684_watch_id; > + GPid pid; > +} NMBr2684ManagerPrivate; > + > +#define NM_BR2684_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), > NM_TYPE_BR2684_MANAGER, NMBr2684ManagerPrivate)) > + > +G_DEFINE_TYPE (NMBr2684Manager, nm_br2684_manager, G_TYPE_OBJECT) > + > +enum { > + STATE_CHANGED, > + > + LAST_SIGNAL > +}; > + > +static guint signals[LAST_SIGNAL] = { 0 }; > + > +enum { > + PROP_0, > + LAST_PROP > +}; > + > +typedef enum { > + NM_BR2684_MANAGER_ERROR_UNKOWN > +} NMBr2684ManagerError; > + > +GQuark > +nm_br2684_manager_error_quark (void) > +{ > + static GQuark quark; > + > + if (!quark) > + quark = g_quark_from_static_string ("nm_br2684_manager_error"); > + > + return quark; > +} > + > +static void > +nm_br2684_manager_init (NMBr2684Manager *manager) > +{ > +} > + > +static gboolean > +iface_update_cb (gpointer user_data) > +{ > + NMBr2684Manager *self = NM_BR2684_MANAGER (user_data); > + NMBr2684ManagerPrivate *priv = NM_BR2684_MANAGER_GET_PRIVATE (self); > + > + gchar *contents = NULL; > + GError *error = NULL; > + const gchar *path = "/sys/devices/virtual/net/nas0/ifindex"; > + > + if (!g_file_get_contents(path, &contents, NULL, &error)) { > + g_clear_error (&error); > + if (priv->iface_up) { > + priv->iface_up = FALSE; > + g_signal_emit(self, signals[STATE_CHANGED], 0, 0); > + } > + > + return TRUE; > + } > + > + if (!priv->iface_up) { > + priv->iface_up = TRUE; > + g_signal_emit(self, signals[STATE_CHANGED], 0, 1); > + } > + > + return TRUE; > +} > + > +static GObject * > +constructor (GType type, > + guint n_construct_params, > + GObjectConstructParam *construct_params) > +{ > + GObject *object; > + NMBr2684Manager *self; > + NMBr2684ManagerPrivate *priv; > + > + object = G_OBJECT_CLASS (nm_br2684_manager_parent_class)->constructor > (type, > + > n_construct_params, > + > construct_params); > + > + if (!object) > + return NULL; > + > + self = NM_BR2684_MANAGER (object); > + priv = NM_BR2684_MANAGER_GET_PRIVATE (self); > + > + priv->iface_up = FALSE; > + priv->iface_poll_id = g_timeout_add_seconds(5, iface_update_cb, self); > + > + return object; > +} > + > +static gboolean > +ensure_killed (gpointer data) > +{ > + int pid = GPOINTER_TO_INT (data); > + > + if (kill (pid, 0) == 0) > + kill (pid, SIGKILL); > + > + /* ensure the child is reaped */ > + nm_log_dbg (LOGD_BR2684, "waiting for br2684ctl pid %d to exit", pid); > + waitpid (pid, NULL, 0); > + nm_log_dbg (LOGD_BR2684, "br2684ctl pid %d cleaned up", pid); > + > + return FALSE; > +} > + > +static void br2684_cleanup (NMBr2684Manager *manager) > +{ > + NMBr2684ManagerPrivate *priv; > + > + g_return_if_fail (NM_IS_BR2684_MANAGER (manager)); > + > + priv = NM_BR2684_MANAGER_GET_PRIVATE (manager); > + > + nm_log_dbg (LOGD_BR2684, "br2684ctl cleanup (pid: %d)", priv->pid); > + > + if (priv->br2684_watch_id) { > + g_source_remove (priv->br2684_watch_id); > + priv->br2684_watch_id = 0; > + } > + > + if (priv->pid) { > + if (kill (priv->pid, SIGTERM) == 0) > + g_timeout_add_seconds (2, ensure_killed, > GINT_TO_POINTER (priv->pid)); > + else { > + kill (priv->pid, SIGKILL); > + > + /* ensure the child is reaped */ > + nm_log_dbg (LOGD_BR2684, "waiting for br2684ctl pid %d > to exit", priv->pid); > + waitpid (priv->pid, NULL, 0); > + nm_log_dbg (LOGD_BR2684, "br2684ctl pid %d cleaned up", > priv->pid); > + } > + > + priv->pid = 0; > + } > +} > + > +static void > +dispose (GObject *object) > +{ > + NMBr2684ManagerPrivate *priv = NM_BR2684_MANAGER_GET_PRIVATE (object); > + > + nm_log_dbg (LOGD_BR2684, "in Br2684Manager::dispose()"); > + > + if (priv->disposed == FALSE) { > + priv->disposed = TRUE; > + > + br2684_cleanup(NM_BR2684_MANAGER (object)); > + > + if (priv->iface_poll_id) { > + g_source_remove(priv->iface_poll_id); > + priv->iface_poll_id = 0; > + } > + } > + > + G_OBJECT_CLASS (nm_br2684_manager_parent_class)->dispose (object); > +} > + > +static void > +nm_br2684_manager_class_init (NMBr2684ManagerClass *manager_class) > +{ > + GObjectClass *object_class = G_OBJECT_CLASS (manager_class); > + > + g_type_class_add_private (manager_class, sizeof > (NMBr2684ManagerPrivate)); > + > + object_class->constructor = constructor; > + object_class->dispose = dispose; > + > + /* signals */ > + signals[STATE_CHANGED] = > + g_signal_new ("state-changed", > + G_OBJECT_CLASS_TYPE (object_class), > + G_SIGNAL_RUN_FIRST, > + G_STRUCT_OFFSET (NMBr2684ManagerClass, > state_changed), > + NULL, NULL, > + g_cclosure_marshal_VOID__UINT, > + G_TYPE_NONE, 1, > + G_TYPE_UINT); > +} > + > +/************************************************/ > + > +static inline const char * > +nm_find_br2684ctl (void) > +{ > + static const char *br2684ctl_binary_paths[] = { > + "/usr/local/sbin/br2684ctl", > + "/usr/sbin/br2684ctl", > + "/sbin/br2684ctl", > + }; > + > + const char **br2684ctl_binary = br2684ctl_binary_paths; > + > + while (*br2684ctl_binary != NULL) { > + if (g_file_test (*br2684ctl_binary, G_FILE_TEST_EXISTS)) > + break; > + br2684ctl_binary++; > + } > + > + return *br2684ctl_binary; > +} > + > +typedef struct { > + GPtrArray *array; > + GStringChunk *chunk; > +} NMCmdLine; > + > +static NMCmdLine * > +nm_cmd_line_new (void) > +{ > + NMCmdLine *cmd; > + > + cmd = g_slice_new (NMCmdLine); > + cmd->array = g_ptr_array_new (); > + cmd->chunk = g_string_chunk_new (1024); > + > + return cmd; > +} > + > +static void > +nm_cmd_line_destroy (NMCmdLine *cmd) > +{ > + g_ptr_array_free (cmd->array, TRUE); > + g_string_chunk_free (cmd->chunk); > + g_slice_free (NMCmdLine, cmd); > +} > + > +static char * > +nm_cmd_line_to_str (NMCmdLine *cmd) > +{ > + char *str; > + > + g_ptr_array_add (cmd->array, NULL); > + str = g_strjoinv (" ", (gchar **) cmd->array->pdata); > + g_ptr_array_remove_index (cmd->array, cmd->array->len - 1); > + > + return str; > +} > + > +static void > +nm_cmd_line_add_string (NMCmdLine *cmd, const char *str) > +{ > + g_ptr_array_add (cmd->array, g_string_chunk_insert (cmd->chunk, str)); > +} > + > +static void > +nm_cmd_line_add_int (NMCmdLine *cmd, int i) > +{ > + char *str; > + > + str = g_strdup_printf ("%d", i); > + nm_cmd_line_add_string (cmd, str); > + g_free (str); > +} > + > +static NMCmdLine * > +create_br2684ctl_cmd_line (NMBr2684Manager *manager, > + NMSettingAdsl *s_adsl, > + GError **err) > +{ > + const char *b2864_binary; > + const char *encapsulation, *protocol, *vpi, *vci; > + gchar *vpivci; > + gboolean is_llc, is_pppoe; > + NMCmdLine *cmd; > + > + b2864_binary = nm_find_br2684ctl (); > + if (!b2864_binary) { > + g_set_error (err, NM_BR2684_MANAGER_ERROR, > NM_BR2684_MANAGER_ERROR, > + "Could not find br2684ctl > binary."); > + } > + > + cmd = nm_cmd_line_new (); > + nm_cmd_line_add_string (cmd, b2864_binary); > + nm_cmd_line_add_string (cmd, "-c"); > + nm_cmd_line_add_int (cmd, 0); // interface number (for now force nas0) > + > + encapsulation = nm_setting_adsl_get_encapsulation (s_adsl); > + is_llc = !strcmp (encapsulation, "llc"); > + > + protocol = nm_setting_adsl_get_protocol (s_adsl); > + is_pppoe = !strcmp (protocol, "pppoe"); > + > + vpi = nm_setting_adsl_get_vpi (s_adsl); > + vci = nm_setting_adsl_get_vci (s_adsl); > + vpivci = g_strdup_printf("%s.%s", vpi, vci); > + > + nm_cmd_line_add_string (cmd, "-e"); > + nm_cmd_line_add_int (cmd, is_llc ? 0 : 1); > + nm_cmd_line_add_string (cmd, "-p"); > + nm_cmd_line_add_int (cmd, is_pppoe ? 1 : 0); > + nm_cmd_line_add_string (cmd, "-a"); > + nm_cmd_line_add_string (cmd, vpivci); > + > + g_free(vpivci); > + > + return cmd; > +} > + > +static void > +br2684_child_setup (gpointer user_data G_GNUC_UNUSED) > +{ > + /* We are in the child process at this point */ > + pid_t pid = getpid (); > + setpgid (pid, pid); > +} > + > +static void > +br2684_watch_cb (GPid pid, gint status, gpointer user_data) > +{ > + NMBr2684Manager *manager = NM_BR2684_MANAGER (user_data); > + NMBr2684ManagerPrivate *priv = NM_BR2684_MANAGER_GET_PRIVATE (manager); > + guint err; > + > + g_assert (pid == priv->pid); > + > + if (WIFEXITED (status)) { > + err = WEXITSTATUS (status); > + } else if (WIFSTOPPED (status)) { > + nm_log_info (LOGD_BR2684, "br2684ctl pid %d stopped > unexpectedly with signal %d", priv->pid, WSTOPSIG (status)); > + } else if (WIFSIGNALED (status)) { > + nm_log_info (LOGD_BR2684, "br2684ctl pid %d died with signal > %d", priv->pid, WTERMSIG (status)); > + } else > + nm_log_info (LOGD_BR2684, "br2684ctl pid %d died from an > unknown cause", priv->pid); > + > + nm_log_dbg (LOGD_BR2684, "br2684ctl pid %d cleaned up", priv->pid); > + priv->pid = 0; > +} > + > + > +/* API Functions */ > + > +gboolean nm_br2684_manager_start (NMBr2684Manager *manager, > + NMActRequest *req, > + guint32 timeout_secs, > + GError **err) > +{ > + NMBr2684ManagerPrivate *priv; > + NMConnection *connection; > + NMSettingAdsl *adsl_setting; > + NMCmdLine *b2684_cmd; > + char *cmd_str; > + > + g_return_val_if_fail (NM_IS_BR2684_MANAGER (manager), FALSE); > + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); > + > + priv = NM_BR2684_MANAGER_GET_PRIVATE (manager); > + priv->pid = 0; > + > + connection = nm_act_request_get_connection (req); > + g_assert (connection); > + > + adsl_setting = (NMSettingAdsl *) nm_connection_get_setting (connection, > NM_TYPE_SETTING_ADSL); > + > + b2684_cmd = create_br2684ctl_cmd_line (manager, adsl_setting, err); > + if (!b2684_cmd) > + goto out; > + > + g_ptr_array_add (b2684_cmd->array, NULL); > + > + nm_log_info (LOGD_BR2684, "starting RFC 2684 Bridge"); > + > + cmd_str = nm_cmd_line_to_str (b2684_cmd); > + nm_log_dbg (LOGD_BR2684, "command line: %s", cmd_str); > + g_free (cmd_str); > + > + priv->pid = 0; > + if (!g_spawn_async (NULL, (char **) b2684_cmd->array->pdata, NULL, > + G_SPAWN_DO_NOT_REAP_CHILD, > + br2684_child_setup, > + NULL, &priv->pid, err)) > + goto out; > + > + nm_log_info (LOGD_BR2684, "br2684ctl started with pid %d", priv->pid); > + > + priv->br2684_watch_id = g_child_watch_add (priv->pid, (GChildWatchFunc) > br2684_watch_cb, manager); > + > +out: > + if (b2684_cmd) > + nm_cmd_line_destroy (b2684_cmd); > + > + return (priv->pid > 0); > +} > + > +NMBr2684Manager *nm_br2684_manager_new () > +{ > + return (NMBr2684Manager *) g_object_new (NM_TYPE_BR2684_MANAGER, > + NULL); > +} > diff --git a/src/br2684-manager/nm-br2684-manager.h > b/src/br2684-manager/nm-br2684-manager.h > new file mode 100644 > index 0000000..dc73639 > --- /dev/null > +++ b/src/br2684-manager/nm-br2684-manager.h > @@ -0,0 +1,64 @@ > +/* -*- 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. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + * > + * Author: Pantelis Koukousoulas <[email protected]> > + */ > + > +#ifndef NM_BR2684_MANAGER_H > +#define NM_BR2864_MANAGER_H > + > +#include <glib.h> > +#include <glib-object.h> > + > +#include "nm-activation-request.h" > +#include "nm-connection.h" > +#include "nm-ip4-config.h" > + > +#define NM_TYPE_BR2684_MANAGER (nm_br2684_manager_get_type ()) > +#define NM_BR2684_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST > ((obj), NM_TYPE_BR2684_MANAGER, NMBr2684Manager)) > +#define NM_BR2684_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), > NM_TYPE_BR2684_MANAGER, NMBr2684ManagerClass)) > +#define NM_IS_BR2684_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE > ((obj), NM_TYPE_BR2684_MANAGER)) > +#define NM_IS_BR2684_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), > NM_TYPE_BR2684_MANAGER)) > +#define NM_BR2684_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), > NM_TYPE_BR2684_MANAGER, NMBr2684ManagerClass)) > + > +typedef struct { > + GObject parent; > +} NMBr2684Manager; > + > +typedef struct { > + GObjectClass parent; > + > + /* Signals */ > + void (*state_changed) (NMBr2684Manager *manager, guint state); > +} NMBr2684ManagerClass; > + > +GType nm_br2684_manager_get_type (void); > + > +NMBr2684Manager *nm_br2684_manager_new (void); > + > +gboolean nm_br2684_manager_start (NMBr2684Manager *manager, > + NMActRequest *req, > + guint32 timeout_secs, > + GError **err); > + > + > +#define NM_BR2684_MANAGER_ERROR nm_br2684_manager_error_quark() > +#define NM_TYPE_BR2684_MANAGER_ERROR (nm_br2684_manager_error_get_type ()) > + > +GQuark nm_br2684_manager_error_quark (void); > + > +#endif /* NM_BR2684_MANAGER_H */ > diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c > index 1e289d3..5b7637b 100644 > --- a/src/logging/nm-logging.c > +++ b/src/logging/nm-logging.c > @@ -44,7 +44,7 @@ static guint32 log_domains = \ > LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_IP4 | LOGD_IP6 | LOGD_AUTOIP4 > | \ > LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_AGENTS | \ > LOGD_SETTINGS | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH > | \ > - LOGD_WIMAX; > + LOGD_WIMAX | LOGD_BR2684; > > typedef struct { > guint32 num; > @@ -85,6 +85,7 @@ static const LogDesc domain_descs[] = { > { LOGD_DEVICE, "DEVICE" }, > { LOGD_OLPC_MESH, "OLPC" }, > { LOGD_WIMAX, "WIMAX" }, > + { LOGD_BR2684, "BR2684" }, > { 0, NULL } > }; > > diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h > index 44e49a7..cd05ada 100644 > --- a/src/logging/nm-logging.h > +++ b/src/logging/nm-logging.h > @@ -52,6 +52,7 @@ enum { > LOGD_DEVICE = 0x00200000, /* Device state and activation */ > LOGD_OLPC_MESH = 0x00400000, > LOGD_WIMAX = 0x00800000, > + LOGD_BR2684 = 0x01000000, > }; > > #define LOGD_DHCP (LOGD_DHCP4 | LOGD_DHCP6) > diff --git a/src/nm-device-adsl.c b/src/nm-device-adsl.c > index 77e4d0a..8850558 100644 > --- a/src/nm-device-adsl.c > +++ b/src/nm-device-adsl.c > @@ -31,8 +31,10 @@ > #include "nm-glib-compat.h" > #include "NetworkManagerUtils.h" > #include "nm-logging.h" > +#include "nm-system.h" > > #include "ppp-manager/nm-ppp-manager.h" > +#include "br2684-manager/nm-br2684-manager.h" > #include "nm-setting-adsl.h" > > #include "nm-device-adsl-glue.h" > @@ -68,6 +70,9 @@ typedef struct { > /* PPP */ > NMPPPManager *ppp_manager; > NMIP4Config *pending_ip4_config; > + > + /* RFC 2684 bridging (PPPoE over ATM) */ > + NMBr2684Manager *br2684_manager; > } NMDeviceAdslPrivate; > > enum { > @@ -222,7 +227,6 @@ dispose (GObject *object) > priv->carrier_poll_id = 0; > } > > - > G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); > } > > @@ -316,7 +320,7 @@ real_check_connection_compatible (NMDevice *device, > } > > s_adsl = (NMSettingAdsl *) nm_connection_get_setting (connection, > NM_TYPE_SETTING_ADSL); > - /* Wired setting is optional for PPPoE */ > + > if (!s_adsl) { > g_set_error (error, > NM_ADSL_ERROR, NM_ADSL_ERROR_CONNECTION_INVALID, > @@ -371,6 +375,11 @@ real_deactivate (NMDevice *device) > g_object_unref (priv->ppp_manager); > priv->ppp_manager = NULL; > } > + > + if (priv->br2684_manager) { > + g_object_unref (priv->br2684_manager); > + priv->br2684_manager = NULL; > + } > } > > static NMConnection * > @@ -405,13 +414,29 @@ real_get_best_auto_connection (NMDevice *dev, > return NULL; > } > > +static void > +br2684_state_changed (NMBr2684Manager *manager, guint status, gpointer > user_data) > +{ > + NMDevice *device = NM_DEVICE (user_data); > + > + if (status) { > + nm_system_device_set_up_down_with_iface ("nas0", TRUE, NULL); > + nm_device_activate_schedule_stage2_device_config (device); > + } else { > + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, > NM_DEVICE_STATE_REASON_BR2684_FAILED); > + } > +} > + > static NMActStageReturn > real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) > { > NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; > NMDeviceAdsl *self = NM_DEVICE_ADSL (dev); > + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); > NMActRequest *req; > NMSettingAdsl *s_adsl; > + GError *err = NULL; > + const char *protocol; > > g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); > > @@ -421,6 +446,22 @@ real_act_stage1_prepare (NMDevice *dev, > NMDeviceStateReason *reason) > s_adsl = NM_SETTING_ADSL (device_get_setting (dev, > NM_TYPE_SETTING_ADSL)); > g_assert (s_adsl); > > + protocol = nm_setting_adsl_get_protocol (s_adsl); > + if (!strcmp (protocol, "pppoe")) { > + priv->br2684_manager = nm_br2684_manager_new(); > + if (!nm_br2684_manager_start (priv->br2684_manager, req, 30, > &err)) { > + nm_log_warn (LOGD_DEVICE, "(%s): RFC 2684 bridge failed > to start: %s", > + nm_device_get_iface > (NM_DEVICE (self)), err->message); > + ret = NM_ACT_STAGE_RETURN_FAILURE; > + goto out; > + } > + g_signal_connect (priv->br2684_manager, "state-changed", > + G_CALLBACK (br2684_state_changed), > + self); > + ret = NM_ACT_STAGE_RETURN_POSTPONE; > + } > + > +out: > return ret; > } > > @@ -494,7 +535,7 @@ pppoa_stage3_ip4_config_start (NMDeviceAdsl *self, > NMDeviceStateReason *reason) > self); > ret = NM_ACT_STAGE_RETURN_POSTPONE; > } else { > - nm_log_warn (LOGD_DEVICE, "(%s): ADSL(PPPoA) failed to start: > %s", > + nm_log_warn (LOGD_DEVICE, "(%s): ADSL failed to start: %s", > nm_device_get_iface (NM_DEVICE (self)), > err->message); > g_error_free (err); > > diff --git a/src/nm-device.c b/src/nm-device.c > index 34e1b3a..32897e2 100644 > --- a/src/nm-device.c > +++ b/src/nm-device.c > @@ -3824,6 +3824,8 @@ reason_to_string (NMDeviceStateReason reason) > return "modem-not-found"; > case NM_DEVICE_STATE_REASON_BT_FAILED: > return "bluetooth-failed"; > + case NM_DEVICE_STATE_REASON_BR2684_FAILED: > + return "br2684 bridge failed"; > default: > break; > } > diff --git a/src/ppp-manager/nm-ppp-manager.c > b/src/ppp-manager/nm-ppp-manager.c > index 0704c3a..e4580c0 100644 > --- a/src/ppp-manager/nm-ppp-manager.c > +++ b/src/ppp-manager/nm-ppp-manager.c > @@ -796,7 +796,7 @@ static NMCmdLine * > create_pppd_cmd_line (NMPPPManager *self, > NMSettingPPP *setting, > NMSettingPPPOE *pppoe, > - NMSettingAdsl *adsl_pppoa, > + NMSettingAdsl *adsl, > const char *ppp_name, > GError **err) > { > @@ -849,27 +849,36 @@ create_pppd_cmd_line (NMPPPManager *self, > nm_cmd_line_add_string (cmd, "rp_pppoe_service"); > nm_cmd_line_add_string (cmd, pppoe_service); > } > - } else if (adsl_pppoa) { > - const char *vpi; > - const char *vci; > - const gchar *encapsulation; > - gchar *vpivci; > - > - vpi = nm_setting_adsl_get_vpi (adsl_pppoa); > - vci = nm_setting_adsl_get_vci (adsl_pppoa); > - encapsulation = nm_setting_adsl_get_encapsulation (adsl_pppoa); > - vpivci = g_strdup_printf("%s.%s", vpi, vci); > - > - nm_cmd_line_add_string (cmd, "plugin"); > - nm_cmd_line_add_string (cmd, "pppoatm.so"); > - nm_cmd_line_add_string (cmd, vpivci); > - > - if (!strcmp (encapsulation, "llc")) > - nm_cmd_line_add_string (cmd, "llc-encaps"); > + } else if (adsl) { > + const gchar *protocol = nm_setting_adsl_get_protocol (adsl); > + > + if (!strcmp (protocol, "pppoa")) { > + const char *vpi; > + const char *vci; > + const gchar *encapsulation; > + gchar *vpivci; > + > + vpi = nm_setting_adsl_get_vpi (adsl); > + vci = nm_setting_adsl_get_vci (adsl); > + encapsulation = nm_setting_adsl_get_encapsulation > (adsl); > + vpivci = g_strdup_printf("%s.%s", vpi, vci); > + > + nm_cmd_line_add_string (cmd, "plugin"); > + nm_cmd_line_add_string (cmd, "pppoatm.so"); > + nm_cmd_line_add_string (cmd, vpivci); > + > + if (!strcmp (encapsulation, "llc")) > + nm_cmd_line_add_string (cmd, "llc-encaps"); > + > + g_free (vpivci); > + } else if (!strcmp (protocol, "pppoe")) { > + nm_cmd_line_add_string (cmd, "plugin"); > + nm_cmd_line_add_string (cmd, "rp-pppoe.so"); > + nm_cmd_line_add_string (cmd, "nas0"); > + } > > nm_cmd_line_add_string (cmd, "noipdefault"); > > - g_free (vpivci); > } else { > nm_cmd_line_add_string (cmd, priv->parent_iface); > /* Don't send some random address as the local address */ _______________________________________________ networkmanager-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/networkmanager-list
