diff --git a/net/tunneldigger-broker/Makefile b/net/tunneldigger-broker/Makefile new file mode 100644 index 0000000000000..42605406e4d7b --- /dev/null +++ b/net/tunneldigger-broker/Makefile @@ -0,0 +1,72 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=tunneldigger-broker +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://github.com/wlanslovenija/tunneldigger.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=4f72b30578ac3dbc5482f4a54054bf870355bdf5 +PKG_MIRROR_HASH:=e93b986b60475c16b0022ba4f5da981929cc3d6992c632f41264804912825473 + +PKG_MAINTAINER:=Nick Hainke +PKG_LICENSE:=AGPL-3.0 +PKG_LICENSE_FILES:=COPYING + +PKG_BUILD_DEPENDS:=python-cffi/host + +include ../../lang/python/pypi.mk +include $(INCLUDE_DIR)/package.mk +include ../../lang/python/python3-package.mk + +define Package/tunneldigger-broker + SECTION:=net + CATEGORY:=Network + DEPENDS:= \ + +ip-full \ + +kmod-l2tp \ + +kmod-l2tp-ip \ + +kmod-l2tp-eth \ + +kmod-sched \ + +libnetfilter-conntrack \ + +libnfnetlink \ + +libnl-tiny \ + +libpthread \ + +librt \ + +python3-cffi \ + +python3-ctypes \ + +python3-light \ + +python3-logging \ + +python3-six \ + +tc-full + TITLE:=Broker for L2TPv3 tunnels using tunneldigger + URL:=https://github.com/wlanslovenija/tunneldigger +endef + +define Package/tunneldigger-broker/description +Tunneldigger is a simple VPN tunneling solution based on the Linux kernel +support for L2TPv3 tunnels over UDP. This package contains the broker. +endef + +PYTHON3_PKG_SETUP_DIR:=broker +PYTHON3_PKG_WHEEL_VERSION:=0.4.0.dev1 + +define Py3Package/tunneldigger-broker/install + $(INSTALL_DIR) $(1)/lib/functions + $(INSTALL_DATA) ./files/tunneldigger.sh $(1)/lib/functions/tunneldigger.sh + $(INSTALL_DIR) $(1)/usr/lib/tunneldigger-broker/hooks + $(INSTALL_BIN) ./files/hook-setup $(1)/usr/lib/tunneldigger-broker/hooks/setup + $(INSTALL_BIN) ./files/hook-teardown $(1)/usr/lib/tunneldigger-broker/hooks/teardown + $(INSTALL_BIN) ./files/hook-mtu-changed $(1)/usr/lib/tunneldigger-broker/hooks/mtu-changed + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/tunneldigger-broker.init $(1)/etc/init.d/tunneldigger-broker + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/config.default $(1)/etc/config/tunneldigger-broker +endef + +define Package/tunneldigger-broker/conffiles +/etc/config/tunneldigger-broker +endef + +$(eval $(call Py3Package,tunneldigger-broker)) +$(eval $(call BuildPackage,tunneldigger-broker)) +$(eval $(call BuildPackage,tunneldigger-broker-src)) diff --git a/net/tunneldigger-broker/files/config.default b/net/tunneldigger-broker/files/config.default new file mode 100644 index 0000000000000..13bb45113ec93 --- /dev/null +++ b/net/tunneldigger-broker/files/config.default @@ -0,0 +1,18 @@ +config broker + list port '53' + list port '123' + list port '8942' + option interface 'loopback' + option max_cookies '1024' + option max_tunnels '1024' + option port_base '20000' + option tunnel_id_base '100' + option tunnel_timeout '60' + option pmtu '0' + option namespace 'production' + option connection_rate_limit '0.2' + +config log + option filename '/dev/null' + option verbosity 'INFO' + option log_ip_addresses '0' diff --git a/net/tunneldigger-broker/files/hook-mtu-changed b/net/tunneldigger-broker/files/hook-mtu-changed new file mode 100755 index 0000000000000..3cfc59a14e823 --- /dev/null +++ b/net/tunneldigger-broker/files/hook-mtu-changed @@ -0,0 +1,30 @@ +#!/bin/sh + +. /lib/functions/tunneldigger.sh + +TUNNEL_ID="$1" +INTERFACE="$3" +OLD_MTU="$4" +NEW_MTU="$5" + +# Get the bridge interface name for the old and new MTUs. +tunneldigger_get_bridge old_bridge "${OLD_MTU}" +tunneldigger_get_bridge new_bridge "${NEW_MTU}" + +if [ -z "$old_bridge" ]; then + echo "Unable to determine which bridge to use for MTU ${OLD_MTU}." + exit 1 +fi + +if [ -z "$new_bridge" ]; then + echo "Unable to determine which bridge to use for MTU ${NEW_MTU}." + exit 1 +fi + +# Remove interface from old bridge. +ip link set dev ${INTERFACE} nomaster +ip link set dev ${old_bridge} mtu ${OLD_MTU} + +# Change interface bridge and MTU. +ip link set dev ${INTERFACE} master ${new_bridge} mtu ${NEW_MTU} +ip link set dev ${new_bridge} mtu ${NEW_MTU} diff --git a/net/tunneldigger-broker/files/hook-setup b/net/tunneldigger-broker/files/hook-setup new file mode 100755 index 0000000000000..ed809ad6dc74e --- /dev/null +++ b/net/tunneldigger-broker/files/hook-setup @@ -0,0 +1,21 @@ +#!/bin/sh + +. /lib/functions/tunneldigger.sh + +TUNNEL_ID="$1" +INTERFACE="$3" +MTU="$4" + +# Get the bridge interface name for this MTU. +tunneldigger_get_bridge bridge "${MTU}" +if [ -z "$bridge" ]; then + echo "Unable to determine which bridge to use for MTU ${MTU}." + exit 1 +fi + +# Disable IPv6 on this interface as it will be bridged. +echo 1 > /proc/sys/net/ipv6/conf/${INTERFACE}/disable_ipv6 +# Add the interface to the proper bridge and bring it up. +ip link set dev ${INTERFACE} master ${bridge} mtu ${MTU} up +# Ensure bridge MTU. +ip link set dev ${bridge} mtu ${MTU} diff --git a/net/tunneldigger-broker/files/hook-teardown b/net/tunneldigger-broker/files/hook-teardown new file mode 100755 index 0000000000000..6f41efee4ae0b --- /dev/null +++ b/net/tunneldigger-broker/files/hook-teardown @@ -0,0 +1,8 @@ +#!/bin/sh + +TUNNEL_ID="$1" +INTERFACE="$3" +MTU="$4" + +# Remove interface from the bridge. +ip link set dev ${INTERFACE} nomaster diff --git a/net/tunneldigger-broker/files/tunneldigger-broker.init b/net/tunneldigger-broker/files/tunneldigger-broker.init new file mode 100755 index 0000000000000..5c0888b0450b2 --- /dev/null +++ b/net/tunneldigger-broker/files/tunneldigger-broker.init @@ -0,0 +1,104 @@ +#!/bin/sh /etc/rc.common + +. $IPKG_INSTROOT/lib/functions/network.sh + +START=90 +USE_PROCD=1 +NAME=tunneldigger-broker + +PIDPATH=/var/run +CONFIGFILE=/var/etc/tunneldigger-broker.cfg +HOOKPATH=/usr/lib/tunneldigger-broker/hooks + +missing() { + echo "Not starting tunneldigger-broker - missing $1" >&2 + exit 1 +} + +cfg_append() { + local value="$1" + echo "$value" >> $CONFIGFILE +} + +cfg_append_section() { + local name="$1" + cfg_append "[${name}]" +} + +cfg_append_kv() { + local key="$1" + local value="$2" + cfg_append "${key}=${value}" +} + +cfg_append_option() { + local cfg="$1" + local option="$2" + local key="$3" + config_get value "$cfg" "${option}" + [ -z "${value}" ] && missing ${option} + cfg_append_kv "${key}" "${value}" +} + +parse_broker() { + local section="$1" + cfg_append_section broker + config_get interface "$section" interface + + [ ! -z "${interface}" ] && { + # Resolve logical interface name. + unset _interface address + network_get_device _interface "${interface}" || _interface="${interface}" + cfg_append_kv interface "${_interface}" + network_get_ipaddr address "${interface}" + cfg_append_kv address "${address}" + } + + OPTIONS="max_cookies max_tunnels port_base tunnel_id_base tunnel_timeout namespace connection_rate_limit pmtu" + for option in ${OPTIONS}; do + cfg_append_option "$section" "${option}" "${option}" + done + + config_get port "$section" port + cfg_append_kv "port" "${port// /,}" + + cfg_append_section hooks + cfg_append_kv "session.up" "${HOOKPATH}/setup" + cfg_append_kv "session.pre-down" "${HOOKPATH}/teardown" + cfg_append_kv "session.mtu-changed" "${HOOKPATH}/mtu-changed" +} + +parse_log() { + local section="$1" + cfg_append_section log + + OPTIONS="filename verbosity" + for option in ${OPTIONS}; do + cfg_append_option "$section" "${option}" "${option}" + done + + config_get_bool log_ip_addresses "$section" log_ip_addresses 1 + if [ "${log_ip_addresses}" -eq 1 ]; then + cfg_append_kv "log_ip_addresses" "true" + else + cfg_append_kv "log_ip_addresses" "false" + fi +} + +start_service() { + # Prepare the configuration file from UCI settings. + rm -f ${CONFIGFILE} + config_load tunneldigger-broker + config_foreach parse_broker broker + config_foreach parse_log log + + # Start the service using procd. + procd_open_instance + procd_set_param command "/usr/bin/python" + procd_append_param command -m tunneldigger_broker.main + procd_append_param command "${CONFIGFILE}" + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_close_instance +} diff --git a/net/tunneldigger-broker/files/tunneldigger.sh b/net/tunneldigger-broker/files/tunneldigger.sh new file mode 100644 index 0000000000000..68b323f3143d1 --- /dev/null +++ b/net/tunneldigger-broker/files/tunneldigger.sh @@ -0,0 +1,39 @@ +. /lib/functions.sh +. /lib/functions/network.sh + +tunneldigger_get_bridge() { + local variable="$1" + local mtu="$2" + + # Overwrite the destination variable. + unset $variable + + # Discover the configured bridge. + unset _td_bridge + _td_bridge="" + config_cb() { + local cfg="$CONFIG_SECTION" + config_get configname "$cfg" TYPE + if [ "$configname" != "bridge" ]; then + return + fi + + config_get cfg_mtu "$cfg" mtu + config_get interface "$cfg" interface + + if [ "$cfg_mtu" != "$mtu" ]; then + return + fi + + _td_bridge="$interface" + } + + config_load tunneldigger-broker + reset_cb + if [ -z "$_td_bridge" ]; then + return + fi + + eval $variable=$_td_bridge + # network_get_device $variable $_td_bridge +}