Qmi_wwan returns error when ModemManager tries to enable raw_ip

I'm using an LTE USB dongle w/ a Quectel EG25-G modem on OpenWRT version 22.03.0.
When my cell modem is inserted, qmi_wwan returns the following error when ModemManager tries to enable raw IP by writing 'Y' to /sys/class/net/wwan0/qmi/raw_ip:

[ 1245.570332] qmi_wwan 1-1:1.4 wwan0: Type change was refused

To get past this error, I commented out the following code in drivers/net/usb/qmi_wwan.c and now the modem comes up & can access the internet:

  /* let other drivers deny the change */
// atk - following causes error on write of 'Y' to /sys/class/net/wwan0/qmi/raw_ip
//	ret = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
//	ret = notifier_to_errno(ret);
//	if (ret) {
//		netdev_err(dev->net, "Type change was refused\n");
//		goto err;
//	}

Are there any fixes for this problem?
How can I track down the entity that returned error for call_netdevice_notifiers()?

It is possible (and recommended) to run a QMI modem without modemmanager. ModemManager may be conflicting with the direct QMI scripts.

What are "direct QMI scripts" & how do I know if they're running on my system & if they're interfering w/ ModemManager?

Remove ModemManager and all your customizations.
Install kmod-usb-net-qmi-wwan uqmi luci-proto-qmi picocom kmod-usb-serial-option

Go to Network → Interfaces → Add new interface… → Protocol : QMI, Interface: cdc-wdm0
enter APN, IP type (v4/v6)
in Advanced Settings: tick "Use default gateway" and "Use DNS servers advertised by peer"
Assign the right firewall zone - WAN

This is not an error. That code was put there to make the netdev morphing safe wrt anything depending on it.

Are you trying to bridge a qmi_wwan interface? That won't work

@AndrewZ - I removed ModemManager & qmi_wwan.c customizations & installed the noted packages & drivers. Then I configured as you stated, but still I get the "qmi_wwan 1-1:1.4 wwan0: Type change was refused" message. I also tried setting raw_ip mode BEFORE adding the configuration & got the "refused" message.

@bmork - I am not doing bridging of the qmi_wwan interface. Is there a way to find out what code is returning non-zero from call_netdevice_notifier()?

Can't see any obvious way to debug this unfortunately. There are few candidats though. These are all the places in the kernel where NETDEV_PRE_TYPE_CHANGE is in use, and you can obviously ignore most of them:

bjorn@miraculix:/usr/local/src/git/linux$ git grep NETDEV_PRE_TYPE_CHANGE
Documentation/fault-injection/notifier-error-inject.rst: * NETDEV_PRE_TYPE_CHANGE
drivers/net/bonding/bond_main.c:                        res = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE,
drivers/net/ipvlan/ipvlan_main.c:       case NETDEV_PRE_TYPE_CHANGE:
drivers/net/macvlan.c:  case NETDEV_PRE_TYPE_CHANGE:
drivers/net/team/team.c:        err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
drivers/net/team/team.c:        case NETDEV_PRE_TYPE_CHANGE:
drivers/net/tun.c:                      ret = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE,
drivers/net/usb/qmi_wwan.c:     ret = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
drivers/net/wan/hdlc.c:         err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
include/linux/netdevice.h:      NETDEV_PRE_TYPE_CHANGE,
lib/netdev-notifier-error-inject.c:             { NOTIFIER_ERR_INJECT_ACTION(NETDEV_PRE_TYPE_CHANGE) },
net/8021q/vlan.c:       case NETDEV_PRE_TYPE_CHANGE:
net/batman-adv/hard-interface.c:        case NETDEV_PRE_TYPE_CHANGE:
net/bridge/br.c:        case NETDEV_PRE_TYPE_CHANGE:
net/hsr/hsr_main.c:     case NETDEV_PRE_TYPE_CHANGE:
net/ipv4/devinet.c:     case NETDEV_PRE_TYPE_CHANGE:
net/ipv6/addrconf.c:    case NETDEV_PRE_TYPE_CHANGE:
net/ipv6/addrconf.c:    else if (event == NETDEV_PRE_TYPE_CHANGE)
net/x25/af_x25.c:               case NETDEV_PRE_TYPE_CHANGE:

The remaining interesting ones are the ipvlan, macvlan, team, vlan, bridge, devinet and addrconf sites.

and looking over those quickly, the only ones ever rejecting a change are those that have obvious reasons to require L2 headers (except maybe ipvlan? unsure why that one needs L2):

  • ipvlan
  • macvlan
  • team
  • vlan
  • bridge
  • hsr

Anyway, you can't run any of that on a raw IP interface. If you don't know of any such device being configured, then maybe you have installed something that sets it up automatically?

I'm adding debug prints in those places to figure this out.

I figured out the culprit. It's a an opensource driver included in the SoC vendor SDK called vfrwd. The driver always returns NOTIFY_BAD for event NETDEV_PRE_TYPE_CHANGE. I've opened a ticket w/ the vendor on this.
Thanks for your help on this!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.