uqmi: Add proper IPv6 support
Use the new --ip-family option to start both IPv4 and IPv6 sessions by default. Autoconnect can't be used when starting two sessions, so revert back to using the client IDs and packet data handles for handling the network connection. Some modem firmwares do not implement a RA server, therefore by default use outband IP configuration and static addressing. Some other firmwares report bogus IP configuration with the WDS get current settings command. In this case inband configuration with DHCP/RA can be optionally enabled by setting option dhcp to 1. Per 3GPP standard a /64 prefix is served to all clients, which is extended to LAN as specified in RFC 7278. v2: Restrict the IPv6 gateway route source address Signed-off-by: Matti Laakso <malaakso@elisanet.fi> SVN-Revision: 46843
This commit is contained in:
parent
eb866e413f
commit
8f24ee6382
@ -1,13 +1,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=uqmi
|
||||
PKG_VERSION:=2014-12-03
|
||||
PKG_VERSION:=2015-08-13
|
||||
PKG_RELEASE=$(PKG_SOURCE_VERSION)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=git://nbd.name/uqmi.git
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=86bcdb8cca652676a78b2df8b5e3fb27a40c60a4
|
||||
PKG_SOURCE_VERSION:=8a97586e9445a60e355dea13aa87885ab3dcb277
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MAINTAINER:=Matti Laakso <malaakso@elisanet.fi>
|
||||
# PKG_MIRROR_MD5SUM:=
|
||||
|
205
package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
Executable file → Normal file
205
package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
Executable file → Normal file
@ -17,28 +17,25 @@ proto_qmi_init_config() {
|
||||
proto_config_add_string pincode
|
||||
proto_config_add_string delay
|
||||
proto_config_add_string modes
|
||||
proto_config_add_boolean ipv6
|
||||
proto_config_add_boolean dhcp
|
||||
}
|
||||
|
||||
qmi_disconnect() {
|
||||
# disable previous autoconnect state using the global handle
|
||||
# do not reuse previous wds client id to prevent hangs caused by stale data
|
||||
uqmi -s -d "$device" \
|
||||
--stop-network 0xffffffff \
|
||||
--autoconnect > /dev/null
|
||||
}
|
||||
|
||||
qmi_wds_release() {
|
||||
[ -n "$cid" ] || return 0
|
||||
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid" --release-client-id wds
|
||||
uci_revert_state network $interface cid
|
||||
}
|
||||
|
||||
_proto_qmi_setup() {
|
||||
proto_qmi_setup() {
|
||||
local interface="$1"
|
||||
|
||||
local device apn auth username password pincode delay modes cid pdh
|
||||
json_get_vars device apn auth username password pincode delay modes
|
||||
local device apn auth username password pincode delay modes ipv6 dhcp
|
||||
local cid_4 pdh_4 cid_6 pdh_6 ipv4
|
||||
local ip subnet gateway dns1 dns2 ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6
|
||||
json_get_vars device apn auth username password pincode delay modes ipv6 dhcp
|
||||
|
||||
ipv4=1
|
||||
|
||||
if [ "$ipv6" = 0 ]; then
|
||||
ipv6=""
|
||||
else
|
||||
ipv6=1
|
||||
fi
|
||||
|
||||
[ -n "$ctl_device" ] && device=$ctl_device
|
||||
|
||||
@ -86,8 +83,6 @@ _proto_qmi_setup() {
|
||||
return 1
|
||||
}
|
||||
|
||||
qmi_disconnect
|
||||
|
||||
uqmi -s -d "$device" --set-data-format 802.3
|
||||
uqmi -s -d "$device" --wda-set-data-format 802.3
|
||||
|
||||
@ -99,67 +94,159 @@ _proto_qmi_setup() {
|
||||
[ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes"
|
||||
|
||||
echo "Starting network $apn"
|
||||
cid=`uqmi -s -d "$device" --get-client-id wds`
|
||||
|
||||
cid_4=`uqmi -s -d "$device" --get-client-id wds`
|
||||
[ $? -ne 0 ] && {
|
||||
echo "Unable to obtain client ID"
|
||||
proto_notify_error "$interface" NO_CID
|
||||
return 1
|
||||
}
|
||||
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid" \
|
||||
pdh_4=`uqmi -s -d "$device" --set-client-id wds,"$cid_4" \
|
||||
--start-network "$apn" \
|
||||
${auth:+--auth-type $auth} \
|
||||
${username:+--username $username} \
|
||||
${password:+--password $password} \
|
||||
--autoconnect > /dev/null
|
||||
|
||||
echo "Starting DHCP"
|
||||
proto_init_update "$ifname" 1
|
||||
proto_send_update "$interface"
|
||||
|
||||
json_init
|
||||
json_add_string name "${interface}_4"
|
||||
json_add_string ifname "@$interface"
|
||||
json_add_string proto "dhcp"
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
|
||||
json_init
|
||||
json_add_string name "${interface}_6"
|
||||
json_add_string ifname "@$interface"
|
||||
json_add_string proto "dhcpv6"
|
||||
json_add_string extendprefix 1
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
}
|
||||
|
||||
proto_qmi_setup() {
|
||||
local ret
|
||||
|
||||
_proto_qmi_setup $@
|
||||
ret=$?
|
||||
|
||||
[ "$ret" = 0 ] || {
|
||||
logger "qmi bringup failed, retry in 15s"
|
||||
sleep 15
|
||||
--ip-family ipv4`
|
||||
[ $? -ne 0 ] && {
|
||||
echo "Unable to connect IPv4"
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds
|
||||
ipv4=""
|
||||
}
|
||||
|
||||
return $rt
|
||||
[ -n "$ipv6" ] && {
|
||||
cid_6=`uqmi -s -d "$device" --get-client-id wds`
|
||||
if [ $? = 0 ]; then
|
||||
pdh_6=`uqmi -s -d "$device" --set-client-id wds,"$cid_6" \
|
||||
--start-network "$apn" \
|
||||
${auth:+--auth-type $auth} \
|
||||
${username:+--username $username} \
|
||||
${password:+--password $password} \
|
||||
--ip-family ipv6`
|
||||
[ $? -ne 0 ] && {
|
||||
echo "Unable to connect IPv6"
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds
|
||||
ipv6=""
|
||||
}
|
||||
else
|
||||
echo "Unable to connect IPv6"
|
||||
ipv6=""
|
||||
fi
|
||||
}
|
||||
|
||||
[ -z "$ipv4" -a -z "$ipv6" ] && {
|
||||
echo "Unable to connect"
|
||||
proto_notify_error "$interface" CALL_FAILED
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ -z "$dhcp" ]; then
|
||||
echo "Setting up $ifname"
|
||||
[ -n "$ipv4" ] && {
|
||||
json_load "$(uqmi -s -d $device --set-client-id wds,$cid_4 --get-current-settings)"
|
||||
json_select ipv4
|
||||
json_get_vars ip subnet gateway dns1 dns2
|
||||
|
||||
proto_init_update "$ifname" 1
|
||||
proto_set_keep 1
|
||||
proto_add_ipv4_address "$ip" "$subnet"
|
||||
proto_add_dns_server "$dns1"
|
||||
proto_add_dns_server "$dns2"
|
||||
proto_add_ipv4_route "0.0.0.0" 0 "$gateway"
|
||||
proto_add_data
|
||||
json_add_string "cid_4" "$cid_4"
|
||||
json_add_string "pdh_4" "$pdh_4"
|
||||
proto_close_data
|
||||
proto_send_update "$interface"
|
||||
}
|
||||
|
||||
[ -n "$ipv6" ] && {
|
||||
json_load "$(uqmi -s -d $device --set-client-id wds,$cid_6 --get-current-settings)"
|
||||
json_select ipv6
|
||||
json_get_var ip_6 ip
|
||||
json_get_var gateway_6 gateway
|
||||
json_get_var dns1_6 dns1
|
||||
json_get_var dns2_6 dns2
|
||||
json_get_var ip_prefix_length ip-prefix-length
|
||||
|
||||
proto_init_update "$ifname" 1
|
||||
proto_set_keep 1
|
||||
# RFC 7278: Extend an IPv6 /64 Prefix to LAN
|
||||
proto_add_ipv6_address "$ip_6" "128"
|
||||
proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}"
|
||||
proto_add_ipv6_route "$gateway_6" "128"
|
||||
proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}"
|
||||
proto_add_dns_server "$dns1_6"
|
||||
proto_add_dns_server "$dns2_6"
|
||||
proto_add_data
|
||||
json_add_string "cid_6" "$cid_6"
|
||||
json_add_string "pdh_6" "$pdh_6"
|
||||
proto_close_data
|
||||
proto_send_update "$interface"
|
||||
}
|
||||
else
|
||||
echo "Starting DHCP on $ifname"
|
||||
proto_init_update "$ifname" 1
|
||||
proto_add_data
|
||||
[ -n "$ipv4" ] && {
|
||||
json_add_string "cid_4" "$cid_4"
|
||||
json_add_string "pdh_4" "$pdh_4"
|
||||
}
|
||||
[ -n "$ipv6" ] && {
|
||||
json_add_string "cid_6" "$cid_6"
|
||||
json_add_string "pdh_6" "$pdh_6"
|
||||
}
|
||||
proto_close_data
|
||||
proto_send_update "$interface"
|
||||
|
||||
[ -n "$ipv4" ] && {
|
||||
json_init
|
||||
json_add_string name "${interface}_4"
|
||||
json_add_string ifname "@$interface"
|
||||
json_add_string proto "dhcp"
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
}
|
||||
|
||||
[ -n "$ipv6" ] && {
|
||||
json_init
|
||||
json_add_string name "${interface}_6"
|
||||
json_add_string ifname "@$interface"
|
||||
json_add_string proto "dhcpv6"
|
||||
# RFC 7278: Extend an IPv6 /64 Prefix to LAN
|
||||
json_add_string extendprefix 1
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
proto_qmi_teardown() {
|
||||
local interface="$1"
|
||||
|
||||
local device
|
||||
local device cid_4 pdh_4 cid_6 pdh_6
|
||||
json_get_vars device
|
||||
|
||||
[ -n "$ctl_device" ] && device=$ctl_device
|
||||
|
||||
local cid=$(uci_get_state network $interface cid)
|
||||
|
||||
echo "Stopping network"
|
||||
qmi_disconnect
|
||||
qmi_wds_release
|
||||
|
||||
json_load "$(ubus call network.interface.$interface status)"
|
||||
json_select data
|
||||
json_get_vars cid_4 pdh_4 cid_6 pdh_6
|
||||
|
||||
[ -n "$cid_4" ] && {
|
||||
[ -n "$pdh_4" ] && {
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid_4" --stop-network "$pdh_4"
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds
|
||||
}
|
||||
}
|
||||
[ -n "$cid_6" ] && {
|
||||
[ -n "$pdh_6" ] && {
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid_6" --stop-network "$pdh_6"
|
||||
uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds
|
||||
}
|
||||
}
|
||||
|
||||
proto_init_update "*" 0
|
||||
proto_send_update "$interface"
|
||||
|
Loading…
Reference in New Issue
Block a user