aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Bar-Lev <alon.barlev@gmail.com>2023-05-15 00:38:28 +0300
committerRobin H. Johnson <robbat2@gentoo.org>2023-11-24 20:54:01 -0800
commita0b69349707b4aaaefc01fd37f1b386935d75c90 (patch)
treeb8afde228485eedab7746bd814ebc158d9c4eac4
parentiwd: depend on "program /usr/libexec/iwd" instead of "program iwd" (diff)
downloadnetifrc-a0b69349707b4aaaefc01fd37f1b386935d75c90.tar.gz
netifrc-a0b69349707b4aaaefc01fd37f1b386935d75c90.tar.bz2
netifrc-a0b69349707b4aaaefc01fd37f1b386935d75c90.zip
net: add qmi interface support
qmi is useful for cellular modem connection, the management interface is implemented using libqmi's qmicli utility. Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com> Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> Closes: https://github.com/gentoo/netifrc/pull/44
-rw-r--r--doc/net.example.Linux.in13
-rw-r--r--net/Makefile2
-rw-r--r--net/qmi.sh133
3 files changed, 147 insertions, 1 deletions
diff --git a/doc/net.example.Linux.in b/doc/net.example.Linux.in
index 42b8071..cbd81e7 100644
--- a/doc/net.example.Linux.in
+++ b/doc/net.example.Linux.in
@@ -1133,6 +1133,19 @@
#config_l2tpeth2="10.100.2.1/24"
#-----------------------------------------------------------------------------
+# QMI
+# For QMI support, emerge net-libs/libqmi
+# QMI is used for some cellular modems.
+#
+# Each QMI interface may have the following configuration:
+#qmi_apn_wwan0= # The name of the APN
+#qmi_auth_wwan0= # none, pop, chap, both, Default: none
+#qmi_username_wwan0= # Default: dummy
+#qmi_password_wwan0= # Default dummy
+#qmi_cdc_wwan0= # Default: /dev/cdc-wmiX where X is taken from IFACE
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
# Advanced Routing
# WARNING: For advanced routing you MUST be using sys-apps/iproute2
#
diff --git a/net/Makefile b/net/Makefile
index 58483cd..f562d15 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -14,7 +14,7 @@ INC-Linux= adsl.sh apipa.sh arping.sh bonding.sh br2684ctl.sh bridge.sh \
ccwgroup.sh clip.sh ethtool.sh iproute2.sh ifplugd.sh ip6to4.sh \
ipppd.sh iwconfig.sh netplugd.sh pppd.sh pump.sh tuntap.sh udhcpc.sh \
vlan.sh macvlan.sh ip6rd.sh firewalld.sh dummy.sh hsr.sh l2tp.sh \
- iw.sh iwd.sh wireguard.sh veth.sh dhclientv6.sh
+ iw.sh iwd.sh wireguard.sh veth.sh dhclientv6.sh qmi.sh
SRCS-NetBSD= ifwatchd.sh.in
INC-NetBSD= ifwatchd.sh
diff --git a/net/qmi.sh b/net/qmi.sh
new file mode 100644
index 0000000..ac1b2dd
--- /dev/null
+++ b/net/qmi.sh
@@ -0,0 +1,133 @@
+# Copyright (c) 2011 by Gentoo Foundation
+# Released under the 2-clause BSD license.
+# shellcheck shell=sh disable=SC1008
+
+_is_qmi() {
+ [ -d "/sys/class/net/${IFACE}/qmi" ]
+}
+
+_get_state() {
+ echo "/run/net.${IFACE}.qmi.state"
+}
+
+_get_device() {
+ echo "/dev/cdc-$(echo "${IFACE}" | sed 's/wwan/wdm/')"
+}
+
+qmi_depend()
+{
+ program qmicli
+ program ip
+ before interface
+}
+
+qmi_pre_start() {
+
+ _is_qmi || return 0
+
+ local device
+ local apn
+ local auth
+ local username
+ local password
+ local out
+ local rc
+
+ eval device=\$qmi_cdc_${IFVAR}
+ eval apn=\$qmi_apn_${IFVAR}
+ eval auth=\$qmi_auth_${IFVAR}
+ eval username=\$qmi_username_${IFVAR}
+ eval password=\$qmi_password_${IFVAR}
+
+ [ -n "${apn}" ] || return 0
+
+ [ -n "${device}" ] || device="$(_get_device)"
+ [ -n "${auth}" ] || auth="none"
+ [ -n "${username}" ] || username="dummy"
+ [ -n "${password}" ] || password="dummy"
+
+ if ! [ -c "${device}" ]; then
+ ewarn "Cannot open device ${device} for ${IFACE}, aborting configuration"
+ return 1
+ fi
+
+ if ! cat "/sys/class/net/${IFACE}/qmi/raw_ip" | grep -q Y; then
+ ebegin "Configuring QMI raw IP"
+
+ ip link set "${IFACE}" down
+ if ! echo Y > "/sys/class/net/${IFACE}/qmi/raw_ip"; then
+ eend 1 "Cannot set raw IP mode for ${IFACE}, aborting configuration"
+ return 1
+ else
+ eend 0
+ fi
+ fi
+
+ local wwan_connection="apn='${apn}',auth='${auth}',username='${username}',password='${password}',autoconnect=yes,ip-type=4"
+ local n
+ for n in 1 2 3; do
+ ebegin "Connecting QMI APN '${apn}' using '${username}'"
+
+ if out="$( \
+ qmicli \
+ --device="${device}" \
+ --wds-start-network="${wwan_connection}" \
+ --device-open-proxy \
+ --client-no-release-cid \
+ )"; then
+ eend 0
+ break
+ elif echo "${out}" | grep -qi "timed out"; then
+ eend 1 "QMI start network timeout"
+ else
+ eend 1 "QMI start network failed for ${IFACE}, aborting"
+ return 1
+ fi
+ done
+
+ local handle="$(echo "${out}" | grep "Packet data handle:" | sed "s/.*'\(.*\)'.*/\1/")"
+ local cid="$(echo "${out}" | grep "CID:" | sed "s/.*'\(.*\)'.*/\1/")"
+
+ if [ -z "${handle}" ]; then
+ ewarn 1 "No QMI connection handle ${IFACE}, aborting configuration"
+ return 1
+ fi
+
+ if [ -z "${cid}" ]; then
+ ewarn "No QMI connection id ${IFACE}, aborting configuration"
+ return 1
+ fi
+
+ cat > "$(_get_state)" << __EOF__
+device="${device}"
+handle="${handle}"
+cid="${cid}"
+__EOF__
+}
+
+qmi_post_stop() {
+
+ _is_qmi || return 0
+
+ local state="$(_get_state)"
+
+ [ -f "${state}" ] || return 0
+
+ ebegin "Disconnecting QMI ${IFACE}"
+
+ local device
+ local handle
+ local cid
+
+ . "${state}"
+
+ qmicli \
+ --device="${device}" \
+ --client-cid="${cid}" \
+ --wds-stop-network="${handle}"
+ rc="$?"
+
+ rm -f "${state}"
+
+ eend "${rc}"
+}