From a0b69349707b4aaaefc01fd37f1b386935d75c90 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Mon, 15 May 2023 00:38:28 +0300 Subject: 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 Signed-off-by: Robin H. Johnson Closes: https://github.com/gentoo/netifrc/pull/44 --- doc/net.example.Linux.in | 13 +++++ net/Makefile | 2 +- net/qmi.sh | 133 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 net/qmi.sh 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 @@ -1132,6 +1132,19 @@ #l2tpsession_l2tpeth2="tunnel_id 2 session_id 1 peer_session_id 1" #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}" +} -- cgit v1.2.3-65-gdbad