arp proxy: add hotplug
This commit is contained in:
parent
9ad732c123
commit
a7396a23e4
|
@ -6,7 +6,7 @@ After=basic.target network.target
|
|||
|
||||
[Service]
|
||||
SyslogIdentifier=wlan2eth
|
||||
ExecStart=/bin/bash /opt/wlan2eth/bridge/nat/wlan2eth.sh
|
||||
ExecStart=/bin/bash /opt/wlan2eth/bridge/nat/run-bridge-nat.sh
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
This bridge is a lot simpler than the NAT version. Just plug your client(s) into the bridge and it should just work.
|
||||
|
||||
Make sure to use a hub (NOT a switch) if you have more than one bridged client. A switch doesn't let the bridge see all the traffic from the clients.
|
||||
I've heard people say that a hub (NOT a switch) is required when bridging more than one client (likely due to the fact that a switch doesn't let the bridge see all the traffic from the clients). But I don't think this matters.
|
||||
|
||||
Also, `parprouted` has a bug where it prints its error messages as raw Ethernet frames over the network. If something isn't working, open Wireshark and restart `parprouted`. Look for white "Ethernet II" frames.
|
||||
Also, `parprouted` has a bug where it prints its log messages as raw Ethernet frames over the network. If something isn't working, open Wireshark and restart `parprouted`. Look for white "Ethernet II" frames.
|
||||
|
|
|
@ -157,38 +157,47 @@ grep '^enable-reflector=yes$' /etc/avahi/avahi-daemon.conf || {
|
|||
|
||||
cat > /etc/systemd/system/parprouted.service <<EOF
|
||||
[Unit]
|
||||
Description=proxy arp routing service
|
||||
Description=Parprouted ARP Routing
|
||||
Documentation=https://raspberrypi.stackexchange.com/q/88954/79866
|
||||
#Requires=sys-subsystem-net-devices-$WLAN_IFACE.device dhcpcd.service
|
||||
#After=sys-subsystem-net-devices-$WLAN_IFACE.device dhcpcd.service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
# Restart until $WLAN_IFACE gained carrier
|
||||
Type=simple
|
||||
# Restart the service until $WLAN_IFACE gained carrier
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
TimeoutStartSec=30
|
||||
# clone the dhcp-allocated IP to $ETH_IFACE so dhcp-helper will relay for the correct subnet
|
||||
ExecStartPre=/bin/bash -c '/sbin/ip addr add \$(/sbin/ip -4 -br addr show $WLAN_IFACE | /bin/grep -Po "\\\d+\\\.\\\d+\\\.\\\d+\\\.\\\d+")/32 dev $ETH_IFACE'
|
||||
ExecStartPre=/sbin/ip link set dev $ETH_IFACE down
|
||||
ExecStartPre=/sbin/ip link set dev $ETH_IFACE up
|
||||
ExecStartPre=/sbin/ip link set $WLAN_IFACE promisc on
|
||||
ExecStart=-/usr/sbin/parprouted $ETH_IFACE $WLAN_IFACE
|
||||
ExecStopPost=/sbin/ip link set $WLAN_IFACE promisc off
|
||||
ExecStopPost=/sbin/ip link set dev $ETH_IFACE down
|
||||
ExecStopPost=/sbin/ip link set dev $ETH_IFACE up
|
||||
ExecStopPost=/bin/bash -c '/sbin/ip addr del \$(/sbin/ip -4 -br addr show $WLAN_IFACE | /bin/grep -Po "\\\d+\\\.\\\d+\\\.\\\d+\\\.\\\d+")/32 dev $ETH_IFACE'
|
||||
|
||||
ExecStart="$DIR/parprouted.sh"
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=wpa_supplicant.service
|
||||
EOF
|
||||
|
||||
cat > /etc/systemd/system/parprouted-monitor.service <<EOF
|
||||
[Unit]
|
||||
Description=Parprouted ARP Routing Hotplug
|
||||
|
||||
[Service]
|
||||
ExecStart="$DIR/parprouted-monitor.sh"
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
ip link set dev $ETH_IFACE down
|
||||
ip link set dev $ETH_IFACE up
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now parprouted dhcp-helper
|
||||
systemctl restart parprouted dhcp-helper
|
||||
systemctl enable --now parprouted dhcp-helper parprouted-monitor
|
||||
systemctl restart parprouted dhcp-helper parprouted-monitor
|
||||
|
||||
systemctl status --no-pager dhcp-helper
|
||||
systemctl status --no-pager parprouted
|
||||
systemctl status --no-pager parprouted-monitor
|
||||
systemctl status --no-pager parprouted.service
|
||||
|
||||
echo -e "\n==============\nDone!\nNow reboot!"
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
SOURCE=${BASH_SOURCE[0]}
|
||||
while [ -L "$SOURCE" ]; do
|
||||
DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)
|
||||
SOURCE=$(readlink "$SOURCE")
|
||||
[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE
|
||||
done
|
||||
DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)
|
||||
|
||||
if [[ -f "$DIR/../../config/arp-config.sh" ]]; then
|
||||
. "$DIR/../../config/arp-config.sh"
|
||||
else
|
||||
echo "$DIR/../../config/arp-config.sh missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo 'This script must be run as root.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "/sys/class/net/$ETH_IFACE/operstate" ]; then
|
||||
echo "ERROR: $ETH_IFACE does not exist?"
|
||||
echo "File does not exist: /sys/class/net/$ETH_IFACE/operstate"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
while true; do
|
||||
if ethtool $ETH_IFACE | grep -q "Link detected: yes"; then
|
||||
systemctl --quiet is-active parprouted || systemctl --quiet start parprouted
|
||||
else
|
||||
systemctl --quiet is-active parprouted && systemctl --quiet stop parprouted
|
||||
fi
|
||||
sleep 1
|
||||
done
|
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
SOURCE=${BASH_SOURCE[0]}
|
||||
while [ -L "$SOURCE" ]; do
|
||||
DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)
|
||||
SOURCE=$(readlink "$SOURCE")
|
||||
[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE
|
||||
done
|
||||
DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)
|
||||
|
||||
if [[ -f "$DIR/../../config/arp-config.sh" ]]; then
|
||||
. "$DIR/../../config/arp-config.sh"
|
||||
else
|
||||
echo "$DIR/../../config/arp-config.sh missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo 'This script must be run as root.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "/sys/class/net/$ETH_IFACE/operstate" ]; then
|
||||
echo "ERROR: $ETH_IFACE does not exist?"
|
||||
echo "File does not exist: /sys/class/net/$ETH_IFACE/operstate"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EXITING=0
|
||||
|
||||
function ctrl_c() {
|
||||
# Reset the interfaces
|
||||
if [ $EXITING -eq 0 ]; then # prevent running this multiple times
|
||||
EXITING=1
|
||||
echo "Cleaning up..."
|
||||
ip link set $WLAN_IFACE promisc off
|
||||
ip link set dev $ETH_IFACE down
|
||||
ip link set dev $ETH_IFACE up
|
||||
ip addr del $(/sbin/ip -4 -br addr show $WLAN_IFACE | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev $ETH_IFACE
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
while ! ethtool $ETH_IFACE | grep -q "Link detected: yes"; do
|
||||
echo "Waiting for wired interface $ETH_IFACE to come up..."
|
||||
sleep 10s
|
||||
done
|
||||
|
||||
|
||||
# Clone our DCHP-allocated IP from wlan0 to eth0 so dhcp-helper will relay for the correct subnet
|
||||
echo "Initializing..."
|
||||
trap ctrl_c SIGINT
|
||||
trap ctrl_c SIGTERM
|
||||
ip addr add $(/sbin/ip -4 -br addr show $WLAN_IFACE | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev $ETH_IFACE
|
||||
ip link set $WLAN_IFACE promisc on
|
||||
|
||||
while true; do
|
||||
WLAN_IFACE_IP=$(ip -4 -br addr show $WLAN_IFACE | grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")
|
||||
if [ -n "${WLAN_IFACE_IP}" ]; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting for wireless interface $WLAN_IFACE to get an IP..."
|
||||
sleep 10s
|
||||
done
|
||||
|
||||
parprouted -d $ETH_IFACE $WLAN_IFACE
|
|
@ -22,7 +22,7 @@ func (c ClientInfo) StringMAC() string {
|
|||
var bridgedClients = make(map[string]ClientInfo)
|
||||
var bridgedClientsLock sync.Mutex
|
||||
|
||||
func AddBridgedClient(ip net.IP, mac net.HardwareAddr, eth0MAC, wlan0MAC net.HardwareAddr, eth0 string) {
|
||||
func AddBridgedClient(ip net.IP, mac, eth0MAC, wlan0MAC net.HardwareAddr, eth0 string) {
|
||||
log := logger.GetLogger()
|
||||
|
||||
// Ignore the wlan0 MAC address
|
||||
|
@ -30,18 +30,22 @@ func AddBridgedClient(ip net.IP, mac net.HardwareAddr, eth0MAC, wlan0MAC net.Har
|
|||
log.Debugf("Not adding client IP (wlan0): %s", ip)
|
||||
return
|
||||
}
|
||||
// Ignore the eth0 MAC address
|
||||
if bytes.Equal(mac, eth0MAC) {
|
||||
log.Debugf("Not adding client IP (eth0): %s", ip)
|
||||
return
|
||||
}
|
||||
// Sometimes this IP shows up
|
||||
if ip.String() == "0.0.0.0" {
|
||||
log.Debug("Not adding client IP: 0.0.0.0")
|
||||
return
|
||||
}
|
||||
// Windows clients will self-assign an IP
|
||||
if isAPIPA(ip) {
|
||||
log.Debugf("Not adding client IP (APIPA): %s", ip)
|
||||
return
|
||||
}
|
||||
// Exclude other wierdness
|
||||
if isExcluded(ip) {
|
||||
log.Debugf("Not adding client IP (excluded): %s", ip)
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue