Support 4G/5G automatic reconnection using ModemManager

Any other ideas to try @vgaetera? Is it possible to issue mmcli connect and DHCP renew of sorts?

I just can't seem to get something that's faster than 'ifup $CFG' that works. I tried mmcli connect followed by renew, but that doesn't work.

It seems mmcli connect after disconnect is pretty much instantaneous and new IP details are reported in logread. But how to get those new details from modemmanager to netifd? Since otherwise 'ifstatus wan' shows bad details despite the proper reconnect.

Thinking about what is apparently missing from OpenWrt right now according to the modemmanager developer:

The way to solve this, after briefly talking with @jow- about this in IRC would be to have the netifd protocol handler launch a "watcher" process which brings up the connection, and is kept alive and running for as long as the network interface is assumed connected. If MM detects a network-initiated disconnection, the dispatcher script called by MM should kill that watcher process. At that point, netifd (if configured to autoconnect) will then kill the netdev, restart that process and await proto updates.

Anyone up to the task of writing this logic in the netfid modemmanager protocol handler?

perhaps that watcher process arrangement could give speedier reconnects somehow by dispensing with the need for the time consuming ifdown and ifup, whilst at the same time managing the IP change?

@mkrle any ideas?

It seems OpenWrt really needs a volunteer to implement the necessary changes to the netifd modemmanager protocol handler.

Can you try commenting out this line in /lib/netifd/proto/modemmanager.sh and checking if it sufficiently reduces the time taken by ifup:

mmcli --modem="${device}" --disable
2 Likes

Excellent call. That significantly reduces the reconnect time on my NR7101 from around five seconds to around three seconds. I wonder in what situations the temporally costly modem disable is actually needed?

Since we surely want the fastest possible reconnect, I wonder whether there might be any other optimisations available to try.

In my script:

root@OpenWrt:~# cat /usr/lib/ModemManager/connection.d/10-report-down-and-reconnect
#!/bin/sh

# Automatically report to netifd that the underlying modem
# is really disconnected and reconnect if interface was up

# require program name and at least 4 arguments
[ $# -lt 4 ] && exit 1

MODEM_PATH="$1"
BEARER_PATH="$2"
INTERFACE="$3"
STATE="$4"

[ "${STATE}" = "disconnected" ] || exit 0

. /usr/share/ModemManager/modemmanager.common
. /lib/netifd/netifd-proto.sh
INCLUDE_ONLY=1 . /lib/netifd/proto/modemmanager.sh

MODEM_STATUS=$(mmcli --modem="${MODEM_PATH}" --output-keyvalue)
[ -n "${MODEM_STATUS}" ] || exit 1

MODEM_DEVICE=$(modemmanager_get_field "${MODEM_STATUS}" "modem.generic.device")
[ -n "${MODEM_DEVICE}" ] || exit 2

CFG=$(mm_get_modem_config "${MODEM_DEVICE}")
[ -n "${CFG}" ] || exit 3

IFUP=$(ifstatus ${CFG} | jsonfilter -e '@.up')

logger -t "modemmanager" "interface ${CFG} (network device ${INTERFACE}) ${STATE}"
proto_init_update $INTERFACE 0
proto_send_update $CFG

[ "${IFUP}" = "true" ] && ifup ${CFG}

exit 0

what does:

proto_init_update $INTERFACE 0
proto_send_update $CFG

actually do before the [ "${IFUP}" = "true" ] && ifup ${CFG} call?

1 Like

My view of the protocol handlers is that they are designed to be simple - setup and teardown (+renew). When MM starts up (and before ifup), it puts the modem in initialized/disabled. state, so it makes sense for teardown to put it back in disabled state on ifdown.

What comes to my mind could be:

  • Add an uci setting to skip disable on teardown or
  • Trigger renew from the MM-down script, and implement renew as a minimal possible version of what the setup is already doing, e.g. just simple connect + IP setup

There seems to be some logic to this in my mind.

Any idea how this should change for that:

root@OpenWrt:~# cat /usr/lib/ModemManager/connection.d/10-report-down-and-reconnect
#!/bin/sh

# Automatically report to netifd that the underlying modem
# is really disconnected and reconnect if interface was up

# require program name and at least 4 arguments
[ $# -lt 4 ] && exit 1

MODEM_PATH="$1"
BEARER_PATH="$2"
INTERFACE="$3"
STATE="$4"

[ "${STATE}" = "disconnected" ] || exit 0

. /usr/share/ModemManager/modemmanager.common
. /lib/netifd/netifd-proto.sh
INCLUDE_ONLY=1 . /lib/netifd/proto/modemmanager.sh

MODEM_STATUS=$(mmcli --modem="${MODEM_PATH}" --output-keyvalue)
[ -n "${MODEM_STATUS}" ] || exit 1

MODEM_DEVICE=$(modemmanager_get_field "${MODEM_STATUS}" "modem.generic.device")
[ -n "${MODEM_DEVICE}" ] || exit 2

CFG=$(mm_get_modem_config "${MODEM_DEVICE}")
[ -n "${CFG}" ] || exit 3

IFUP=$(ifstatus ${CFG} | jsonfilter -e '@.up')

logger -t "modemmanager" "interface ${CFG} (network device ${INTERFACE}) ${STATE}"
proto_init_update $INTERFACE 0
proto_send_update $CFG

[ "${IFUP}" = "true" ] && ifup ${CFG}

exit 0
1 Like

A year later, in the latest openwrt 23.05 and main line tasks.
There is still no change in the Modemmanager, and I cannot reconnect myself after disconnecting the link.
You must manually click Reconnect on the network port interface to work properly.
Is anyone willing to think of a solution?

See post before yours. It’s a hack, but it works.

Well, it works with ModemManager only. ModemManager is quite big and thus unwelcome on smaller devices. When used with Huawei modems, it needlessly disables IPv6 (see my bug report from 5 years ago). Also, it is incompatible with luci-app-3ginfo-lite and luci-app-sms-tool-js from @IceG. So, it is not a universally acceptable solution, but, sadly, we don't have any other.

The problem I see with uqmi and most other tools is that they need exclusive access to cdc-wdm device and/or USB serial (AT command) port. So a centralized daemon to manage/serialize requests and monitor/notify on events is probably need. This is more or less exactly what MM already does - heavy as it is I find it well architected, with an API/library, modem drivers etc.

It'd be great if we could get some feedback from the OpenWRT gurus on what the ideal architecture to manage the modem (re)connections would be, as I believe ifdown/ifup may be too heavy (slow) for this task. Otherwise we'll be stuck in the world of scripts and hacks.

3 Likes