simply use nmcli to handle networkmanager

only support NM >= 0.9.9
This commit is contained in:
garywill 2018-08-31 18:41:06 +08:00 committed by garywill
parent 650d78d456
commit c69d7daa89
2 changed files with 60 additions and 220 deletions

View File

@ -118,17 +118,17 @@ Options:
-h, --help Show this help -h, --help Show this help
--version Print version number --version Print version number
-i <interface> Interface to share Internet to. An NATed subnet will be made on it. -i <interface> Interface to share Internet to. An NATed subnet is made upon it.
To create Wifi hotspot use --ap instead To create Wifi hotspot use '--ap' instead
-n Disable Internet sharing -n Disable Internet sharing
--tp <port> Transparent proxy (redsocks), redirect tcp and udp traffic to port. --tp <port> Transparent proxy (redsocks), redirect tcp and udp traffic to port.
Usually use with --dns-proxy Usually use with --dns-proxy
-g <gateway> Set Gateway IPv4 address, netmask is /24 (default: 192.168.18.1) -g <gateway> Set Gateway IPv4 address, netmask is /24 (default: 192.168.18.1)
--dns-proxy <port> Redirect incoming 53 port to DNS proxy port. dnsmasq DNS is disabled --dns-proxy <port> Redirect incoming port 53 to DNS proxy port. DNS server is disabled
--no-serve-dns dnsmasq DNS disabled --no-serve-dns Disable DNS server
--no-dnsmasq Disable dnsmasq server completely (dhcp and dns) --no-dnsmasq Disable dnsmasq server completely (DHCP and DNS)
--log-dns Show dnsmasq DNS server query log --log-dns Show DNS server query log
--dhcp-dns <IP1[,IP2]>|no --dhcp-dns <IP1[,IP2]>|no
Set DNS offered by DHCP, or no DNS offered (default: gateway as DNS) Set DNS offered by DHCP, or no DNS offered (default: gateway as DNS)
-d DNS server will take into account /etc/hosts -d DNS server will take into account /etc/hosts
@ -162,19 +162,14 @@ Options:
Instance managing: Instance managing:
--daemon Run lnxrouter in the background --daemon Run lnxrouter in the background
--list-running Show the lnxrouter processes that are already running
--stop <id> Send stop command to an already running lnxrouter. For an <id> --stop <id> Send stop command to an already running lnxrouter. For an <id>
you can put the PID of lnxrouter or interface. You can you can put the PID of lnxrouter or interface. You can
get them with --list-running get them with --list-running
--list-running Show the lnxrouter processes that are already running
--list-clients <id> List the clients connected to lnxrouter instance associated with <id>. --list-clients <id> List the clients connected to lnxrouter instance associated with <id>.
For an <id> you can put the PID of lnxrouter or interface. For an <id> you can put the PID of lnxrouter or interface.
If virtual WiFi interface was created, then use that one. If virtual WiFi interface was created, then use that one.
You can get them with --list-running You can get them with --list-running
Tools:
--fix-unmanaged If NetworkManager shows your interface as unmanaged after you
close lnxrouter, then use this option to switch your interface
back to managed
``` ```

251
lnxrouter Normal file → Executable file
View File

@ -63,22 +63,15 @@ usage() {
echo echo
echo " Instance managing:" echo " Instance managing:"
echo " --daemon Run lnxrouter in the background" echo " --daemon Run lnxrouter in the background"
echo " --list-running Show the lnxrouter processes that are already running"
echo " --stop <id> Send stop command to an already running lnxrouter. For an <id>" echo " --stop <id> Send stop command to an already running lnxrouter. For an <id>"
echo " you can put the PID of lnxrouter or interface. You can" echo " you can put the PID of lnxrouter or interface. You can"
echo " get them with --list-running" echo " get them with --list-running"
echo " --list-running Show the lnxrouter processes that are already running"
echo " --list-clients <id> List the clients connected to lnxrouter instance associated with <id>." echo " --list-clients <id> List the clients connected to lnxrouter instance associated with <id>."
echo " For an <id> you can put the PID of lnxrouter or interface." echo " For an <id> you can put the PID of lnxrouter or interface."
echo " If virtual WiFi interface was created, then use that one." echo " If virtual WiFi interface was created, then use that one."
echo " You can get them with --list-running" echo " You can get them with --list-running"
echo echo
echo " Tools:"
echo " --fix-unmanaged If NetworkManager shows your interface as unmanaged after you"
echo " close lnxrouter, then use this option to switch your interface"
echo " back to managed"
echo
echo
echo "Examples:" echo "Examples:"
echo " "$PROGNAME" -i eth1" echo " "$PROGNAME" -i eth1"
echo " "$PROGNAME" --ap wlan0 MyAccessPoint --password MyPassPhrase" echo " "$PROGNAME" --ap wlan0 MyAccessPoint --password MyPassPhrase"
@ -104,7 +97,6 @@ ADDN_HOSTS=
SUBNET_IFACE= SUBNET_IFACE=
CONN_IFACE= CONN_IFACE=
ISOLATE_CLIENTS=0
SHARE_METHOD=nat SHARE_METHOD=nat
TP_PORT= TP_PORT=
TP_DNS_PORT= TP_DNS_PORT=
@ -132,7 +124,7 @@ FREQ_BAND=2.4
NO_HAVEGED=0 NO_HAVEGED=0
HOSTAPD_DEBUG_ARGS= HOSTAPD_DEBUG_ARGS=
USE_PSK=0 USE_PSK=0
FIX_UNMANAGED=0 ISOLATE_CLIENTS=0
LIST_RUNNING=0 LIST_RUNNING=0
STOP_ID= STOP_ID=
@ -284,10 +276,7 @@ while [[ -n "$1" ]]; do
shift shift
NO_VIRT=1 NO_VIRT=1
;; ;;
--fix-unmanaged)
shift
FIX_UNMANAGED=1
;;
--country) --country)
shift shift
COUNTRY="$1" COUNTRY="$1"
@ -561,173 +550,51 @@ haveged_watchdog() {
#======== #========
NETWORKMANAGER_CONF=/etc/NetworkManager/NetworkManager.conf
NM_OLDER_VERSION=1
networkmanager_exists() { # only support NetworkManager >= 0.9.9
local NM_VER NM_RUNNING=0
which nmcli > /dev/null 2>&1 || return 1 NM_UNM_LIST=
if (which nmcli >/dev/null 2>&1 ) && (nmcli -t -f RUNNING g 2>&1 | grep -E '^running$' >/dev/null 2>&1 ) ; then
NM_RUNNING=1
NM_VER=$(nmcli -v | grep -m1 -oE '[0-9]+(\.[0-9]+)*\.[0-9]+') NM_VER=$(nmcli -v | grep -m1 -oE '[0-9]+(\.[0-9]+)*\.[0-9]+')
version_cmp $NM_VER 0.9.9 version_cmp $NM_VER 0.9.9 && echo "Warning: NetworkManager need >=0.9.9 or you may encounter problems"
if [[ $? -eq 1 ]]; then
NM_OLDER_VERSION=1
else
NM_OLDER_VERSION=0
fi fi
return 0
nm_knows() {
(nmcli dev show $1 | grep -E "^GENERAL.STATE:" >/dev/null 2>&1 ) && return 0 # nm sees
return 1 # nm doesn't see this interface
} }
nm_get_manage() { # get an interface's managed state
networkmanager_is_running() { local s
local NMCLI_OUT s=$(nmcli dev show $1 | grep -E "^GENERAL.STATE:") || return 2 # no such interface
networkmanager_exists || return 1 (echo $s | grep "unmanaged" >/dev/null 2>&1) && return 1 # unmanaged
if [[ $NM_OLDER_VERSION -eq 1 ]]; then return 0 # managed
NMCLI_OUT=$(nmcli -t -f RUNNING nm 2>&1 | grep -E '^running$')
else
NMCLI_OUT=$(nmcli -t -f RUNNING g 2>&1 | grep -E '^running$')
fi
[[ -n "$NMCLI_OUT" ]]
} }
nm_set_unmanaged() {
networkmanager_iface_is_unmanaged() { while ! nm_knows $1 ; do # wait for virtual wifi interface seen by NM
is_interface "$1" || return 2 sleep 0.5
(nmcli -t -f DEVICE d 2>&1 | grep -Fxq "$1") || return 0 # NM doesn't know this interface
(nmcli -t -f DEVICE,STATE d 2>&1 | grep -E "^$1:unmanaged$" > /dev/null 2>&1) || return 1
return 0 # is unmanaged
}
ADDED_UNMANAGED=
networkmanager_add_unmanaged() {
local MAC UNMANAGED WAS_EMPTY x
networkmanager_exists || return 1
[[ -d ${NETWORKMANAGER_CONF%/*} ]] || mkdir -p ${NETWORKMANAGER_CONF%/*}
[[ -f ${NETWORKMANAGER_CONF} ]] || touch ${NETWORKMANAGER_CONF}
if [[ $NM_OLDER_VERSION -eq 1 ]]; then
if [[ -z "$2" ]]; then
MAC=$(get_macaddr "$1")
else
MAC="$2"
fi
[[ -z "$MAC" ]] && return 1
fi
UNMANAGED=$(grep -m1 -Eo '^unmanaged-devices=[[:alnum:]:;,-]*' /etc/NetworkManager/NetworkManager.conf)
WAS_EMPTY=0
[[ -z "$UNMANAGED" ]] && WAS_EMPTY=1
UNMANAGED=$(echo "$UNMANAGED" | sed 's/unmanaged-devices=//' | tr ';,' ' ')
# if it exists, do nothing
for x in $UNMANAGED; do
if [[ $x == "mac:${MAC}" ]] ||
[[ $NM_OLDER_VERSION -eq 0 && $x == "interface-name:${1}" ]]; then
return 2
fi
done done
if nm_get_manage $1 ;then
if [[ $NM_OLDER_VERSION -eq 1 ]]; then echo "Set $1 unmanaged by NetworkManager"
UNMANAGED="${UNMANAGED} mac:${MAC}" nmcli dev set $1 managed no || die "Failed to set $1 unmanaged by NetworkManager"
else NM_UNM_LIST=$1
UNMANAGED="${UNMANAGED} interface-name:${1}"
fi
UNMANAGED=$(echo $UNMANAGED | sed -e 's/^ //')
UNMANAGED="${UNMANAGED// /;}"
UNMANAGED="unmanaged-devices=${UNMANAGED}"
if ! grep -E '^\[keyfile\]' ${NETWORKMANAGER_CONF} > /dev/null 2>&1; then
echo -e "\n\n[keyfile]\n${UNMANAGED}" >> ${NETWORKMANAGER_CONF}
elif [[ $WAS_EMPTY -eq 1 ]]; then
sed -e "s/^\(\[keyfile\].*\)$/\1\n${UNMANAGED}/" -i ${NETWORKMANAGER_CONF}
else
sed -e "s/^unmanaged-devices=.*/${UNMANAGED}/" -i ${NETWORKMANAGER_CONF}
fi
ADDED_UNMANAGED="${ADDED_UNMANAGED} ${1} "
local nm_pid=$(pidof NetworkManager)
[[ -n "$nm_pid" ]] && kill -HUP $nm_pid
return 0
}
networkmanager_rm_unmanaged() {
local MAC UNMANAGED
networkmanager_exists || return 1
[[ ! -f ${NETWORKMANAGER_CONF} ]] && return 1
if [[ $NM_OLDER_VERSION -eq 1 ]]; then
if [[ -z "$2" ]]; then
MAC=$(get_macaddr "$1")
else
MAC="$2"
fi
[[ -z "$MAC" ]] && return 1
fi
UNMANAGED=$(grep -m1 -Eo '^unmanaged-devices=[[:alnum:]:;,-]*' /etc/NetworkManager/NetworkManager.conf | sed 's/unmanaged-devices=//' | tr ';,' ' ')
if [[ -z "$UNMANAGED" ]]; then
return 1
fi
[[ -n "$MAC" ]] && UNMANAGED=$(echo $UNMANAGED | sed -e "s/mac:${MAC}\( \|$\)//g")
UNMANAGED=$(echo $UNMANAGED | sed -e "s/interface-name:${1}\( \|$\)//g")
UNMANAGED=$(echo $UNMANAGED | sed -e 's/ $//')
if [[ -z "$UNMANAGED" ]]; then
sed -e "/^unmanaged-devices=.*/d" -i ${NETWORKMANAGER_CONF}
else
UNMANAGED="${UNMANAGED// /;}"
UNMANAGED="unmanaged-devices=${UNMANAGED}"
sed -e "s/^unmanaged-devices=.*/${UNMANAGED}/" -i ${NETWORKMANAGER_CONF}
fi
ADDED_UNMANAGED="${ADDED_UNMANAGED/ ${1} /}"
local nm_pid=$(pidof NetworkManager)
[[ -n "$nm_pid" ]] && kill -HUP $nm_pid
return 0
}
networkmanager_fix_unmanaged() {
[[ -f ${NETWORKMANAGER_CONF} ]] || return
sed -e "/^unmanaged-devices=.*/d" -i ${NETWORKMANAGER_CONF}
local nm_pid=$(pidof NetworkManager)
[[ -n "$nm_pid" ]] && kill -HUP $nm_pid
}
networkmanager_rm_unmanaged_if_needed() {
if [[ $ADDED_UNMANAGED =~ .*\ ${1}\ .* ]]; then
echo "$1 needs to remove unmanaged"
networkmanager_rm_unmanaged $1 $2
else
echo "$1 doesn't need to remove unmanaged"
fi
}
networkmanager_wait_until_unmanaged() {
local RES
networkmanager_is_running || return 1
while :; do
networkmanager_iface_is_unmanaged "$1"
RES=$?
[[ $RES -eq 0 ]] && break
[[ $RES -eq 2 ]] && die "Interface '${1}' does not exist.
It's probably renamed by a udev rule.
use iwconfig to see devices.
use iw dev <dev name> del to delete uneeded device"
sleep 1 sleep 1
done fi
sleep 2
return 0
} }
nm_set_managed() {
nmcli dev set $1 managed yes
NM_UNM_LIST=
}
nm_restore_manage() {
if [[ $NM_UNM_LIST ]]; then
echo "Restore $NM_UNM_LIST managed by NetworkManager"
nm_set_managed $NM_UNM_LIST
sleep 0.5
fi
}
#========= #=========
alias iptables="iptables -w" alias iptables="iptables -w"
@ -836,23 +703,21 @@ kill_processes() {
} }
_cleanup() { _cleanup() {
local PID x local x
#disown -a nm_restore_manage
rm -rf $CONFDIR rm -rf $CONFDIR
ip addr flush ${SUBNET_IFACE} ip addr flush ${SUBNET_IFACE}
if [[ $WIFI_IFACE && $NO_VIRT -eq 0 ]]; then if [[ $WIFI_IFACE && $NO_VIRT -eq 0 ]]; then
ip link set down dev ${AP_IFACE} ip link set down dev ${AP_IFACE}
networkmanager_rm_unmanaged_if_needed ${VWIFI_IFACE} ${OLD_MACADDR}
iw dev ${VWIFI_IFACE} del iw dev ${VWIFI_IFACE} del
dealloc_iface $VWIFI_IFACE dealloc_iface $VWIFI_IFACE
else else
if [[ -n "$NEW_MACADDR" ]]; then if [[ -n "$NEW_MACADDR" ]]; then
ip link set dev ${TARGET_IFACE} address ${OLD_MACADDR} && echo "Restore ${TARGET_IFACE} to old MAC address ${OLD_MACADDR}" ip link set dev ${TARGET_IFACE} address ${OLD_MACADDR} && echo "Restore ${TARGET_IFACE} to old MAC address ${OLD_MACADDR}"
fi fi
networkmanager_rm_unmanaged_if_needed ${TARGET_IFACE} ${OLD_MACADDR}
fi fi
# if we are the last lnxrouter instance then set back the common values # if we are the last lnxrouter instance then set back the common values
@ -1121,12 +986,6 @@ if [[ -n "$STOP_ID" ]]; then
exit 0 exit 0
fi fi
if [[ $FIX_UNMANAGED -eq 1 ]]; then
echo "Trying to fix unmanaged status in NetworkManager..."
networkmanager_fix_unmanaged
exit 0
fi
#============================================= #=============================================
#============================================= #=============================================
@ -1226,6 +1085,8 @@ fi
## ======================================================== ## ========================================================
## ======================================================== ## ========================================================
echo "PID: $$"
TARGET_IFACE= # This is the existing physical interface to use TARGET_IFACE= # This is the existing physical interface to use
if [[ $CONN_IFACE ]]; then if [[ $CONN_IFACE ]]; then
TARGET_IFACE=$CONN_IFACE TARGET_IFACE=$CONN_IFACE
@ -1258,7 +1119,6 @@ chmod 755 $TMPDIR 2>/dev/null
CONFDIR=$(mktemp -d $TMPDIR/lnxrouter.${TARGET_IFACE}.conf.XXX) CONFDIR=$(mktemp -d $TMPDIR/lnxrouter.${TARGET_IFACE}.conf.XXX)
chmod 755 $CONFDIR chmod 755 $CONFDIR
#echo "Config dir: $CONFDIR" #echo "Config dir: $CONFDIR"
echo "PID: $$"
echo $$ > $CONFDIR/pid echo $$ > $CONFDIR/pid
@ -1275,16 +1135,9 @@ if [[ $WIFI_IFACE ]]; then
fi fi
if [[ $NO_VIRT -eq 0 ]]; then if [[ $NO_VIRT -eq 0 ]]; then
VWIFI_IFACE=$(alloc_new_iface) ## Generate virtual wifi interface
# in NetworkManager 0.9.9 and above we can set the interface as unmanaged without VWIFI_IFACE=$(alloc_new_iface)
# the need of MAC address, so we set it before we create the virtual interface.
if networkmanager_is_running && [[ $NM_OLDER_VERSION -eq 0 ]]; then
echo "Network Manager found, set ${VWIFI_IFACE} as unmanaged device... "
networkmanager_add_unmanaged ${VWIFI_IFACE}
# do not call networkmanager_wait_until_unmanaged because interface does not
# exist yet
fi
if is_wifi_connected ${WIFI_IFACE}; then if is_wifi_connected ${WIFI_IFACE}; then
WIFI_IFACE_FREQ=$(iw dev ${WIFI_IFACE} link | grep -i freq | awk '{print $2}') WIFI_IFACE_FREQ=$(iw dev ${WIFI_IFACE} link | grep -i freq | awk '{print $2}')
@ -1308,9 +1161,8 @@ if [[ $WIFI_IFACE ]]; then
echo "Creating a virtual WiFi interface... " echo "Creating a virtual WiFi interface... "
if iw dev ${WIFI_IFACE} interface add ${VWIFI_IFACE} type __ap; then if iw dev ${WIFI_IFACE} interface add ${VWIFI_IFACE} type __ap; then
# now we can call networkmanager_wait_until_unmanaged
networkmanager_is_running && [[ $NM_OLDER_VERSION -eq 0 ]] && networkmanager_wait_until_unmanaged ${VWIFI_IFACE}
echo "${VWIFI_IFACE} created." echo "${VWIFI_IFACE} created."
sleep 2
else else
VWIFI_IFACE= VWIFI_IFACE=
die "$VIRTDIEMSG" die "$VIRTDIEMSG"
@ -1425,15 +1277,8 @@ fi
#=================================================== #===================================================
#=================================================== #===================================================
if networkmanager_exists && ! networkmanager_iface_is_unmanaged ${SUBNET_IFACE}; then if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE ; then
echo "Network Manager found, set ${SUBNET_IFACE} as unmanaged device... " nm_set_unmanaged ${SUBNET_IFACE}
networkmanager_add_unmanaged ${SUBNET_IFACE}
if networkmanager_is_running; then
networkmanager_wait_until_unmanaged ${SUBNET_IFACE}
fi
echo "Successfully set to unmanaged"
fi fi
if [[ $NO_DNSMASQ -eq 0 ]]; then if [[ $NO_DNSMASQ -eq 0 ]]; then