Skip to content

ryansch/wifi-bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 

Repository files navigation

WiFi Bridge

I'm using this on a raspberry pi 3 running Ubuntu server to bridge an Ethernet-only OpenSprinker to my WiFi network.

This is a proxy-ARP pseudo-bridge (parprouted + dhcp-helper), not an L2 bridge. The pi routes between eth0 and wlan0.

Install

sudo apt install parprouted dhcp-helper avahi-daemon net-tools networkd-dispatcher arp-scan

/etc/netplan/60-wifi-bridge.yaml:

network:
  version: 2
  ethernets:
    renderer: networkd
    eth0:
      optional: true
      dhcp4: false

/etc/sysctl.d/local.conf:

net.ipv4.ip_forward=1
# best-effort: let eth0 learn the OpenSprinkler from its gratuitous ARP after DHCP.
# not sufficient on its own — see the priming timer below.
net.ipv4.conf.eth0.arp_accept=1

/etc/networkd-dispatcher/routable.d/50-wifi-bridge:

#!/bin/sh

if [ "$IFACE" = "wlan0" ]; then
  /sbin/ip link set wlan0 promisc on
  /sbin/ip addr add $(/sbin/ip addr show wlan0 | perl -wne 'm|^\s+inet (.*)/| && print $1')/32 dev eth0
  /usr/sbin/parprouted eth0 wlan0
fi

/etc/networkd-dispatcher/off.d/50-wifi-bridge:

#!/bin/sh

if [ "$IFACE" = "wlan0" ]; then
  /usr/bin/killall /usr/sbin/parprouted
  /sbin/ip link set eth0 down
fi

/usr/local/sbin/wifi-bridge-prime.sh:

#!/bin/sh
# Discover whatever the OpenSprinkler leased and keep its eth0 neighbor entry fresh.
# Logs only on change so the journal reads as events, not a 15s heartbeat.
state=/run/wifi-bridge-prime.state

subnet=$(/sbin/ip -o -f inet route show dev wlan0 scope link | awk '{print $1; exit}')
if [ -z "$subnet" ]; then
  echo "wlan0 has no connected subnet yet; skipping this cycle"
  exit 0
fi

hosts=$(/usr/sbin/arp-scan --interface=eth0 --retry=2 "$subnet" 2>&1 \
  | awk '/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[ \t]/ {print $1, $2}')

# The real work: refresh every run, silently.
echo "$hosts" | while read ip mac; do
  [ -n "$ip" ] && /sbin/ip neigh replace "$ip" lladdr "$mac" dev eth0 nud reachable
done

# The logging: only when what we found differs from last run.
if [ "$hosts" != "$(cat "$state" 2>/dev/null)" ]; then
  if [ -z "$hosts" ]; then
    echo "no hosts found on eth0 (subnet $subnet)"
  else
    echo "discovered on eth0: $hosts"
  fi
  printf '%s\n' "$hosts" > "$state"
fi

Make the hook scripts executable.

sudo chmod +x /etc/networkd-dispatcher/routable.d/50-wifi-bridge
sudo chmod +x /etc/networkd-dispatcher/off.d/50-wifi-bridge
sudo chmod +x /usr/local/sbin/wifi-bridge-prime.sh

/etc/systemd/system/wifi-bridge-prime.service:

[Unit]
Description=Prime parprouted neighbor table for OpenSprinkler
After=network-online.target

[Service]
Type=oneshot
ExecStart=-/usr/local/sbin/wifi-bridge-prime.sh

/etc/systemd/system/wifi-bridge-prime.timer:

[Unit]
Description=Periodically prime parprouted for OpenSprinkler

[Timer]
OnBootSec=30
OnUnitActiveSec=15

[Install]
WantedBy=timers.target

Edit /etc/default/dhcp-helper:

# relay dhcp requests as broadcast to wlan0
DHCPHELPER_OPTS="-b wlan0"

Edit /etc/avahi/avahi-daemon.conf:

[reflector]
enable-reflector=yes

Enable services:

sudo systemctl enable dhcp-helper
sudo systemctl enable wifi-bridge-prime.timer

Reboot!

Troubleshooting

ip neigh show dev eth0
ip route | grep eth0
journalctl -u wifi-bridge-prime.service

References

Inspired by: https://gist.github.com/Jiab77/76000284f8200da5019a232854421564

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors