Table of Contents

Use USB QMI or CDC-MBIM capable dongles for WWAN connection

Many currently-available cellular modems use USB CDC-MBIM standard device class (or the ancestor Qualcomm's QMI) to interact with the host system, e.g. with an OpenWrt router or a PC or a smartphone with WWAN connectivity. For your information, QMI is a proprietary protocol by Qualcomm which has been used by many devices from different vendors as well. MBIM is a standard protocol (inspired by QMI) from the USB Implementer's Forum. Differences between QMI and CDC-MBIM are mostly related to stripping the Qualcomm-specific features while adding support for generic vendor-specific extensions.

The Linux driver for QMI is called qmi_wwan, the driver for CDC-MBIM is called cdc_mbim. They both rely on the common cdc_wdm driver.

This recipe explains how to setup and configure OpenWrt for using cellular USB modems for WWAN connection, using either MBIM or QMI interfaces.

The same applies to modems connected to external USB ports and internal USB-capable M.2(NGFF) or miniPCIe slots.

You may want to checkout the mwan3 (Multi WAN load balancing/failover) package to use this simultaneously with other connections to the Internet.

Also, see the Optimization sub-section of this page, for certain issues with MTU and Bufferbloat management.

About

Many modern USB modems may operate in different modes. If your modem provides only serial interface(s) like pushing data across /dev/ttyUSBx (PPP Mode) instead of only using that interface for AT commands, please refer to the 3GDongle Wiki Page on how to use 3g/UMTS USB Dongle for WAN connection. For more information about other protocols commonly used:

If it is possible to switch your modem to provide QMI or MBIM interface - then this article is for you.

Router Preparation

1. Install OpenWrt release image for your device.

2. Complete Steps OpenWrt Configuration

3. Router should be turned on and connected to the Internet to get the needed packages. Please refer to: Internet Connection.

Additional Required Packages

To make use of QMI protocol, packages kmod-usb-net-qmi-wwan (driver) and uqmi (control utility) are needed, additionally luci-proto-qmi (for web interface support). For MBIM protocol, the package equivalents are kmod-usb-net-cdc-mbim, umbim, and luci-proto-mbim. Additionally, there is the ModemManager package, which takes control of the modem using the MBIM protocol, and adds a web interface page luci-app-modemmanager.

Support for the particular modem's serial interfaces (/dev/ttyUSBx) - require packages such as kmod-usb-serial-option, kmod-usb-serial-qualcomm or kmod-usb-serial-sierrawireless, depending on the modem. They are needed to interact with the modem using AT commands, for configuration purposes or to be able to send/receive SMS and USSD.

A terminal program like picocom will be needed to interactively send & receive AT commands. picocom /dev/ttyUSB2 is the typical shell command to start communicating with AT commands.

If you are building Openwrt, see build-image-with-3g-dongle-support

Optional Packages

1. Web protocol support (LuCI) as stated earlier - install luci-proto-qmi for QMI or luci-proto-mbim for MBIM, to use the web interface to configure and visualize your connection.

2. Install usb-modeswitch package only if that is needed for switching the modem into a “working” state. More about: USB mode switch

3. If available, add support for storage component of your modem - refer to: USB Storage

4. Additional utilities for modems that can be added to an Openwrt build, are available at https://github.com/koshev-msk/modemfeed repository. To add them to your build environment, cp 'feeds.conf.default' to 'feeds.conf', and add the line: src-git modemfeed https://github.com/koshev-msk/modemfeed.git. It includes a luci-app-modeminfo, that requires you also select the underlying component, like modeminfo-qmi, in your build configuration. This functions similar to luci-app-modemmanager, but unlike modemmanager, aims to simply display the cellular connection information, rather than controlling the modem connection aggressively/directly.

5. There is a lot of additional, useful information that can save you a lot of time, at this repository https://github.com/danielewood/sierra-wireless-modems, if you have a Sierra modem. If you have a Quectel device, their support forum is a decent location to find information.

Sample installation

1. Install all the needed packages either in LuCI → System → Software or via command line: See Modem Preparation below, if you have picocom serial interface working, but are not sure what mode the modem is in.

:!: If your have not enough space on your device - think about upgrading your hardware or installing Rootfs on External Storage (extroot). Refer to your router wiki page or forum thread for possibility and instructions. Also, there are devices that have plenty of actual space, but are partitioned poorly by the OEM. A stock Openwrt image tries to be conservative, so you can flash back to the manufacturer's firmware. You can look into repartitioning your device, but this is outside the scope of this article.

2. Reboot the router by executing reboot on the console.

3. Check if you got a new device:

root@OpenWrt:~# ls -l /dev/cdc*

crw-r--r--    1 root     root      180, 176 Oct  1 12:03 /dev/cdc-wdm0

If there is no such device found - try to get more details:

See Troubleshooting Section of this page for more information.

Modem Preparation

Unlike conventional interfaces, cell modems have to be 'prepared' to be in the right mode. They may come shipped in one mode, but you prefer to use another. Or your needs require a different mode.

Legacy Modem Preparation

If QMI or MBIM interface is not exposed by the modem initially you may need to switch it to another mode or composition by using USB mode switch tool or a vendor-specific AT command.

:!: You can read further about AT commands for your modem. Typically, the command is 'picocom /dev/ttyUSB2'.

LTE or 5G Modem Preparation

More recent modems are set by default to MBIM or QMI mode.

This is an example of switching modes for popular Quectel modems (these are manufacturer-specific, don't expect them to work on devices from other manufacturers):

AT+QCFG="usbnet"	# check the current mode
AT+QCFG="usbnet",0	# set QMI or RMNET mode, or
AT+QCFG="usbnet",1	# set ECM mode, or
AT+QCFG="usbnet",2	# set MBIM mode

Reboot the modem to apply changes - power toggle it, or send AT+CFUN=1,1 command.

The equivalent commands for Sierra Wireless (SEMTECH) modems:

AT!ENTERCND="A710"	# enter the configuration mode allowing you to make certain administrative changes
AT!USBCOMP?		# check the current mode
AT!USBCOMP=1,1,10D	# set QMI mode, or
AT!USBCOMP=1,1,100D	# set MBIM mode
AT!RESET		# Reset and apply the changes


Although the APN, Authentication Type and PDP (IPv4, v6 or both) are set through the LuCI web interface, it may be worth familiarizing yourself with the list of stored PDP Contexts and APNs configured on the modem.

To see the stored values, use a standard 3GPP command: AT+CGDCONT?

Typically, but not always, context #1 is used for the Internet connection. On Verizon, it's Context 3, and Context 1 is used for IMS (Messaging services, SMS).

If it is not configured with the correct information (IP type and APN), it is recommended to set the desired parameters. Example:

AT+CGDCONT=1,"IP","internet"

Replace IP with IPV4V6 or IPV6 if necessary and use your APN instead of internet.

More specific examples:

Verizon has strict guidelines on how the PDP Contexts are supposed to be set-up, all the way back from at least 10 years ago (2017). See more references here and here and here.

For an alternative method, see Manual validation section below.


While in the terminal, check the modem firmware version with ATI, and see if there is an upgrade available on the manufacturer's support website or forum. Oftentimes, it improves performance. But on some modems, it may have unintended consequences. It is best, but not necessary, if you have your original firmware available to go back to.

Configuration

With LuCi web interface

[QMI]: Assuming luci-proto-qmi package is installed, navigate to Network → Interfaces, then Add new interface… → Protocol: QMI Cellular

[MBIM]: Assuming luci-proto-mbim package is installed, navigate to Network → Interfaces, then Add new interface… → Protocol: MBIM Cellular

[Common]:

Select Interface “cdc-wdm0” in the drop-down. If it is not available there, check if the corresponding driver (kmod-usb-net-*) is loaded, reset the modem if its mode has recently been changed.

Enter your APN and select the IP type as instructed by the carrier. Don't set IP type to IPV4V6 until you're 100% sure that provider supports IPv6, that is critical in QMI mode.

Note: For IPv6 mode it is recommended to enable the IPv6 options (see further down).

Assign the firewall zone (wan) on 'Firewall Settings' tab. You may need to enable masquerading (checked ON by default for the pre-defined 'wan' zone), depending on the provider, if you do not get a -PD (assigned set of IPv6 addresses for your network). Verizon, T-Mobile and other major networks now do Prefix Delegation. Otherwise, it's called 'IPv6 Masquerading', under the 'Advanced Settings' tab. If you are not going to use MSS Clamping, which enables certain firewall rules, do not check it here. There is a work-around for Quectel devices that crash when their MTU is set, which MSS Clamping is dependent on. It is below ('MTU Issues' under Troubleshooting & Optimization). Those alternate instructions turn on MSS Clamping without triggering the crash of the modem.

Editing text configuration files

Instead of using the web interface, this is how the files can be manually edited:

Add new interface to /etc/config/network using a text editor like vi or nano:

Replace “qmi” with “mbim” if necessary to match the modem configuration. Make sure the APN name is one provided by your carrier.

QMI Protocol Configuration Parameters

QMI (and MBIM) interfaces could be manually configured in UCI using uci command line or text editor.

Name Type Required Default Description
device file path yes (none) QMI device node, typically /dev/cdc-wdm0
apn string yes (none) Used APN
v6apn string no (none) APN for IPv6, if different from IPv4 APN
auth string no (none) Authentication type: pap, chap, both, none
username string no (none) Username for PAP/CHAP authentication
password string no (none) Password for PAP/CHAP authentication
pincode number no (none) PIN code to unlock SIM card
delay number no 0 Seconds to wait before trying to interact with the modem (some ZTE modems require up to 30 s.)
modes string no (modem default) Allowed network modes, comma separated list of: all, lte, umts, gsm, cdma, td-scdma
pdptype string no IP PDP Context Type, IP (for IPv4), IPV6 (for IPv6) or IPV4V6 (for dual-stack). Connection will fail if selected type is unsupported by the carrier.
profile number no 1 PDP Context Identifier
v6profile number no (none) PDP Context Identifier for IPv6 if different from IPv4 profile
dhcp boolean no 1 Whether to use DHCP (default) or uqmi (0) to get IPv4 interface configuration
dhcpv6 boolean no 0 Whether to use DHCP (1) or uqmi (default) to get IPv6 interface configuration
sourcefilter boolean no 1 Used to disable source-based IPv6 routing
delegate boolean no 1 Used to disable IPv6 Prefix Delegation
autoconnect boolean no 1
plmn number no (none) Limit network registration to specific operator. First 3 digits is the MCC (Mobile Country Code) and last 3 digits is the MNC (Mobile Network Code); for example, if lock is required for a network with MCC 338 and MNC 20, then plmn should be set to 338020
timeout number no 10 Timeout (in seconds) to wait for SIM operations
mtu number no (none) Interface MTU size

Here is a brief help about uqmi command line usage:

Click to display ⇲

Click to hide ⇱

Usage: uqmi <options|actions>
Options:
  --single, -s:                     Print output as a single line (for scripts)
  --device=NAME, -d NAME:           Set device name to NAME (required)
  --keep-client-id <name>:          Keep Client ID for service <name>
  --release-client-id <name>:       Release Client ID after exiting
  --mbim, -m                        NAME is an MBIM device with EXT_QMUX support
  --timeout, -t                     response timeout in msecs
 
Services:                           dms, nas, pds, wds, wms
 
Actions:
  --get-versions:                   Get service versions
  --set-client-id <name>,<id>:      Set Client ID for service <name> to <id>
                                    (implies --keep-client-id)
  --get-client-id <name>:           Connect and get Client ID for service <name>
                                    (implies --keep-client-id)
  --sync:                           Release all Client IDs
  --start-network:                  Start network connection (use with options below)
    --apn <apn>:                    Use APN
    --auth-type pap|chap|both|none: Use network authentication type
    --username <name>:              Use network username
    --password <password>:          Use network password
    --ip-family <family>:           Use ip-family for the connection (ipv4, ipv6, unspecified)
    --autoconnect:                  Enable automatic connect/reconnect
    --profile <index>:              Use connection profile
  --stop-network <pdh>:             Stop network connection (use with option below)
    --autoconnect:                  Disable automatic connect/reconnect
  --get-data-status:                Get current data access status
  --set-ip-family <val>:            Set ip-family (ipv4, ipv6, unspecified)
  --set-autoconnect <val>:          Set automatic connect/reconnect (disabled, enabled, paused)
  --get-profile-settings <val,#>:   Get APN profile settings (3gpp, 3gpp2),#
  --get-default-profile <val>:      Get default profile number (3gpp, 3gpp2)
  --create-profile <val>            Create profile (3gpp, 3gpp2)
    --apn <apn>:                    Use APN
    --pdp-type ipv4|ipv6|ipv4v6>:   Use pdp-type for the connection
    --username <name>:              Use network username
    --password <password>:          Use network password
    --auth-type pap|chap|both|none: Use network authentication type
    --no-roaming false|true         To allow roaming, set to false
  --modify-profile <val>,#          Modify profile number (3gpp, 3gpp2)
    --apn <apn>:                    Use APN
    --pdp-type ipv4|ipv6|ipv4v6>:   Use pdp-type for the connection
    --username <name>:              Use network username
    --password <password>:          Use network password
    --auth-type pap|chap|both|none: Use network authentication type
    --no-roaming false|true         To allow roaming, set to false
  --get-current-settings:           Get current connection settings
  --get-capabilities:               List device capabilities
  --get-pin-status:                 Get PIN verification status
  --verify-pin1 <pin>:              Verify PIN1
  --verify-pin2 <pin>:              Verify PIN2
  --set-pin1-protection <state>:    Set PIN1 protection state (disabled, enabled)
    --pin <pin>:                    PIN1 needed to change state
  --set-pin2-protection <state>:    Set PIN2 protection state (disabled, enabled)
    --pin <pin2>:                   PIN2 needed to change state
  --change-pin1:                    Change PIN1
    --pin <old pin>:                Current PIN1
    --new-pin <new pin>:            New pin
  --change-pin2:                    Change PIN2
    --pin <old pin>:                Current PIN2
    --new-pin <new pin>:            New pin
  --unblock-pin1:                   Unblock PIN1
    --puk <puk>:                    PUK needed to unblock
    --new-pin <new pin>:            New pin
  --unblock-pin2:                   Unblock PIN2
    --puk <puk>:                    PUK needed to unblock
    --new-pin <new pin>:            New pin
  --get-iccid:                      Get the ICCID
  --get-imsi:                       Get International Mobile Subscriber ID
  --get-imei:                       Get International Mobile Equipment ID
  --get-msisdn:                     Get the MSISDN (telephone number)
  --reset-dms:                      Reset the DMS service
  --get-device-operating-mode       Get the device operating mode
  --set-device-operating-mode <m>   Set the device operating mode
                                    (modes: online, low_power, factory_test, offline
                                     reset, shutting_down, persistent_low_power,
                                     mode_only_low_power)
  --fcc-auth:                       Set FCC authentication
  --uim-verify-pin1 <pin>:          Verify PIN1 (new devices)
  --uim-verify-pin2 <pin>:          Verify PIN2 (new devices)
  --uim-get-sim-state:              Get current SIM state
  --uim-power-off:                  Power off SIM card
    --uim-slot:                     SIM slot [1-2]
  --uim-power-on:                   Power on SIM card
    --uim-slot:                     SIM slot [1-2]
  --set-network-modes <modes>:      Set usable network modes (Syntax: <mode1>[,<mode2>,...])
                                    Available modes: all, lte, umts, gsm, cdma, td-scdma
  --set-network-preference <mode>:  Set preferred network mode to <mode>
                                    Available modes: auto, gsm, wcdma
  --set-network-roaming <mode>:     Set roaming preference:
                                    Available modes: any, off, only
  --network-scan:                   Initiate network scan
  --network-register:               Initiate network register
  --set-plmn:                       Register at specified network
    --mcc <mcc>:                    Mobile Country Code (0 - auto)
    --mnc <mnc>:                    Mobile Network Code
  --get-plmn:                       Get preferred network selection info
  --get-signal-info:                Get signal strength info
  --get-serving-system:             Get serving system info
  --get-system-info:                Get system info
  --get-lte-cphy-ca-info:           Get LTE Cphy CA Info
  --get-cell-location-info:         Get Cell Location Info
  --get-tx-rx-info <radio>:         Get TX/RX Info (gsm, umts, lte)
  --list-messages:                  List SMS messages
    --storage <mem>:                Messages storage (sim (default), me)
  --delete-message <id>:            Delete SMS message at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --get-message <id>:               Get SMS message at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --get-raw-message <id>:           Get SMS raw message contents at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --send-message <data>:            Send SMS message (use options below)
    --send-message-smsc <nr>:       SMSC number
    --send-message-target <nr>:     Destination number (required)
    --send-message-flash:           Send as Flash SMS
  --wda-set-data-format <type>:     Set data format (type: 802.3|raw-ip)
  --wda-get-data-format:            Get data format


MBIM Protocol support

MBIM configuration is very similar to QMI. Supported interface configuration options:

Name Type Required Default Description
device file path yes (none) MBIM device node, typically /dev/cdc-wdm0
apn string yes (none) Used APN
auth string no (none) Authentication type: pap, chap, both, none
username string no (none) Username for PAP/CHAP authentication
password string no (none) Password for PAP/CHAP authentication
pincode number no (none) PIN code to unlock SIM card
delay number no 0 Seconds to wait before trying to interact with the modem
pdptype string no IP PDP Context Type, IP (for IPv4), IPV6 (for IPv6) or IPV4V6 (for dual-stack)
ipv6 boolean no 1 Set it to 0 to disable IPv6 operation
dhcp boolean no 0 Whether to use DHCP (1) or “umbim” tool (default) to get IPv4 interface configuration
dhcpv6 boolean no 0 Whether to use DHCPv6 (1) or “umbim” tool (default) to get IPv6 interface configuration
sourcefilter boolean no 1 Used to disable source-based IPv6 routing
extendprefix boolean no 0 Accept a /64 IPv6 prefix via SLAAC and extend it on one downstream interface
delegate boolean no 1 Used to disable IPv6 Prefix Delegation
allow_roaming ** | boolean | no | 0 | Allow connection if the modem is registered to the network in roaming | | **allow_partner boolean no 0 Allow connection if the modem is registered to a partner network
mtu number no (none) Interface MTU size

Here is a brief help about umbim command line:

root@OpenWrt:~# umbim help
Usage: umbim <caps|pinstate|unlock|home|registration|subscriber|attach|detach|connect|disconnect|config|radio> [options]
Options:
    -d <device>         the device (/dev/cdc-wdmX)
    -t <transaction>    the transaction id
    -n                  no close
    -v                  verbose

uqmi tool can talk to MBIM modems using --mbim or -m option on the command line.

Manual validation

where “internet” is the APN of your provider

and

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --get-signal-info
{
        "type": "lte",
        "rssi": -71,
        "rsrq": -9,
        "rsrp": -94,
        "snr": 70
}

:!: Some providers will accept almost any APN, in this case using “internet” is fine.

--autoconnect key says that you want always be connected, once the modem is physically connected to the router and cellular network is in range. :!: It will be kept after reboot.

Checking your balance

To check your balance or send any other AT commands, you need to have USB serial device like: /dev/ttyUSB2

You should see in first terminal USSD response.

Modem Status page in LuCI

WAN status is available in Dashboard and System→Overview in LuCI web interface. ModemManager is a managed QMI/MBIM interface that has a page showing signal strength and other values. There are also external packages like https://github.com/4IceG/luci-app-modemdata or https://github.com/4IceG/luci-app-3ginfo-lite for displaying modem status and https://github.com/4IceG/luci-app-sms-tool-js for SMS support.

Troubleshooting & Optimization

Stability issues with the connection

Read-on, but also see the Optimization section, below.

Everything is okay but modem doesn't establish connection. What can I try?

* Moreover based on this article I discovered that need to reset my modem (tested on Dell Wireless 5804 413c:819b) in boot process, so you can try add the following commands in your /etc/rc.local:

/sbin/uqmi -d /dev/cdc-wdm0 --set-device-operating-mode offline
/sbin/uqmi -d /dev/cdc-wdm0 --set-device-operating-mode reset
/bin/sleep 20
/sbin/uqmi -d /dev/cdc-wdm0 --set-device-operating-mode online
/sbin/uqmi -d /dev/cdc-wdm0 --set-autoconnect enabled
/sbin/uqmi -d /dev/cdc-wdm0 --network-register

My router is not detecting the modem. What should I do?

Then wait for the modem to get issued an IP from your ISP.

No serial or network device is present (/dev/ttyUSB, /dev/cdc-wdm)

Scheduled modem-only reboot

As explained elsewhere, your modem might suffer regular or irregular disconnections. First, see the Optimization guide below.

Irregular disconnections might be caused by incorrect MSS/MTU settings, or the software and hardware of the modem, whose symptoms are generally loss of connectivity minutes after rebooting the router, very high latency and high packet loss on heavy load, modem software hanging and becoming irresponsive on certain events or during transmission of specific data. For these kind of situations, a firmware upgrade, watchdog script or watchcat package is recommended. See :docs:guide-user:network:wan:wwan:ltedongle#sample_cell_modem_wan_watchdog_script_basic_simple or watchcat

Regular disconnections (at specific times of the day, or after an exact number of hours) are generally when the mobile provider is force-issuing them. These should be normally handled transparently by the modem, but this may not the case that the modem handles it correctly. For this, you might want to perform a regular reboot of the only the modem, to keep it working. However, [as a contributor who has read ALL of Quectel's 300+ pages of modem documentation, and has had several of them, talked with others who have managed over 1000 quectel devices, and has been using them for years successfully with Openwrt] for another perspective, it may simply be an issue with your configuration. Chronically-bad stability issues, of the type mentioned, went away with use of pure QMI, and no MTU value assignment or APN assignment, besides selecting the correct SIM profile. [End comment]

If you find there is a specific period needed for restarting only the modem device, and you want to do it based on time instead of status of the connection, here is a sample script:

The modem will reboot, OpenWrt will detect the USB and CDC interfaces disappearing and reappearing again, and restart the WAN interface, effectively requesting a new connection to the network and acquiring a new IP.

While those above commands will do the described action, it's generally better to fix the stability issues, and probe the connection periodically with the advanced connectivity script, allowing it to log and take action as necessary.

PIN_STATUS_FAILED

The modem responds not_initialized during the QMI start-up process, producing a PIN_STATUS_FAILED error on the QMI Interface. But there is no PIN required (and pin1 value is blank). A workaround is editing the '/lib/netifd/proto/qmi.sh' script, at line 158, adding/editing the response 'not_initialized' instead of 'disabled'.

MTU Issues / Stability / Performance

Cellular networks use an additional 80 bytes of encapsulation, beyond what ordinary ethernet networks have. Starting with how your actual data payload is called the MSS, the total packet size is called the MTU. For instance, on ethernet, we have an MSS of 1460, and have to add 40 more bytes of overhead to get the MTU (1500). On cellular networks, we have even more overhead than ethernet, so we have to make the MSS smaller, to make additional room for the 80 additional bytes of overhead, that are part of added encapsulation protocols, that handle getting your data to it's destination, which results in an effective MTU of 1420. While Verizon uses 1428, and you could adjust your values by +8 accordingly, it's generally 1420 that is used for cellular networks. You may find that a slightly lower value, like 1400, works better even with an excellent quality connection. However, the standard practice is to start with 1420 and see how it goes.

The examples below will all use 1420.

If you do not adjust your MTU at all, you may find unusual issues, like images not loading on certain sites, strange performance issues, and generally other odd behavior.

MTU Issues / Stability: Concerning IPv4

On the IPv4 protocol, the router is responsible for altering packets that are too big. Whereas on IPv6, it's exclusively the client's responsbility. So, on a typical legacy IPv4 network stack, there is the assumption that if you simply set MSS Clamping on (in your WAN zone Firewall settings), and the Device Interface (WAN interface/device in Network→Interfaces) MTU is properly set, then everything will work.

There are two problems with that presumption:

1) There are known issues with the most common cellular modem chipsets firmware, found in routers, specifically the Quectel-brand modems. They run Quectel's implementation of Qualcomm's core firmware, and seem to exhibit a common problem, that if you set the MTU in Openwrt, or use a protocol that detects and sets the MTU (like MBIM), the modem chip locks-up within 2 minutes. Start with using the plain (and often the default support in firmware like ROOTER) QMI-support libraries (luci-proto-qmi), and only set the minimal APN information, and select the PDP Context ID (called the APN Profile Index in Openwrt Luci). If you specifically set the MTU, it can cause stability or crashes of the modem. This MTU crash issue happens with the MBIM protocol or ModemManager too, as ModemManager uses MBIM, sets the MTU, and causes the same hard-lock of the chip, within minutes. see here for more info

2) MSS Clamping does not fix IPv6 clamping issues, other than TCP packets.

Since you still need to limit the MSS to fit inside the 1420 MTU for optimal performance, read-on:

This command sets the MSS maximum segment size to 1360. When adding the IPV6 (40) and TCP (20) overhead, that brings the MTU to 1420. It's almost identical to the MSS Clamping commands added to the firewall, but specifies a value (1360) instead of telling the firewall to read the wwan device's MTU and calculate an MSS. tracepath <destination>, without this firewall instruction, can help you determine an MTU suitable for you, although a value here of MSS 1360 is almost certainly the one to work on your cell network wan link. Note: You are setting the MSS, not the MTU. So 1360 + 40 + 20 = 1420.

The standard MSS Clamping option in the wan zone of the Luci Web Firewall interface, is meant to add a similar instruction, but calculate MSS from the Device Interface MTU, and does not have a field for setting a specific target MSS or MTU value. Therefore, when making the above firewall changes, uncheck MSS Clamping, equivalent to remarking-out or removing the mtu_fix '1' option for the WAN Zone in your /etc/config/firewall config. Be sure when you are finished to service firewall restart or restart it in the LuCI web interface.

MTU Issues / Stability: Concerning IPv6

IPv6 is not affected entirely by the above MTU command. IPv6 also requires the client, not the router, to react to 'packet too big' messages, so the client can send smaller packets. Further, in some cellular networks, they fail in handling proper PMTUD, so they fail to pass the 'packet too big' messages back to your clients. So your client does not know to reduce its IPv6 packet sizes. Fixing this is not automatic (yet) on Openwrt, even as of build r32579/v25.12: we need to add additional instructions for IPv6. Since we always know the maximum standard for cellular is an MTU of 1420, we need to make sure Openwrt's Router Advertisements -a part of IPv6- lets clients know the maximum MTU is 1420.

In particular, the main aspect is the option ra_mtu '1420' in the config dhcp 'lan' section of /etc/config/dhcp.

That is directly from a router with an internal cellular modem, using a verizon sim. This has been tested on Sierra, Quectel, Verizon and TMOBILE. Both Verizon and T-Mobile do issue /64 -PD Prefix Delegation, so your LAN clients can get a valid IPv6 address. However, they also block all unsolicited IPv6 and IPv4 packets at the CGNAT (corporate gateway) level. While your IPv4 assigned address is not public, your ipv6 address is. But you will find PMTUD is broken (packet too big messages don't pass through), and it's not possible to get inbound ipv6 connections (torrents, webhosting, remote control, ssh etc).

If you re-use the above example, the first 'list ntp' servers are your router's NTP Server. It should be turned on in your System settings. And the 1.1 should be changed to your router and 1.2 to a back-up Openwrt device on your network (or another NTP server). The 'time.nist.gov' should be modified to a regional NTP server of your choice, and an additional ipv6 address of an NTP server should be added. This configuration properly supports Android (SLAAC), Windows (DHCPv6) and IoT devices (many definitely need the ra_mtu). Use https://test-ipv6.run to check ipv4/6. There are issues with test-ipv6.com scripts, as of this writing, causing android devices to mis-report that IPv6 addresses are not being assigned. Another way to test ipv6 is with a curl -6 ifconfig.co command, from Termux or a shell. If it works, it will simply respond with your device's IPv6 address.

Other OpenWrt devices on your network and IPv6 support

If you do not modify the default settings to the configuration below, on your other OpenWrt devices on your network, you will experience the symptom that network clients will not get IPv6 addresses. It's because the Router Advertisement packets are not being passed.

More IPv6 Specific Issues

Continuing from the above ra_mtu issue, and related to it:

Firewall and IPv6

Because IPv6 also requires essential services to pass through your firewall, and Openwrt does not (yet) fully enable them by default, here are the additional firewall config rule rules concerning the wan zone: These are taken directly from a fully-functional router with a built-in cellular modem. All services, sites, apps, and devices work and load smoothly. All IPv4 and IPv6 issues have been overcome. This is the 'finished product', in production:

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	option limit '100/sec'
	option family 'ipv6'
	option target 'ACCEPT'
	list icmp_type 'bad-header'
	list icmp_type 'destination-unreachable'
	list icmp_type 'echo-reply'
	list icmp_type 'echo-request'
	list icmp_type 'neighbour-advertisement'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'packet-too-big'
	list icmp_type 'router-advertisement'
	list icmp_type 'router-solicitation'
	list icmp_type 'time-exceeded'
	list icmp_type 'unknown-header-type'
	option limit_burst '10'

config rule
	option name 'Allow-ICMPv6-Forward-Ping'
	option src 'wan'
	option dest 'lan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	option limit '10/second'
	option family 'ipv6'
	option target 'ACCEPT'
	option limit_burst '10'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'lan'
	option dest 'wan'
	option proto 'icmp'
	option limit '10/second'
	option family 'ipv6'
	option target 'ACCEPT'
	list icmp_type 'bad-header'
	list icmp_type 'destination-unreachable'
	list icmp_type 'echo-reply'
	list icmp_type 'echo-request'
	list icmp_type 'neighbour-advertisement'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'packet-too-big'
	list icmp_type 'router-advertisement'
	list icmp_type 'router-solicitation'
	list icmp_type 'time-exceeded'
	list icmp_type 'unknown-header-type'
	option limit_burst '10'

QMI IPv6 Gateway information (Out of Band issues)

Along with the above ra_mtu and firewall issues on IPv6, as of this writing, again using a recent build - r32579 / v25.12 - , Openwrt still fails to properly support the ipv6 portion of cellular data links over QMI. Specifically, in the aspect of forming a default ipv6 route / dealing with the upstream provider IPv6 gateway information, which can be read with ifstatus qmi. To solve this, an additional script, /etc/hotplug.d/iface/90-qmi-ipv6-route, will pull the gateway information from the ifstatus qmi query, after connecting, and integrate the information into your routing table, so clients and the router can properly reach ipv6 sites.

1) Create the script / file in the folder as shown. 2) Make sure to do a chmod +x 90-qmi-ipv6-route to make it executable.

Tethering-specific (TTL/HopLimit) Issues

Note: 64 is the value given here, although your particular cellular service provider may require a different value. Other users have reported successful values online, and you can do an internet search to find them.

Hosting sites or access from the internet to IPv6 clients on the LAN

Along with the above firewall modifications, you may find that your LAN clients are still unreachable, even though your cellular provider issues -PD addresses in a range that is public, and your LAN client is clearly getting a public IPv6 address (curl -6 ifconfig.co). Various carriers (Verizon being one) use upstream firewall rules that block inbound access to their typical cellular network clients. There is no workaround for this, besides running 6in4 or some kind of remote VPS or other method of directing inbound traffic through a tunnel, to bypass carrier security restrictions.

General Note about stability issues in Quectel devices

Sample cell modem WAN watchdog script (basic, simple)

For a much more advanced version of this wan-watchdog.sh script, that handles bandwidth shaping, fail-over, VPN's and more: See Wireguard Extra's more advanced connectivity monitoring script.

For a basic version: Here is a wan_watchdog.sh script that tests the connection, and if it receives no response from several well-known DNS providers, it can:

  1. Tell the modem to soft-off.
  2. Tell the modem to soft-on (boot up).
  3. Restart the interface, and
  4. Reboot the router (if everything prior was unsuccessful).

If you need to edit this script, while your router is running, first stop it by doing a ps | grep wan, and you'll see the process ID. Then do a kill (id), then nano wan-watchdog.sh. When finished, do a /root/wan-watchdog.sh & and the script will execute in the background (you can close the shell/ssh session).

Setting the time & date (NTPd)

The sleep delay timer, and then the NTP service restart, in the /etc/rc.local script above, corrects a common issue issue on Openwrt routers with internal cellular modem chips, where since most router-boards do not have a battery-backup for their clock, to maintain correct time & date between reboots, they have to pull the time from the internet (upstream), every time they power-up. Ordinarily, the WAN on a cell-modem router takes 30-45 seconds to connect, and time-retrieval services (NTPd) start before an upstream provider (internet) connection is established. Openwrt devices with built-in modems, can thus have the wrong time, initially. If you do not need the delay and ntpd restart, it does not negatively affect your router. The Openwrt device will eventually get the correct time, however, without this command, the initial boot time, e.g. for logging messages (the wan-watchdog.sh script) would be incorrect, leading to startup times and dates in the log that are not correct, hindering trouble-shooting.

Setting SAR Values

By default, modem chipsets like quectel, sierra and others, use Specific Absorption Rate, a measure of the amount of radio-frequency energy that your body absorbs when using a cellular device. However, who holds their router up to their head when using it?. The SAR back-off values that are set by default into cellular modem chipsets, are based on the assumption they are being used in a cellular phone that is up against your head, even though these chipsets are installed in a router.

Alternative to adjusting SAR: Global Power Limit

AT!MAXPWR=0

If configuring every band/state is too cumbersome for your test setup, this short-cut may work. You can try setting the global maximum power limit, though this is less granular than SAR backoff control:

Note: This command may be ignored if the carrier NVU (Verizon) enforces the stricter SAR tables.

Note: This has resulted, in real-world testing, in significantly better connectivity, bandwidth and lower latency to the tower. Your individual performance results, may vary.