summaryrefslogtreecommitdiff
path: root/src/devices
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2016-10-06 11:27:45 -0500
committerDan Williams <dcbw@redhat.com>2016-10-07 14:54:27 -0500
commit6126c32e6bd58c3f83d834d3b28fa3f3cfc176c8 (patch)
treed80feba4b7bee1457f1aff4cf22c409e99a48e05 /src/devices
parent3ceaef90fefbaf3199a8d52c5cfaa06420a81747 (diff)
downloadNetworkManager-6126c32e6bd58c3f83d834d3b28fa3f3cfc176c8.tar.gz
wwan/ppp: send explicit port speed to pppd when port speed is zero (rh #1281731)
Some TTY drivers or devices appear to ignore port speed and always report zero. Technically this means the port is hung up and control lines should be disconnected, but with USB devices many of the serial port attributes are meaningless and ignored by some devices. pppd requires the port's speed to be greater than zero, and will exit immediately when that is not the case, even though these modems will work fine. Passing an explicit speed to pppd in this case works around the issue, as pppd attempts to set that speed on the port and doesn't actually care if that operation fails. https://bugzilla.redhat.com/show_bug.cgi?id=1281731
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/adsl/nm-device-adsl.c2
-rw-r--r--src/devices/nm-device-ethernet.c2
-rw-r--r--src/devices/wwan/nm-modem.c30
3 files changed, 31 insertions, 3 deletions
diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c
index a5b6641abf..d1d0a9b0de 100644
--- a/src/devices/adsl/nm-device-adsl.c
+++ b/src/devices/adsl/nm-device-adsl.c
@@ -477,7 +477,7 @@ act_stage3_ip4_config_start (NMDevice *device,
}
priv->ppp_manager = nm_ppp_manager_new (ppp_iface);
- if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_adsl_get_username (s_adsl), 30, &err)) {
+ if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_adsl_get_username (s_adsl), 30, 0, &err)) {
g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_STATE_CHANGED,
G_CALLBACK (ppp_state_changed),
self);
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index fd80a607a2..3604a168a8 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -937,7 +937,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas
g_assert (s_pppoe);
priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (NM_DEVICE (self)));
- if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_pppoe_get_username (s_pppoe), 30, &err)) {
+ if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_pppoe_get_username (s_pppoe), 30, 0, &err)) {
g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_STATE_CHANGED,
G_CALLBACK (ppp_state_changed),
self);
diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c
index d5f12b1cc2..9897424466 100644
--- a/src/devices/wwan/nm-modem.c
+++ b/src/devices/wwan/nm-modem.c
@@ -23,7 +23,9 @@
#include "nm-modem.h"
+#include <fcntl.h>
#include <string.h>
+#include <termios.h>
#include "nm-core-internal.h"
#include "nm-platform.h"
@@ -492,6 +494,23 @@ ppp_stats (NMPPPManager *ppp_manager,
}
}
+static gboolean
+port_speed_is_zero (const char *port)
+{
+ struct termios options;
+ gs_fd_close int fd = -1;
+
+ fd = open (port, O_RDWR | O_NONBLOCK | O_NOCTTY);
+ if (fd < 0)
+ return FALSE;
+
+ memset (&options, 0, sizeof (struct termios));
+ if (tcgetattr (fd, &options) != 0)
+ return FALSE;
+
+ return cfgetospeed (&options) == B0;
+}
+
static NMActStageReturn
ppp_stage3_ip_config_start (NMModem *self,
NMActRequest *req,
@@ -502,6 +521,7 @@ ppp_stage3_ip_config_start (NMModem *self,
GError *error = NULL;
NMActStageReturn ret;
guint ip_timeout = 30;
+ guint baud_override = 0;
g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE);
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE);
@@ -531,8 +551,16 @@ ppp_stage3_ip_config_start (NMModem *self,
ip_timeout = priv->mm_ip_timeout;
}
+ /* Some tty drivers and modems ignore port speed, but pppd requires the
+ * port speed to be > 0 or it exits. If the port speed is 0 pass an
+ * explicit speed to pppd to prevent the exit.
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1281731
+ */
+ if (port_speed_is_zero (priv->data_port))
+ baud_override = 57600;
+
priv->ppp_manager = nm_ppp_manager_new (priv->data_port);
- if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, &error)) {
+ if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, baud_override, &error)) {
g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_STATE_CHANGED,
G_CALLBACK (ppp_state_changed),
self);