Reimplementation of 6a3e1d98
commit
With the 6a3e1d98
commit NetworkManager was throwing an assertion so
we take a different approach when we create the bridge interface.
Also if the <interface-with-internet> is already a bridge interface
we skip creation.
The new approach is:
1) Save the IPs and route table of INTERNET_IFACE
2) If NetworkManager is running set INTERNET_IFACE as unmanaged
3) Create BRIDGE_IFACE and add INTERNET_IFACE to it
4) Set the previously saved IPs and route table to BRIDGE_IFACE
Better fix #19
This commit is contained in:
parent
14ec50f379
commit
81d861cb46
@ -54,6 +54,9 @@
|
||||
### Bridged Internet sharing:
|
||||
create_ap -m bridge wlan0 eth0 MyAccessPoint MyPassPhrase
|
||||
|
||||
### Bridged Internet sharing (pre-configured bridge interface):
|
||||
create_ap -m bridge wlan0 br0 MyAccessPoint MyPassPhrase
|
||||
|
||||
### Internet sharing from the same WiFi interface:
|
||||
create_ap wlan0 wlan0 MyAccessPoint MyPassPhrase
|
||||
|
||||
|
146
create_ap
146
create_ap
@ -43,6 +43,8 @@ usage() {
|
||||
echo " * If you're not using the --no-virt option, then you can create an AP with the same"
|
||||
echo " interface you are getting your Internet connection."
|
||||
echo " * You can pass your SSID and password through pipe or through arguments (see examples)."
|
||||
echo " * On bridge method if the <interface-with-internet> is not a bridge interface, then"
|
||||
echo " a bridge interface is created automatically."
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " $(basename $0) wlan0 eth0 MyAccessPoint MyPassPhrase"
|
||||
@ -52,6 +54,7 @@ usage() {
|
||||
echo " $(basename $0) wlan0 wlan0 MyAccessPoint MyPassPhrase"
|
||||
echo " $(basename $0) -n wlan0 MyAccessPoint MyPassPhrase"
|
||||
echo " $(basename $0) -m bridge wlan0 eth0 MyAccessPoint MyPassPhrase"
|
||||
echo " $(basename $0) -m bridge wlan0 br0 MyAccessPoint MyPassPhrase"
|
||||
echo " $(basename $0) --driver rtl871xdrv wlan0 eth0 MyAccessPoint MyPassPhrase"
|
||||
}
|
||||
|
||||
@ -88,6 +91,10 @@ is_wifi_interface() {
|
||||
return 1
|
||||
}
|
||||
|
||||
is_bridge_interface() {
|
||||
brctl show | cut -f1 | grep -E "^$1\$" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
get_phy_device() {
|
||||
for x in /sys/class/ieee80211/*; do
|
||||
[[ ! -d "$x" ]] && continue
|
||||
@ -160,9 +167,8 @@ get_macaddr() {
|
||||
|
||||
get_avail_bridge() {
|
||||
for i in {0..100}; do
|
||||
curr_bridge=$(brctl show | grep "br$i" | cut -s -f1)
|
||||
if [[ -z $curr_bridge ]]; then
|
||||
echo "br$i"
|
||||
if ! is_bridge_interface "br${i}"; then
|
||||
echo "br${i}"
|
||||
return
|
||||
fi
|
||||
done
|
||||
@ -177,7 +183,6 @@ get_new_macaddr() {
|
||||
echo $NEWMAC
|
||||
}
|
||||
|
||||
ADDED_UNMANAGED=0
|
||||
NETWORKMANAGER_CONF=/etc/NetworkManager/NetworkManager.conf
|
||||
NM_OLDER_VERSION=1
|
||||
|
||||
@ -323,6 +328,8 @@ BRIDGE_IFACE=
|
||||
OLD_IP_FORWARD=
|
||||
OLD_BRIDGE_IPTABLES=
|
||||
OLD_MACADDR=
|
||||
IP_ADDRS=
|
||||
ROUTE_ADDRS=
|
||||
|
||||
cleanup() {
|
||||
trap "" SIGINT
|
||||
@ -345,19 +352,39 @@ cleanup() {
|
||||
iptables -D FORWARD -i ${INTERNET_IFACE} -d ${GATEWAY%.*}.0/24 -j ACCEPT > /dev/null 2>&1
|
||||
[[ -n $OLD_IP_FORWARD ]] && echo $OLD_IP_FORWARD > /proc/sys/net/ipv4/ip_forward
|
||||
elif [[ "$SHARE_METHOD" == "bridge" ]]; then
|
||||
ip route show dev $BRIDGE_IFACE | grep -v -E '^default' | while read x; do
|
||||
ip route del $x dev $BRIDGE_IFACE
|
||||
ip route add $x dev $INTERNET_IFACE
|
||||
done
|
||||
|
||||
ip route show dev $BRIDGE_IFACE | grep -E '^default' | while read x; do
|
||||
ip route del $x dev $BRIDGE_IFACE
|
||||
ip route add $x dev $INTERNET_IFACE
|
||||
done
|
||||
if [[ -n $OLD_BRIDGE_IPTABLES ]]; then
|
||||
echo $OLD_BRIDGE_IPTABLES > /proc/sys/net/bridge/bridge-nf-call-iptables
|
||||
fi
|
||||
|
||||
if ! is_bridge_interface $INTERNET_IFACE; then
|
||||
ip link set down $BRIDGE_IFACE
|
||||
brctl delbr $BRIDGE_IFACE
|
||||
[[ -n $OLD_BRIDGE_IPTABLES ]] && echo $OLD_BRIDGE_IPTABLES > /proc/sys/net/bridge/bridge-nf-call-iptables
|
||||
ip addr flush $INTERNET_IFACE
|
||||
ip link set dev $INTERNET_IFACE up
|
||||
|
||||
for x in "${IP_ADDRS[@]}"; do
|
||||
x="${x/inet/}"
|
||||
x="${x/secondary/}"
|
||||
x="${x/dynamic/}"
|
||||
x=$(echo $x | sed 's/\([0-9]\)sec/\1/g')
|
||||
x="${x/${INTERNET_IFACE}/}"
|
||||
ip addr add $x dev $INTERNET_IFACE
|
||||
done
|
||||
|
||||
ip route flush dev $INTERNET_IFACE
|
||||
|
||||
for x in "${ROUTE_ADDRS[@]}"; do
|
||||
[[ "$x" == default* ]] && continue
|
||||
ip route add $x dev $INTERNET_IFACE
|
||||
done
|
||||
|
||||
for x in "${ROUTE_ADDRS[@]}"; do
|
||||
[[ "$x" != default* ]] && continue
|
||||
ip route add $x dev $INTERNET_IFACE
|
||||
done
|
||||
|
||||
networkmanager_rm_unmanaged_if_needed $INTERNET_IFACE
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -501,17 +528,6 @@ if [[ "$SHARE_METHOD" != "nat" && "$SHARE_METHOD" != "bridge" && "$SHARE_METHOD"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$SHARE_METHOD" == "bridge" ]]; then
|
||||
OLD_BRIDGE_IPTABLES=$(cat /proc/sys/net/bridge/bridge-nf-call-iptables)
|
||||
BRIDGE_IFACE=$(get_avail_bridge)
|
||||
if [[ -z $BRIDGE_IFACE ]]; then
|
||||
echo "ERROR: No availabe bridges < br100" >&2
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$SHARE_METHOD" == "nat" ]]; then
|
||||
OLD_IP_FORWARD=$(cat /proc/sys/net/ipv4/ip_forward)
|
||||
fi
|
||||
|
||||
if [[ "$SHARE_METHOD" != "none" ]]; then
|
||||
MIN_REQUIRED_ARGS=2
|
||||
else
|
||||
@ -562,6 +578,23 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$SHARE_METHOD" == "bridge" ]]; then
|
||||
OLD_BRIDGE_IPTABLES=$(cat /proc/sys/net/bridge/bridge-nf-call-iptables)
|
||||
|
||||
if is_bridge_interface $INTERNET_IFACE; then
|
||||
BRIDGE_IFACE=$INTERNET_IFACE
|
||||
else
|
||||
BRIDGE_IFACE=$(get_avail_bridge)
|
||||
fi
|
||||
|
||||
if [[ -z $BRIDGE_IFACE ]]; then
|
||||
echo "ERROR: No availabe bridges < br100" >&2
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$SHARE_METHOD" == "nat" ]]; then
|
||||
OLD_IP_FORWARD=$(cat /proc/sys/net/ipv4/ip_forward)
|
||||
fi
|
||||
|
||||
if [[ $NO_VIRT -eq 1 && "$WIFI_IFACE" == "$INTERNET_IFACE" ]]; then
|
||||
echo -n "ERROR: You can not share your connection from the same" >&2
|
||||
echo " interface if you are using --no-virt option." >&2
|
||||
@ -693,48 +726,65 @@ if [[ "$SHARE_METHOD" != "none" ]]; then
|
||||
elif [[ "$SHARE_METHOD" == "bridge" ]]; then
|
||||
# disable iptables rules for bridged interfaces
|
||||
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables || die
|
||||
# create and initialize bridged interface
|
||||
brctl addbr ${BRIDGE_IFACE} || die
|
||||
brctl addif ${BRIDGE_IFACE} ${INTERNET_IFACE} || die
|
||||
|
||||
# to initialize the bridge interface correctly we need to do the following:
|
||||
#
|
||||
# 1) duplicate the IPs of INTERNET_IFACE to BRIDGE_IFACE
|
||||
# 2) duplicate routing table of INTERNET_IFACE to BRIDGE_IFACE
|
||||
# 3) delete routing table of INTERNET_IFACE
|
||||
# NOTE: we don't need to delete the IPs of INTERNET_IFACE
|
||||
# 1) save the IPs and route table of INTERNET_IFACE
|
||||
# 2) if NetworkManager is running set INTERNET_IFACE as unmanaged
|
||||
# 3) create BRIDGE_IFACE and add INTERNET_IFACE to it
|
||||
# 4) set the previously saved IPs and route table to BRIDGE_IFACE
|
||||
#
|
||||
# we need the above because BRIDGE_IFACE is the master interface from now on
|
||||
# and it must know where is connected, otherwise connection is lost.
|
||||
ip link set dev ${BRIDGE_IFACE} up || die
|
||||
if ! is_bridge_interface $INTERNET_IFACE; then
|
||||
echo -n "Create a bridge interface... "
|
||||
OLD_IFS="$IFS"
|
||||
IFS=$'\n'
|
||||
|
||||
ip addr show $INTERNET_IFACE | grep -E '[[:blank:]]+inet ' | while read x; do
|
||||
IPADDR=$(echo $x | sed 's/inet \([^ ]*\).*/\1/')
|
||||
BRDADDR=
|
||||
if [[ $x == *\ brd\ * ]]; then
|
||||
BRDADDR=$(echo $x | sed 's/.* brd \([^ ]*\).*/\1/')
|
||||
fi
|
||||
if [[ -n "$BRDADDR" ]]; then
|
||||
ip addr add $IPADDR broadcast $BRDADDR dev $BRIDGE_IFACE || die
|
||||
else
|
||||
ip addr add $IPADDR dev $BRIDGE_IFACE || die
|
||||
IP_ADDRS=( $(ip addr show $INTERNET_IFACE | grep -A 1 -E 'inet[[:blank:]]' | paste - -) )
|
||||
ROUTE_ADDRS=( $(ip route show dev $INTERNET_IFACE) )
|
||||
|
||||
IFS="$OLD_IFS"
|
||||
|
||||
if networkmanager_is_running; then
|
||||
networkmanager_add_unmanaged $INTERNET_IFACE
|
||||
networkmanager_wait_until_unmanaged $INTERNET_IFACE
|
||||
fi
|
||||
|
||||
brctl addbr $BRIDGE_IFACE || die
|
||||
brctl setfd $BRIDGE_IFACE 0
|
||||
brctl addif $BRIDGE_IFACE $INTERNET_IFACE || die
|
||||
ip link set dev $BRIDGE_IFACE up || die
|
||||
ip link set dev $INTERNET_IFACE up || die
|
||||
|
||||
ip addr flush $INTERNET_IFACE
|
||||
for x in "${IP_ADDRS[@]}"; do
|
||||
x="${x/inet/}"
|
||||
x="${x/secondary/}"
|
||||
x="${x/dynamic/}"
|
||||
x=$(echo $x | sed 's/\([0-9]\)sec/\1/g')
|
||||
x="${x/${INTERNET_IFACE}/}"
|
||||
ip addr add $x dev $BRIDGE_IFACE || die
|
||||
done
|
||||
|
||||
# remove any existing entries that were added from 'ip addr add'
|
||||
ip route flush dev $BRIDGE_IFACE || die
|
||||
ip route flush dev $INTERNET_IFACE
|
||||
ip route flush dev $BRIDGE_IFACE
|
||||
|
||||
# we must first add the entries that specify the subnets and then the
|
||||
# gateway entry, otherwise 'ip addr add' will return an error
|
||||
ip route show dev $INTERNET_IFACE | grep -v -E '^default' | while read x; do
|
||||
ip route del $x dev $INTERNET_IFACE || die
|
||||
for x in "${ROUTE_ADDRS[@]}"; do
|
||||
[[ "$x" == default* ]] && continue
|
||||
ip route add $x dev $BRIDGE_IFACE || die
|
||||
done
|
||||
|
||||
ip route show dev $INTERNET_IFACE | grep -E '^default' | while read x; do
|
||||
ip route del $x dev $INTERNET_IFACE || die
|
||||
for x in "${ROUTE_ADDRS[@]}"; do
|
||||
[[ "$x" != default* ]] && continue
|
||||
ip route add $x dev $BRIDGE_IFACE || die
|
||||
done
|
||||
|
||||
echo "$BRIDGE_IFACE created."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "No Internet sharing"
|
||||
|
Loading…
Reference in New Issue
Block a user