diff --git a/luci-app-omr-dscp/Makefile b/luci-app-omr-dscp/Makefile index 152e91cf0..b099678d6 100644 --- a/luci-app-omr-dscp/Makefile +++ b/luci-app-omr-dscp/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI Interface to DSCP - +LUCI_DEPENDS:=+LINUX_5_4:omr-dscp +!LINUX_5_4:omr-dscp-nft PKG_LICENSE:=GPLv3 #include ../luci/luci.mk diff --git a/omr-dscp/Makefile b/omr-dscp/Makefile new file mode 100644 index 000000000..58d60117f --- /dev/null +++ b/omr-dscp/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (C) 2018-2023 Ycarus (Yannick Chabanois) for OpenMPTCProuter +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=omr-dscp +PKG_VERSION:=0.1 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) +SECTION:=net +CATEGORY:=Network +DEPENDS:= +dnsmasq-full +LINUX_5_4:iptables +LINUX_5_4:iptables-mod-extra +LINUX_5_4:ipset +TITLE:=OMR-DSCP +endef + +define Package/$(PKG_NAME)-nft +SECTION:=net +CATEGORY:=Network +DEPENDS:= +dnsmasq-full +TITLE:=OMR-DSCP nft +endef + +define Package/$(PKG_NAME)/description +OMR-ByPass +endef + +define Package/$(PKG_NAME)-nft/description +OMR-ByPass nft support +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(CP) ./files/* $(1)/ + rm -f $(1)/etc/init.d/omr-dscp-nft +endef + +define Package/$(PKG_NAME)-nft/install + $(CP) ./files/* $(1)/ + mv $(1)/etc/init.d/omr-dscp-nft $(1)/etc/init.d/omr-dscp +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) +$(eval $(call BuildPackage,$(PKG_NAME)-nft)) diff --git a/luci-app-omr-dscp/root/etc/config/dscp b/omr-dscp/files/etc/config/dscp similarity index 100% rename from luci-app-omr-dscp/root/etc/config/dscp rename to omr-dscp/files/etc/config/dscp diff --git a/luci-app-omr-dscp/root/etc/init.d/omr-dscp b/omr-dscp/files/etc/init.d/omr-dscp similarity index 98% rename from luci-app-omr-dscp/root/etc/init.d/omr-dscp rename to omr-dscp/files/etc/init.d/omr-dscp index bed7c3bad..d5b7467c0 100755 --- a/luci-app-omr-dscp/root/etc/init.d/omr-dscp +++ b/omr-dscp/files/etc/init.d/omr-dscp @@ -11,9 +11,9 @@ USE_PROCD=1 # shellcheck disable=SC1091 . /lib/functions.sh -if [ -f /usr/sbin/iptables-legacy ]; then - IPTABLES="/usr/sbin/iptables-legacy" - IP6TABLES="/usr/sbin/ip6tables-legacy" +if [ -e /usr/sbin/iptables-nft ]; then + IPTABLES="/usr/sbin/iptables-nft" + IP6TABLES="/usr/sbin/ip6tables-nft" else IPTABLES="/usr/sbin/iptables" IP6TABLES="/usr/sbin/ip6tables" diff --git a/omr-dscp/files/etc/init.d/omr-dscp-nft b/omr-dscp/files/etc/init.d/omr-dscp-nft new file mode 100755 index 000000000..689136171 --- /dev/null +++ b/omr-dscp/files/etc/init.d/omr-dscp-nft @@ -0,0 +1,183 @@ +#!/bin/sh /etc/rc.common +# vim: set noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 : + +# shellcheck disable=SC2034 +START=90 +# shellcheck disable=SC2034 +STOP=10 +# shellcheck disable=SC2034 +USE_PROCD=1 + +# shellcheck disable=SC1091 +. /lib/functions.sh + +# Get the lan interface name +lan_device= +config_load network +config_get lan_device lan ifname + +#config_load dscp + +_add_dscp_domain() { + domain=""; config_get domain "$1" name "" + class=""; config_get class "$1" class "" + [ -n "$domain" ] && [ -n "$class" ] && [ -z "$(uci -q get dhcp.omr_dscp-$class.domain | grep $domain)" ] && { + uci -q batch <<-EOF + add_list dhcp.omr_dscp_$class.domain="$domain" + commit dhcp + EOF + } +} + +_add_dscp_domains_rules() { + for class in cs0 cs1 cs2 cs3 cs4 cs5 cs6 cs7 ef; do + uci -q batch <<-EOF + set dhcp.omr_dscp_${class}=ipset + add_list dhcp.omr_dscp_${class}.name="omr_dscp_${class}_4" + add_list dhcp.omr_dscp_${class}.name="omr_dscp_${class}_6" + commit dhcp + set firewall.omr_dscp_${class}_4=ipset + set firewall.omr_dscp_${class}_4.name="omr_dscp_${class}_4" + set firewall.omr_dscp_${class}_4.match='dest_ip" + set firewall.omr_dscp_${class}_6=ipset + set firewall.omr_dscp_${class}_6.name="omr_dscp_${class}_6" + set firewall.omr_dscp_${class}_6.match='dest_ip" + set firewall.omr_dscp_${class}=rule + set firewall.omr_dscp_${class}.ipset="omr_dscp-${class}_4" + set firewall.omr_dscp_${class}.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')" + set firewall.omr_dscp_${class}.target='DSCP' + set firewall.omr_dscp_${class}.src='lan' + set firewall.omr_dscp_${class}.dest='*' + set firewall.omr6_dscp_${class}=rule + set firewall.omr6_dscp_${class}.ipset="omr_dscp-${class}_6" + set firewall.omr6_dscp_${class}.target='DSCP' + set firewall.omr6_dscp_${class}.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')" + set firewall.omr6_dscp_${class}.src='lan' + set firewall.omr6_dscp_${class}.dest='*' + commit firewall + EOF + done +} + +_add_dscp_rules() { + proto="" ; config_get proto "$1" proto all + src_ip="" ; config_get src_ip "$1" src_ip 0.0.0.0/0 + src_port="" ; config_get src_port "$1" src_port 0:65535 + dest_ip="" ; config_get dest_ip "$1" dest_ip 0.0.0.0/0 + dest_port="" ; config_get dest_port "$1" dest_port 0:65535 + class="" ; config_get class "$1" class + direction="" ; config_get direction "$1" direction "upload" + comment="" ; config_get comment "$1" comment "-" + + src_port="$(echo $src_port | sed 's/:/-/g')" + dest_port="$(echo $dest_port | sed 's/:/-/g')" + count=$((count + 1)) + [ "$proto" = "all" ] && proto="tcp udp" + case "$direction" in + upload|both) + # Apply the rule locally + uci -q batch <<-EOF + set firewall.omr_dscp_rule$count=rule + set firewall.omr_dscp_rule$count.name="omr_dscp_rule$count" + set firewall.omr_dscp_rule$count.target="DSCP" + set firewall.omr_dscp_rule$count.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')" + set firewall.omr_dscp_rule$count.src="lan" + set firewall.omr_dscp_rule$count.src_ip="$src_ip" + set firewall.omr_dscp_rule$count.dest_ip="$dest_ip" + set firewall.omr_dscp_rule$count.proto="$proto" + EOF + src_port="$(echo $src_port | sed 's/,/ /g')" + dest_port="$(echo $dest_port | sed 's/,/ /g')" + for port in $src_port; do + uci -q set firewall.omr_dscp_rule$count.src_port="$src_port" + done + for port in $src_port; do + uci -q set firewall.omr_dscp_rule$count.dest_port="$dest_port" + done + #_add_dscp_rule -m multiport --sports "$src_port" -m multiport --dports "$dest_port" + ;; + download|both) + ;; + esac + uci -q commit firewall + +} + + +_add_fwmark_chain() { + _ipt4 -N dscp_mark + _ipt4 -A PREROUTING -i "$lan_device" -j dscp_mark + _ipt4 -A POSTROUTING -j dscp_mark + _ipt6 -N dscp_mark + _ipt6 -A PREROUTING -i "$lan_device" -j dscp_mark + _ipt6 -A POSTROUTING -j dscp_mark + for class in cs4 cs5 cs6 cs7; do + # xtun (hex) -> 0x7874756e + _ipt4 -A dscp_mark \ + -m comment --comment "$class" \ + -m dscp --dscp-class "$class" \ + -j MARK --set-mark 0x7874756e + _ipt6 -A dscp_mark \ + -m comment --comment "$class" \ + -m dscp --dscp-class "$class" \ + -j MARK --set-mark 0x7874756e + done +} + +_remove_ipset_dnsmasq() { + [ -n "$(echo $1 | grep omr_dscp)" ] && uci -q delete dhcp.$1 +} + +_remove_rules() { + [ -n "$(echo $1 | grep omr_dscp)" ] && uci -q delete firewall.$1 +} + +_setup_tunnel() { + # Mark the packets to route through xtun0 + _add_fwmark_chain + # tun0: cs0 (default) + # xtun0: cs6 + _ipt4 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6 + _ipt6 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6 +} + +_cleanup() { + config_load dhcp + config_foreach _remove_ipset_dnsmasq + config_load firewall + config_foreach _remove_rules + uci -q commit dhcp + uci -q commit firewall + fw4 restart +} + +start_service() { + # Cleanup + _cleanup + + config_load dscp + # Add chains + _add_dscp_domains_rules + + # Setup the tunnels dscp / marks + #_setup_tunnel + + # Add rules base on the user configuration + count=0 + config_foreach _add_dscp_rules classify + config_foreach _add_dscp_domain domains + uci -q commit dhcp + fw4 restart +} + +stop_service() { + _cleanup +} + +reload_service() { + start +} + +service_triggers() { + procd_add_reload_trigger dscp +}