forked from freifunk-franken/firmware
162 lines
3.8 KiB
Bash
162 lines
3.8 KiB
Bash
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
|
|
configure() {
|
|
local proto
|
|
local peerip
|
|
local otherpeers
|
|
local fields="
|
|
proto
|
|
port
|
|
vid
|
|
ttl
|
|
tos
|
|
mtu
|
|
macaddr
|
|
zone
|
|
rxcsum
|
|
txcsum
|
|
srcportmin
|
|
srcportmax
|
|
ageing
|
|
maxaddress
|
|
learning
|
|
rsc
|
|
proxy
|
|
l2miss
|
|
l3miss
|
|
gbp
|
|
tunlink
|
|
ipaddr
|
|
ip6addr
|
|
"
|
|
|
|
# cleanup old vxmesh and peer entries
|
|
uci -q delete network.vxmesh0
|
|
while uci -q delete network.@vxlan_peer[-1]; do :; done
|
|
|
|
# remove vxmesh0 entry from the client bridge and remove extra whitespaces
|
|
uci set network.client.ifname="$(uci -q get network.client.ifname | sed s/vxmesh0// | xargs)"
|
|
|
|
# reset dns to authorative
|
|
uci set dhcp.@dnsmasq[0].authoritative="1"
|
|
|
|
# check if a vxmesh config is available, otherwise quit
|
|
uci -q get gateway.@vxmesh[0] > /dev/null || return 0
|
|
|
|
# check if proto is set and probe for the correct peer ip
|
|
proto="$(uci -q get gateway.@vxmesh[0].proto)"
|
|
case "$proto" in
|
|
vxlan6)
|
|
peerip="$(uci -q get gateway.@gateway[0].peer_ip6)"
|
|
;;
|
|
vxlan)
|
|
peerip="$(uci -q get gateway.@gateway[0].peer_ip)"
|
|
;;
|
|
*)
|
|
echo "FATAL: vxmesh: option proto 'vxlan|vxlan6' required!"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
# vxmesh needs a separate peer ip as the ip on the client interface ip
|
|
# might be shared over multiple devices
|
|
[ -z "$peerip" ] && {
|
|
echo "FATAL: vxmesh: peer_ip|peer_ip6 required!"
|
|
return 1
|
|
}
|
|
|
|
uci -q get gateway.@vxmesh[0].vid > /dev/null || {
|
|
echo "FATAL: vxmesh: missing vid!"
|
|
return 1
|
|
}
|
|
|
|
# copy main options over
|
|
uci set network.vxmesh0="interface"
|
|
for option in $fields; do
|
|
uci set network.vxmesh0."$option"="$(uci -q get gateway.@vxmesh[0]."$option")"
|
|
done
|
|
|
|
# exclude peerip from the local router, so packets aren't sent to itself
|
|
otherpeers=$(uci -q get gateway.@vxmesh[0].peer | xargs -n1 | grep -v -e "$peerip")
|
|
|
|
for peer in $otherpeers; do
|
|
# create peer sections
|
|
if ! uci -q batch > /dev/null; then
|
|
echo "FATAL: vxmesh: error setting up peer!"
|
|
echo " peer: \"$peer\""
|
|
return 1
|
|
fi <<- EOF
|
|
add network vxlan_peer
|
|
set network.@vxlan_peer[-1].vxlan="vxmesh0"
|
|
set network.@vxlan_peer[-1].dst="$peer"
|
|
EOF
|
|
done
|
|
|
|
# learn routes to other peers only over babel interfaces with sufficient mtu
|
|
# - according to the rfc, vxlan packets must not be fragmented by a VTEP
|
|
# - the vxlan tunnel requires an mtu of 1570 when using ipv6
|
|
#
|
|
# -> to avoid sending too large packets over an interface with too small mtu,
|
|
# don't learn a route to a peer over that interface in the first place
|
|
babel_filter_mtu() {
|
|
local config="$1"
|
|
local otherpeers="$2"
|
|
local mtu
|
|
local ifname
|
|
|
|
case $config in
|
|
babelpeer*) ;;
|
|
wireguardpeer*) ;;
|
|
*) return ;;
|
|
esac
|
|
|
|
config_get mtu "$config" mtu
|
|
config_get ifname "$config" ifname
|
|
|
|
[ "${mtu:-0}" -ge "1570" ] && return
|
|
[ -z "${ifname}" ] && {
|
|
echo "WARNING: could not determine ifname from \"$config\""
|
|
return
|
|
}
|
|
for peer in $otherpeers; do
|
|
if ! uci -q batch > /dev/null; then
|
|
echo "FATAL: error adding babel filter for vxlan peer!"
|
|
echo " peer: \"$peer\""
|
|
echo " interface: \"$ifname\""
|
|
return 1
|
|
fi <<- EOF
|
|
add babeld filter
|
|
set babeld.@filter[-1].type="in"
|
|
set babeld.@filter[-1].ip="$peer"
|
|
set babeld.@filter[-1].if="$ifname"
|
|
set babeld.@filter[-1].addedbyautoconfig="true"
|
|
set babeld.@filter[-1].action="deny"
|
|
EOF
|
|
done
|
|
}
|
|
|
|
config_load network
|
|
config_foreach babel_filter_mtu interface "$otherpeers"
|
|
|
|
# with multiple routers in the network, there shouldn't be an authoritative
|
|
# dhcp server
|
|
uci set dhcp.@dnsmasq[0].authoritative="0"
|
|
|
|
# add the vxlan interface to the client bridge
|
|
uci set network.client.ifname="$(uci -q get network.client.ifname) vxmesh0"
|
|
}
|
|
|
|
apply() {
|
|
uci commit network
|
|
uci commit dhcp
|
|
uci commit babeld
|
|
}
|
|
|
|
revert() {
|
|
uci revert network
|
|
uci revert dhcp
|
|
uci revert babeld
|
|
}
|