From 67083bb239fe66399e05f9b8a5945610eebfcd11 Mon Sep 17 00:00:00 2001 From: vdutta Date: Thu, 31 Jan 2019 14:06:13 +0530 Subject: [PATCH] Added easy_qos package for marking packets in mangle table --- easy-qos/Makefile | 31 +++++++ easy-qos/files/etc/config/easy_qos | 30 +++++++ easy-qos/files/etc/init.d/easy_qos | 139 +++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 easy-qos/Makefile create mode 100644 easy-qos/files/etc/config/easy_qos create mode 100755 easy-qos/files/etc/init.d/easy_qos diff --git a/easy-qos/Makefile b/easy-qos/Makefile new file mode 100644 index 000000000..775a90e8e --- /dev/null +++ b/easy-qos/Makefile @@ -0,0 +1,31 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=easy-qos +PKG_VERSION:=1.0 +PKG_RELEASE:=0 + +include $(INCLUDE_DIR)/package.mk + +define Package/easy-qos + SECTION:=net + CATEGORY:=Network + TITLE:=Easy QoS +endef + +define Package/easy-qos/description + This package contains Easy QoS utitie +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./files/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile +endef + +define Package/easy-qos/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,easy-qos)) diff --git a/easy-qos/files/etc/config/easy_qos b/easy-qos/files/etc/config/easy_qos new file mode 100644 index 000000000..f7a095ef4 --- /dev/null +++ b/easy-qos/files/etc/config/easy_qos @@ -0,0 +1,30 @@ +config rule + option priority "high" + option macaddr "12:34:56:78:9a:bc" + list port 22 + list port 53 + option comment "SSH, DNS" + # -j MARK --set-xmark 0x7/0x7 + +config rule + option priority "medium" + option macaddr "08:00:27:db:2a:31" + option proto "tcp" + list port 21 + list port 25 + list port 80 + option comment "FTP, SMTP, HTTP" + # -j MARK --set-xmark 0x5/0x5 + +config rule + option priority "normal" + option macaddr "1a:2b:3c:4d:5e:6f" + option comment "All Traffic" + # -j MARK --set-xmark 0x3/0x3 + +config rule + option priority "low" + option macaddr "6a:4b:2c:5d:1e:70" + list proto icmp + option comment "Ping" + # -j MARK --set-xmark 0x1/0x1 diff --git a/easy-qos/files/etc/init.d/easy_qos b/easy-qos/files/etc/init.d/easy_qos new file mode 100755 index 000000000..70e5c5d43 --- /dev/null +++ b/easy-qos/files/etc/init.d/easy_qos @@ -0,0 +1,139 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2015 inteno.org +# + +START=99 +USE_PROCD=1 + +log() { + echo "${@}"|logger -t easy_qos -p debug +} + +exec_log() { + ${@} + if [ "${?}" -ne 0 ]; then + log "Failed to create ${@}"; + fi +} + +get_priority() { + local prio=$(echo $1|tr [A-Z] [a-z]); + case "${prio}" in + "lowest") + echo 0;; + "low") + echo 1;; + "best") + echo 2;; + "normal") + echo 3;; + "video") + echo 4;; + "medium") + echo 5;; + "high") + echo 6;; + "highest") + echo 7;; + esac +} + +# Find the IP of a corresponding mac from arp table +get_ipaddress() { + local mac=${1}; + local ip=$(grep -i "${mac}" /proc/net/arp |awk '{ print $1}'); + if [ -z "${ip}" ]; then + log "Failed to get IP for ${mac}"; + fi + echo ${ip}; +} + +validate_rule_section() +{ + uci_validate_section easy_qos rule "${1}" \ + 'priority:string' \ + 'macaddr:string' \ + 'proto:string:none' \ + 'port:list(uinteger)' \ + 'comment:string:none' +} + +# Clear existing rules before applying new rules +clear_existing_rules() { + local rule=$(iptables -t mangle -S OUTPUT|grep -m 1 MARK |sed 's/-A/-D/1') + while [ -n "${rule}" ]; do + exec_log iptables -t mangle ${rule} + rule=$(iptables -t mangle -S OUTPUT|grep -m 1 MARK |sed 's/-A/-D/1') + done +} + +check_and_create() { + iptables -t mangle -C OUTPUT ${@} 2>/dev/null + # Create rule if not exists + if [ ${?} -ne 0 ]; then + exec_log iptables -t mangle -A OUTPUT ${@} + else + log "Rule exists for ${@}" + fi +} + +create_rule() { + local proto=$1; shift + local src_ip=$1; shift + local mark="0x$1/0x$1"; shift + local ports=$1; + local cmd=""; + + cmd="-j MARK --set-xmark ${mark}"; + if [ -n "${ports}" ]; then + cmd="--match multiport --dports ${ports} ${cmd}"; + fi + + if [ "${proto}" == "icmp" ]; then + cmd="-p icmp -m icmp --icmp-type 8 $cmd" + else + cmd="-p ${proto} -m ${proto} $cmd" + fi + cmd="-s ${src_ip} $cmd" + check_and_create ${cmd} +} + +manage_rule() { + local cfg="$1" + local priority macaddr proto port comment prio_num ip port_list + + validate_rule_section "${1}" || { + log "Validation of section failed" + return 1; + } + + prio_num=$(get_priority ${priority}) + ip=$(get_ipaddress ${macaddr}) + port_list=$(echo ${port}|sed 's/ /,/g') + + if [ -n "${ip}" -a -n "${prio_num}" ]; then + if [ "${proto}" == "none" ]; then + create_rule tcp ${ip} ${prio_num} ${port_list} + create_rule udp ${ip} ${prio_num} ${port_list} + else + create_rule ${proto} ${ip} ${prio_num} ${port_list} + fi + fi +} + +reload_service() { + clear_existing_rules + config_load easy_qos + config_foreach manage_rule rule +} + +start_service() { + reload_service + echo "Easy QoS installed">/dev/console; +} + +service_triggers() { + procd_add_reload_trigger "easy_qos" +} +