set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
if [ "$1" -gt 1 ]
then
- shift "$1"
- else
+ shift "$1"
+ else
shift
fi
echo "${1-0}"."${2-0}"."${3-0}"."${4-0}"
}
}
-modemmanager_connected_method_ppp() {
+modemmanager_connected_method_ppp_ipv4() {
local interface="$1"
local ttyname="$2"
local username="$3"
ip-down-script /lib/netifd/ppp-down
}
-modemmanager_disconnected_method_ppp() {
+modemmanager_disconnected_method_ppp_ipv4() {
local interface="$1"
echo "running disconnection (ppp method)"
proto_kill_command "$interface"
}
-modemmanager_connected_method_dhcp() {
+modemmanager_connected_method_dhcp_ipv4() {
local interface="$1"
local wwan="$2"
local metric="$3"
proto_init_update "${wwan}" 1
+ proto_set_keep 1
proto_send_update "${interface}"
json_init
ubus call network add_dynamic "$(json_dump)"
}
-modemmanager_disconnected_method_dhcp() {
- local interface="$1"
-
- echo "running disconnection (dhcp method)"
-
- proto_init_update "*" 0
- proto_send_update "${interface}"
-}
-
-modemmanager_connected_method_static() {
+modemmanager_connected_method_static_ipv4() {
local interface="$1"
local wwan="$2"
local address="$3"
# TODO: mtu reporting in proto handler
proto_init_update "${wwan}" 1
+ proto_set_keep 1
echo "adding IPv4 address ${address}, netmask ${mask}"
proto_add_ipv4_address "${address}" "${mask}"
[ -n "${gateway}" ] && {
proto_send_update "${interface}"
}
-modemmanager_disconnected_method_static() {
+modemmanager_connected_method_dhcp_ipv6() {
local interface="$1"
+ local wwan="$2"
+ local metric="$3"
- echo "running disconnection (static method)"
+ 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"
+
+ echo "running disconnection (common)"
proto_init_update "*" 0
proto_send_update "${interface}"
local interface="$1"
local modempath modemstatus bearercount bearerpath connectargs bearerstatus beareriface
+ local bearermethod_ipv4 bearermethod_ipv6
local operatorname operatorid registration accesstech signalquality
local device apn username password pincode iptype metric
-
+
local address prefix gateway mtu dns1 dns2
json_get_vars device apn username password pincode iptype metric
# always cleanup before attempting a new connection, just in case
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)
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}" || {
proto_notify_error "${interface}" CONNECT_FAILED
proto_block_restart "${interface}"
# load network interface and method information
beareriface=$(modemmanager_get_field "${bearerstatus}" "bearer.status.interface")
- bearermethod=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
- echo "connection setup required in interface ${beareriface}: ${bearermethod}"
-
- case "${bearermethod}" in
- "dhcp")
- modemmanager_connected_method_dhcp "${interface}" "${beareriface}" "${metric}"
- ;;
- "static")
- address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.address")
- prefix=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.prefix")
- gateway=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.gateway")
- mtu=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.mtu")
- dns1=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[1\]")
- dns2=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[2\]")
- modemmanager_connected_method_static "${interface}" "${beareriface}" "${address}" "${prefix}" "${gateway}" "${mtu}" "${dns1}" "${dns2}" "${metric}"
- ;;
- "ppp")
- modemmanager_connected_method_ppp "${interface}" "${beareriface}" "${username}" "${password}"
- ;;
- *)
- proto_notify_error "${interface}" UNKNOWN_METHOD
- return 1
- ;;
- esac
+ [ "$iptype" = "ipv4" ] || [ "$iptype" = "ipv4v6" ] && {
+ 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}"
+ }
+
+ # setup IPv4
+ [ -n "${bearermethod_ipv4}" ] && {
+ case "${bearermethod_ipv4}" in
+ "dhcp")
+ modemmanager_connected_method_dhcp_ipv4 "${interface}" "${beareriface}" "${metric}"
+ ;;
+ "static")
+ address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.address")
+ prefix=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.prefix")
+ gateway=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.gateway")
+ mtu=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.mtu")
+ dns1=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[1\]")
+ dns2=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[2\]")
+ modemmanager_connected_method_static_ipv4 "${interface}" "${beareriface}" "${address}" "${prefix}" "${gateway}" "${mtu}" "${dns1}" "${dns2}" "${metric}"
+ ;;
+ "ppp")
+ modemmanager_connected_method_ppp_ipv4 "${interface}" "${beareriface}" "${username}" "${password}"
+ ;;
+ *)
+ proto_notify_error "${interface}" UNKNOWN_METHOD
+ 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
}
local interface="$1"
local modemstatus bearerpath errorstring
+ local bearermethod_ipv4 bearermethod_ipv6
- local device lowpower
- json_get_vars device lowpower
+ local device lowpower iptype
+ json_get_vars device lowpower iptype
echo "stopping network"
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)
- bearermethod=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
- [ -n "${bearermethod}" ] || {
- echo "couldn't load bearer method"
- return
+ [ "$iptype" = "ipv4" ] || [ "$iptype" = "ipv4v6" ] && {
+ bearermethod_ipv4=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
+ echo "IPv4 connection teardown required in interface ${interface}: ${bearermethod_ipv4}"
+ }
+ [ "$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
- "dhcp")
- modemmanager_disconnected_method_dhcp "${interface}"
- ;;
- "static")
- modemmanager_disconnected_method_static "${interface}"
- ;;
- "ppp")
- modemmanager_disconnected_method_ppp "${interface}"
- ;;
- *)
- ;;
- esac
+ # disconnection handling only requires special treatment in IPv4/PPP
+ [ "${bearermethod_ipv4}" = "ppp" ] && modemmanager_disconnected_method_ppp_ipv4 "${interface}"
+ modemmanager_disconnected_method_common "${interface}"
# disconnect
mmcli --modem="${device}" --simple-disconnect ||