modemmanager: add IPv6/IPv4v6 support
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
This commit is contained in:
parent
827969027a
commit
859becef19
2 changed files with 158 additions and 63 deletions
|
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=modemmanager
|
PKG_NAME:=modemmanager
|
||||||
PKG_VERSION:=1.12.0
|
PKG_VERSION:=1.12.0
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
PKG_SOURCE:=ModemManager-$(PKG_VERSION).tar.xz
|
PKG_SOURCE:=ModemManager-$(PKG_VERSION).tar.xz
|
||||||
PKG_SOURCE_URL:=https://www.freedesktop.org/software/ModemManager
|
PKG_SOURCE_URL:=https://www.freedesktop.org/software/ModemManager
|
||||||
|
|
|
@ -17,8 +17,8 @@ cdr2mask ()
|
||||||
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
|
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
|
||||||
if [ "$1" -gt 1 ]
|
if [ "$1" -gt 1 ]
|
||||||
then
|
then
|
||||||
shift "$1"
|
shift "$1"
|
||||||
else
|
else
|
||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
echo "${1-0}"."${2-0}"."${3-0}"."${4-0}"
|
echo "${1-0}"."${2-0}"."${3-0}"."${4-0}"
|
||||||
|
@ -111,7 +111,7 @@ modemmanager_cleanup_connection() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modemmanager_connected_method_ppp() {
|
modemmanager_connected_method_ppp_ipv4() {
|
||||||
local interface="$1"
|
local interface="$1"
|
||||||
local ttyname="$2"
|
local ttyname="$2"
|
||||||
local username="$3"
|
local username="$3"
|
||||||
|
@ -139,7 +139,7 @@ modemmanager_connected_method_ppp() {
|
||||||
ip-down-script /lib/netifd/ppp-down
|
ip-down-script /lib/netifd/ppp-down
|
||||||
}
|
}
|
||||||
|
|
||||||
modemmanager_disconnected_method_ppp() {
|
modemmanager_disconnected_method_ppp_ipv4() {
|
||||||
local interface="$1"
|
local interface="$1"
|
||||||
|
|
||||||
echo "running disconnection (ppp method)"
|
echo "running disconnection (ppp method)"
|
||||||
|
@ -163,12 +163,13 @@ modemmanager_disconnected_method_ppp() {
|
||||||
proto_kill_command "$interface"
|
proto_kill_command "$interface"
|
||||||
}
|
}
|
||||||
|
|
||||||
modemmanager_connected_method_dhcp() {
|
modemmanager_connected_method_dhcp_ipv4() {
|
||||||
local interface="$1"
|
local interface="$1"
|
||||||
local wwan="$2"
|
local wwan="$2"
|
||||||
local metric="$3"
|
local metric="$3"
|
||||||
|
|
||||||
proto_init_update "${wwan}" 1
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
proto_send_update "${interface}"
|
proto_send_update "${interface}"
|
||||||
|
|
||||||
json_init
|
json_init
|
||||||
|
@ -181,16 +182,7 @@ modemmanager_connected_method_dhcp() {
|
||||||
ubus call network add_dynamic "$(json_dump)"
|
ubus call network add_dynamic "$(json_dump)"
|
||||||
}
|
}
|
||||||
|
|
||||||
modemmanager_disconnected_method_dhcp() {
|
modemmanager_connected_method_static_ipv4() {
|
||||||
local interface="$1"
|
|
||||||
|
|
||||||
echo "running disconnection (dhcp method)"
|
|
||||||
|
|
||||||
proto_init_update "*" 0
|
|
||||||
proto_send_update "${interface}"
|
|
||||||
}
|
|
||||||
|
|
||||||
modemmanager_connected_method_static() {
|
|
||||||
local interface="$1"
|
local interface="$1"
|
||||||
local wwan="$2"
|
local wwan="$2"
|
||||||
local address="$3"
|
local address="$3"
|
||||||
|
@ -218,6 +210,7 @@ modemmanager_connected_method_static() {
|
||||||
# TODO: mtu reporting in proto handler
|
# TODO: mtu reporting in proto handler
|
||||||
|
|
||||||
proto_init_update "${wwan}" 1
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
echo "adding IPv4 address ${address}, netmask ${mask}"
|
echo "adding IPv4 address ${address}, netmask ${mask}"
|
||||||
proto_add_ipv4_address "${address}" "${mask}"
|
proto_add_ipv4_address "${address}" "${mask}"
|
||||||
[ -n "${gateway}" ] && {
|
[ -n "${gateway}" ] && {
|
||||||
|
@ -236,10 +229,75 @@ modemmanager_connected_method_static() {
|
||||||
proto_send_update "${interface}"
|
proto_send_update "${interface}"
|
||||||
}
|
}
|
||||||
|
|
||||||
modemmanager_disconnected_method_static() {
|
modemmanager_connected_method_dhcp_ipv6() {
|
||||||
|
local interface="$1"
|
||||||
|
local wwan="$2"
|
||||||
|
local metric="$3"
|
||||||
|
|
||||||
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
|
proto_send_update "${interface}"
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_string name "${interface}_6"
|
||||||
|
json_add_string ifname "@${interface}"
|
||||||
|
json_add_string proto "dhcpv6"
|
||||||
|
proto_add_dynamic_defaults
|
||||||
|
json_add_string extendprefix 1 # RFC 7278: Extend an IPv6 /64 Prefix to LAN
|
||||||
|
[ -n "$metric" ] && json_add_int metric "${metric}"
|
||||||
|
json_close_object
|
||||||
|
ubus call network add_dynamic "$(json_dump)"
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_connected_method_static_ipv6() {
|
||||||
|
local interface="$1"
|
||||||
|
local wwan="$2"
|
||||||
|
local address="$3"
|
||||||
|
local prefix="$4"
|
||||||
|
local gateway="$5"
|
||||||
|
local mtu="$6"
|
||||||
|
local dns1="$7"
|
||||||
|
local dns2="$8"
|
||||||
|
local metric="$9"
|
||||||
|
|
||||||
|
[ -n "${address}" ] || {
|
||||||
|
proto_notify_error "${interface}" ADDRESS_MISSING
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "${prefix}" ] || {
|
||||||
|
proto_notify_error "${interface}" PREFIX_MISSING
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: mtu reporting in proto handler
|
||||||
|
|
||||||
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
|
echo "adding IPv6 address ${address}, prefix ${prefix}"
|
||||||
|
proto_add_ipv6_address "${address}" "128"
|
||||||
|
proto_add_ipv6_prefix "${address}/${prefix}"
|
||||||
|
[ -n "${gateway}" ] && {
|
||||||
|
echo "adding default IPv6 route via ${gateway}"
|
||||||
|
proto_add_ipv6_route "${gateway}" "128"
|
||||||
|
proto_add_ipv6_route "::0" "0" "${gateway}" "" "" "${address}/${prefix}"
|
||||||
|
}
|
||||||
|
[ -n "${dns1}" ] && {
|
||||||
|
echo "adding primary DNS at ${dns1}"
|
||||||
|
proto_add_dns_server "${dns1}"
|
||||||
|
}
|
||||||
|
[ -n "${dns2}" ] && {
|
||||||
|
echo "adding secondary DNS at ${dns2}"
|
||||||
|
proto_add_dns_server "${dns2}"
|
||||||
|
}
|
||||||
|
[ -n "$metric" ] && json_add_int metric "${metric}"
|
||||||
|
proto_send_update "${interface}"
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_disconnected_method_common() {
|
||||||
local interface="$1"
|
local interface="$1"
|
||||||
|
|
||||||
echo "running disconnection (static method)"
|
echo "running disconnection (common)"
|
||||||
|
|
||||||
proto_init_update "*" 0
|
proto_init_update "*" 0
|
||||||
proto_send_update "${interface}"
|
proto_send_update "${interface}"
|
||||||
|
@ -259,10 +317,11 @@ proto_modemmanager_setup() {
|
||||||
local interface="$1"
|
local interface="$1"
|
||||||
|
|
||||||
local modempath modemstatus bearercount bearerpath connectargs bearerstatus beareriface
|
local modempath modemstatus bearercount bearerpath connectargs bearerstatus beareriface
|
||||||
|
local bearermethod_ipv4 bearermethod_ipv6
|
||||||
local operatorname operatorid registration accesstech signalquality
|
local operatorname operatorid registration accesstech signalquality
|
||||||
|
|
||||||
local device apn username password pincode iptype metric
|
local device apn username password pincode iptype metric
|
||||||
|
|
||||||
local address prefix gateway mtu dns1 dns2
|
local address prefix gateway mtu dns1 dns2
|
||||||
|
|
||||||
json_get_vars device apn username password pincode iptype metric
|
json_get_vars device apn username password pincode iptype metric
|
||||||
|
@ -294,9 +353,12 @@ proto_modemmanager_setup() {
|
||||||
# always cleanup before attempting a new connection, just in case
|
# always cleanup before attempting a new connection, just in case
|
||||||
modemmanager_cleanup_connection "${modemstatus}"
|
modemmanager_cleanup_connection "${modemstatus}"
|
||||||
|
|
||||||
|
# ip type IPv4 is assumed if none explicitly given
|
||||||
|
[ -z "${iptype}" ] && iptype="ipv4"
|
||||||
|
|
||||||
# setup connect args; APN mandatory (even if it may be empty)
|
# setup connect args; APN mandatory (even if it may be empty)
|
||||||
echo "starting connection with apn '${apn}'..."
|
echo "starting connection with apn '${apn}'..."
|
||||||
connectargs="apn=${apn}${username:+,user=${username}}${password:+,password=${password}}${pincode:+,pin=${pincode}}${iptype:+,ip-type=${iptype}}"
|
connectargs="apn=${apn},ip-type=${iptype}${username:+,user=${username}}${password:+,password=${password}}${pincode:+,pin=${pincode}}"
|
||||||
mmcli --modem="${device}" --timeout 120 --simple-connect="${connectargs}" || {
|
mmcli --modem="${device}" --timeout 120 --simple-connect="${connectargs}" || {
|
||||||
proto_notify_error "${interface}" CONNECT_FAILED
|
proto_notify_error "${interface}" CONNECT_FAILED
|
||||||
proto_block_restart "${interface}"
|
proto_block_restart "${interface}"
|
||||||
|
@ -330,30 +392,66 @@ proto_modemmanager_setup() {
|
||||||
|
|
||||||
# load network interface and method information
|
# load network interface and method information
|
||||||
beareriface=$(modemmanager_get_field "${bearerstatus}" "bearer.status.interface")
|
beareriface=$(modemmanager_get_field "${bearerstatus}" "bearer.status.interface")
|
||||||
bearermethod=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
|
[ "$iptype" = "ipv4" ] || [ "$iptype" = "ipv4v6" ] && {
|
||||||
echo "connection setup required in interface ${beareriface}: ${bearermethod}"
|
bearermethod_ipv4=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
|
||||||
|
echo "IPv4 connection setup required in interface ${interface}: ${bearermethod_ipv4}"
|
||||||
|
}
|
||||||
|
[ "$iptype" = "ipv6" ] || [ "$iptype" = "ipv4v6" ] && {
|
||||||
|
bearermethod_ipv6=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.method")
|
||||||
|
echo "IPv6 connection setup required in interface ${interface}: ${bearermethod_ipv6}"
|
||||||
|
}
|
||||||
|
|
||||||
case "${bearermethod}" in
|
# setup IPv4
|
||||||
"dhcp")
|
[ -n "${bearermethod_ipv4}" ] && {
|
||||||
modemmanager_connected_method_dhcp "${interface}" "${beareriface}" "${metric}"
|
case "${bearermethod_ipv4}" in
|
||||||
;;
|
"dhcp")
|
||||||
"static")
|
modemmanager_connected_method_dhcp_ipv4 "${interface}" "${beareriface}" "${metric}"
|
||||||
address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.address")
|
;;
|
||||||
prefix=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.prefix")
|
"static")
|
||||||
gateway=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.gateway")
|
address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.address")
|
||||||
mtu=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.mtu")
|
prefix=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.prefix")
|
||||||
dns1=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[1\]")
|
gateway=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.gateway")
|
||||||
dns2=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[2\]")
|
mtu=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.mtu")
|
||||||
modemmanager_connected_method_static "${interface}" "${beareriface}" "${address}" "${prefix}" "${gateway}" "${mtu}" "${dns1}" "${dns2}" "${metric}"
|
dns1=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[1\]")
|
||||||
;;
|
dns2=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[2\]")
|
||||||
"ppp")
|
modemmanager_connected_method_static_ipv4 "${interface}" "${beareriface}" "${address}" "${prefix}" "${gateway}" "${mtu}" "${dns1}" "${dns2}" "${metric}"
|
||||||
modemmanager_connected_method_ppp "${interface}" "${beareriface}" "${username}" "${password}"
|
;;
|
||||||
;;
|
"ppp")
|
||||||
*)
|
modemmanager_connected_method_ppp_ipv4 "${interface}" "${beareriface}" "${username}" "${password}"
|
||||||
proto_notify_error "${interface}" UNKNOWN_METHOD
|
;;
|
||||||
return 1
|
*)
|
||||||
;;
|
proto_notify_error "${interface}" UNKNOWN_METHOD
|
||||||
esac
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# setup IPv6
|
||||||
|
# note: if using ipv4v6, both IPv4 and IPv6 settings will have the same MTU and metric values reported
|
||||||
|
[ -n "${bearermethod_ipv6}" ] && {
|
||||||
|
case "${bearermethod_ipv6}" in
|
||||||
|
"dhcp")
|
||||||
|
modemmanager_connected_method_dhcp_ipv6 "${interface}" "${beareriface}" "${metric}"
|
||||||
|
;;
|
||||||
|
"static")
|
||||||
|
address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.address")
|
||||||
|
prefix=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.prefix")
|
||||||
|
gateway=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.gateway")
|
||||||
|
mtu=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.mtu")
|
||||||
|
dns1=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.dns.value\[1\]")
|
||||||
|
dns2=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.dns.value\[2\]")
|
||||||
|
modemmanager_connected_method_static_ipv6 "${interface}" "${beareriface}" "${address}" "${prefix}" "${gateway}" "${mtu}" "${dns1}" "${dns2}" "${metric}"
|
||||||
|
;;
|
||||||
|
"ppp")
|
||||||
|
proto_notify_error "${interface}" "unsupported method"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
proto_notify_error "${interface}" UNKNOWN_METHOD
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -362,9 +460,10 @@ proto_modemmanager_teardown() {
|
||||||
local interface="$1"
|
local interface="$1"
|
||||||
|
|
||||||
local modemstatus bearerpath errorstring
|
local modemstatus bearerpath errorstring
|
||||||
|
local bearermethod_ipv4 bearermethod_ipv6
|
||||||
|
|
||||||
local device lowpower
|
local device lowpower iptype
|
||||||
json_get_vars device lowpower
|
json_get_vars device lowpower iptype
|
||||||
|
|
||||||
echo "stopping network"
|
echo "stopping network"
|
||||||
|
|
||||||
|
@ -376,27 +475,23 @@ proto_modemmanager_teardown() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# load bearer connection method
|
# ip type IPv4 is assumed if none explicitly given
|
||||||
|
[ -z "${iptype}" ] && iptype="ipv4"
|
||||||
|
|
||||||
|
# load bearer connection methods
|
||||||
bearerstatus=$(mmcli --bearer "${bearerpath}" --output-keyvalue)
|
bearerstatus=$(mmcli --bearer "${bearerpath}" --output-keyvalue)
|
||||||
bearermethod=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
|
[ "$iptype" = "ipv4" ] || [ "$iptype" = "ipv4v6" ] && {
|
||||||
[ -n "${bearermethod}" ] || {
|
bearermethod_ipv4=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
|
||||||
echo "couldn't load bearer method"
|
echo "IPv4 connection teardown required in interface ${interface}: ${bearermethod_ipv4}"
|
||||||
return
|
}
|
||||||
|
[ "$iptype" = "ipv6" ] || [ "$iptype" = "ipv4v6" ] && {
|
||||||
|
bearermethod_ipv6=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.method")
|
||||||
|
echo "IPv6 connection teardown required in interface ${interface}: ${bearermethod_ipv6}"
|
||||||
}
|
}
|
||||||
|
|
||||||
case "${bearermethod}" in
|
# disconnection handling only requires special treatment in IPv4/PPP
|
||||||
"dhcp")
|
[ "${bearermethod_ipv4}" = "ppp" ] && modemmanager_disconnected_method_ppp_ipv4 "${interface}"
|
||||||
modemmanager_disconnected_method_dhcp "${interface}"
|
modemmanager_disconnected_method_common "${interface}"
|
||||||
;;
|
|
||||||
"static")
|
|
||||||
modemmanager_disconnected_method_static "${interface}"
|
|
||||||
;;
|
|
||||||
"ppp")
|
|
||||||
modemmanager_disconnected_method_ppp "${interface}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# disconnect
|
# disconnect
|
||||||
mmcli --modem="${device}" --simple-disconnect ||
|
mmcli --modem="${device}" --simple-disconnect ||
|
||||||
|
|
Loading…
Reference in a new issue