summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2014-04-04 11:50:20 -0400
committerDan Winship <danw@gnome.org>2014-04-14 10:11:05 -0400
commit7955806a02db64b20079267743056d7d9d45af3b (patch)
treebec0b438998d9646b81c10a328254fcdcd54bdfd
parentebc5ea0b80072b5026d8fb220208befd00bdd2c3 (diff)
ppp-manager: don't use kernel pppoe (rh #1034860, rh #1061641)
The kernel PPPoE code disconnects when it receives a PADT frame, but doesn't notify userland about it. So if the server sends a PPPoE PADT without having sent the standard PPP LCP Termination request first, then pppd (and thus NetworkManager) will not know that the connection has been disconnected. This should eventually be fixed in the kernel, but for now, work around this by using the userland pppoe client rather than the kernel code.
-rw-r--r--configure.ac9
-rw-r--r--src/ppp-manager/nm-ppp-manager.c88
2 files changed, 69 insertions, 28 deletions
diff --git a/configure.ac b/configure.ac
index 4f5183107..74db8c112 100644
--- a/configure.ac
+++ b/configure.ac
@@ -546,6 +546,15 @@ fi
AC_DEFINE_UNQUOTED(PPPD_PATH, "$PPPD_PATH", [Define to path of pppd binary])
AC_SUBST(PPPD_PATH)
+AC_ARG_WITH(pppoe, AS_HELP_STRING([--with-pppoe=/path/to/pppoe], [path to pppoe binary]))
+if test "x${with_pppoe}" = x; then
+ AC_PATH_PROG(PPPOE_PATH, pppoe, [], $PATH:/sbin:/usr/sbin)
+else
+ PPPOE_PATH="$with_pppoe"
+fi
+AC_DEFINE_UNQUOTED(PPPOE_PATH, "$PPPOE_PATH", [Define to path of pppoe binary])
+AC_SUBST(PPPOE_PATH)
+
# ModemManager1 with libmm-glib
AC_ARG_WITH(modem-manager-1, AS_HELP_STRING([--with-modem-manager-1], [Enable new ModemManager1 interface support]),,[with_modem_manager_1=auto])
if (test "${with_modem_manager_1}" != "no"); then
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index 9ab140db1..54308376c 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -647,26 +647,34 @@ nm_cmd_line_add_int (NMCmdLine *cmd, int i)
/*******************************************/
+static const char *pppd_binary_paths[] = {
+ PPPD_PATH,
+ "/usr/local/sbin/pppd",
+ "/usr/sbin/pppd",
+ "/sbin/pppd",
+ NULL
+};
+
+static const char *pppoe_binary_paths[] = {
+ PPPOE_PATH,
+ "/usr/local/sbin/pppoe",
+ "/usr/sbin/pppoe",
+ "/sbin/pppoe",
+ NULL
+};
+
static inline const char *
-nm_find_pppd (void)
+nm_find_binary (const char *paths[])
{
- static const char *pppd_binary_paths[] = {
- PPPD_PATH,
- "/usr/local/sbin/pppd",
- "/usr/sbin/pppd",
- "/sbin/pppd",
- NULL
- };
-
- const char **pppd_binary = pppd_binary_paths;
-
- while (*pppd_binary != NULL) {
- if (**pppd_binary && g_file_test (*pppd_binary, G_FILE_TEST_EXISTS))
+ const char **binary = paths;
+
+ while (*binary != NULL) {
+ if (**binary && g_file_test (*binary, G_FILE_TEST_EXISTS))
break;
- pppd_binary++;
+ binary++;
}
- return *pppd_binary;
+ return *binary;
}
static void
@@ -788,19 +796,29 @@ create_pppd_cmd_line (NMPPPManager *self,
GError **err)
{
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
- const char *pppd_binary;
+ const char *pppd_binary, *pppoe_binary = NULL;
NMCmdLine *cmd;
gboolean ppp_debug;
g_return_val_if_fail (setting != NULL, NULL);
- pppd_binary = nm_find_pppd ();
+ pppd_binary = nm_find_binary (pppd_binary_paths);
if (!pppd_binary) {
g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR,
"Could not find pppd binary.");
return NULL;
}
+ if ( pppoe
+ || (adsl && strcmp (nm_setting_adsl_get_protocol (adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE))) {
+ pppoe_binary = nm_find_binary (pppoe_binary_paths);
+ if (!pppoe_binary) {
+ g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR,
+ "Could not find pppoe binary.");
+ return NULL;
+ }
+ }
+
/* Create pppd command line */
cmd = nm_cmd_line_new ();
nm_cmd_line_add_string (cmd, pppd_binary);
@@ -828,21 +846,30 @@ create_pppd_cmd_line (NMPPPManager *self,
}
if (pppoe) {
- char *dev_str;
+ GString *pppoe_arg;
const char *pppoe_service;
+ char *quoted;
- nm_cmd_line_add_string (cmd, "plugin");
- nm_cmd_line_add_string (cmd, "rp-pppoe.so");
+ g_assert (pppoe_binary != NULL);
+ pppoe_arg = g_string_new (pppoe_binary);
- dev_str = g_strdup_printf ("nic-%s", priv->parent_iface);
- nm_cmd_line_add_string (cmd, dev_str);
- g_free (dev_str);
+ g_string_append (pppoe_arg, " -I ");
+ quoted = g_shell_quote (priv->parent_iface);
+ g_string_append (pppoe_arg, quoted);
+ g_free (quoted);
pppoe_service = nm_setting_pppoe_get_service (pppoe);
if (pppoe_service) {
- nm_cmd_line_add_string (cmd, "rp_pppoe_service");
- nm_cmd_line_add_string (cmd, pppoe_service);
+ g_string_append (pppoe_arg, " -S ");
+ quoted = g_shell_quote (pppoe_service);
+ g_string_append (pppoe_arg, quoted);
+ g_free (quoted);
}
+
+ nm_cmd_line_add_string (cmd, "pty");
+ nm_cmd_line_add_string (cmd, pppoe_arg->str);
+
+ g_string_free (pppoe_arg, TRUE);
} else if (adsl) {
const gchar *protocol = nm_setting_adsl_get_protocol (adsl);
@@ -865,9 +892,14 @@ create_pppd_cmd_line (NMPPPManager *self,
nm_cmd_line_add_string (cmd, "vc-encaps");
} else if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) {
- nm_cmd_line_add_string (cmd, "plugin");
- nm_cmd_line_add_string (cmd, "rp-pppoe.so");
- nm_cmd_line_add_string (cmd, priv->parent_iface);
+ char *pppoe_arg;
+
+ g_assert (pppoe_binary != NULL);
+
+ pppoe_arg = g_strdup_printf ("%s -I %s", pppoe_binary, priv->parent_iface);
+ nm_cmd_line_add_string (cmd, "pty");
+ nm_cmd_line_add_string (cmd, pppoe_arg);
+ g_free (pppoe_arg);
}
nm_cmd_line_add_string (cmd, "noipdefault");