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()?
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
@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 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!