diff --git a/src/packages/fff/fff-layer3-vxmesh/Makefile b/src/packages/fff/fff-layer3-vxmesh/Makefile new file mode 100644 index 00000000..b748c198 --- /dev/null +++ b/src/packages/fff/fff-layer3-vxmesh/Makefile @@ -0,0 +1,29 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=fff-layer3-vxmesh +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/fff-layer3-vxmesh + SECTION:=base + CATEGORY:=Freifunk + TITLE:=Freifunk-Franken layer3 configuration for mesh via vxlan + URL:=http://www.freifunk-franken.de + DEPENDS:=+vxlan +endef + +define Package/fff-layer3-vxmesh/description + Adds a simple configuration to connect multple routers into one layer 2 + network via vxlan. +endef + +define Build/Compile + # nothing +endef + +define Package/fff-layer3-vxmesh/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,fff-layer3-vxmesh)) diff --git a/src/packages/fff/fff-layer3-vxmesh/files/etc/layer3.d/60-vxmesh b/src/packages/fff/fff-layer3-vxmesh/files/etc/layer3.d/60-vxmesh new file mode 100644 index 00000000..f6deeb80 --- /dev/null +++ b/src/packages/fff/fff-layer3-vxmesh/files/etc/layer3.d/60-vxmesh @@ -0,0 +1,161 @@ +#!/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 +} diff --git a/src/packages/fff/fff-layer3/Makefile b/src/packages/fff/fff-layer3/Makefile index ce3d2002..ea9183a7 100644 --- a/src/packages/fff/fff-layer3/Makefile +++ b/src/packages/fff/fff-layer3/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=fff-layer3 -PKG_RELEASE:=8 +PKG_RELEASE:=9 include $(INCLUDE_DIR)/package.mk @@ -36,7 +36,7 @@ define Package/fff-layer3 +mtr \ +tc \ +tcpdump \ - +vxlan + +fff-layer3-vxmesh endef define Package/fff-layer3/description diff --git a/src/packages/fff/fff-network/Makefile b/src/packages/fff/fff-network/Makefile index c97a816a..21af16af 100644 --- a/src/packages/fff/fff-network/Makefile +++ b/src/packages/fff/fff-network/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=fff-network -PKG_RELEASE:=31 +PKG_RELEASE:=32 include $(INCLUDE_DIR)/package.mk diff --git a/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh b/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh index 1d5cd832..98e9f92d 100755 --- a/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh +++ b/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh @@ -12,7 +12,7 @@ debug "Collecting information about connected clients" client_count=0 dataclient="" -CLIENT_INTERFACES=$(ls "/sys/class/net/$MESH_INTERFACE/brif" | grep -v '^bat') +CLIENT_INTERFACES=$(ls "/sys/class/net/$MESH_INTERFACE/brif" | grep -v -e '^bat' -v -e '^vxmesh') for clientif in ${CLIENT_INTERFACES}; do cc=$(bridge fdb show br "$MESH_INTERFACE" brport "$clientif" | grep -v self | grep -v permanent -c) client_count=$((client_count + cc))