#!/bin/sh # Install iptables rules IP_RULE="" init_iptables_rule() { IP_RULE="" } iptables_filter_intf() { IP_RULE="$IP_RULE -i $1" } iptables_filter_proto() { IP_RULE="$IP_RULE -p $1" } iptables_filter_ip_src() { IP_RULE="$IP_RULE -s $1" } iptables_filter_ip_dest() { IP_RULE="$IP_RULE -d $1" } iptables_filter_port_dest() { IP_RULE="$IP_RULE --dport $1" } iptables_filter_port_src() { IP_RULE="$IP_RULE --sport $1" } iptables_filter_port_dest_range() { IP_RULE="$IP_RULE --dport $1:$2" } iptables_filter_port_src_range() { IP_RULE="$IP_RULE --sport $1:$2" } iptables_filter_dscp_filter() { IP_RULE="$IP_RULE -m dscp --dscp $1" } iptables_filter_ip_len_min() { IP_RULE="$IP_RULE -m length --length $1" } iptables_filter_ip_len_max() { IP_RULE="$IP_RULE:$1" } iptables_set_dscp_mark() { IP_RULE="$IP_RULE -j DSCP --set-dscp $1" } append_rule_to_mangle_table() { if [ "$2" == 4 ]; then echo "iptables -w -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.iptables elif [ "$2" == 6 ]; then echo "ip6tables -w -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.ip6tables elif [ "$2" == 1 ]; then echo "iptables -w -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.iptables echo "ip6tables -w -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.ip6tables fi } handle_iptables_rules() { local cid="$1" local ip_version=0 local is_l3_rule=0 init_iptables_rule config_get proto "$cid" "proto" config_get traffic_class "$cid" "traffic_class" config_get dscp_mark "$cid" "dscp_mark" config_get dscp_filter "$cid" "dscp_filter" config_get dest_port "$cid" "dest_port" config_get dest_port_range "$cid" "dest_port_range" config_get src_port "$cid" "src_port" config_get src_port_range "$cid" "src_port_range" config_get dest_ip "$cid" "dest_ip" config_get src_ip "$cid" "src_ip" config_get ip_len_min "$cid" "ip_len_min" config_get ip_len_max "$cid" "ip_len_max" config_get ifname "$cid" "ifname" #check version of ip case $src_ip$dest_ip in *.*) ip_version=4 ;; *:*) ip_version=6 ;; *) ip_version=1 #ip address not used esac #filter interface if [ -n "$ifname" ]; then if [ "$ifname" != "lo" ]; then iptables_filter_intf "$ifname" fi fi # filter proto if [ -n "$proto" ]; then iptables_filter_proto "$proto" is_l3_rule=1 fi #filter src. ip if [ -n "$src_ip" ]; then iptables_filter_ip_src "$src_ip" is_l3_rule=1 fi #filter dest. ip if [ -n "$dest_ip" ]; then iptables_filter_ip_dest "$dest_ip" is_l3_rule=1 fi #filter dest. port if [ -n "$dest_port" ] && [ -z "$dest_port_range" ]; then iptables_filter_port_dest "$dest_port" is_l3_rule=1 fi #filter src. port if [ -n "$src_port" ] && [ -z "$src_port_range" ]; then iptables_filter_port_src "$src_port" is_l3_rule=1 fi #filter dest. port range if [ -n "$dest_port" ] && [ -n "$dest_port_range" ]; then if [ "$dest_port_range" == "-1" ] ; then dest_port_range="$dest_port" fi iptables_filter_port_dest_range "$dest_port" "$dest_port_range" is_l3_rule=1 fi #filter src. port range if [ -n "$src_port" ] && [ -n "$src_port_range" ]; then if [ "$src_port_range" == "-1" ] ; then src_port_range="$src_port" fi iptables_filter_port_src_range "$src_port" "$src_port_range" is_l3_rule=1 fi #filter dscp if [ -n "$dscp_filter" ]; then iptables_filter_dscp_filter "$dscp_filter" is_l3_rule=1 fi #filter min. IP packet len. if [ -n "$ip_len_min" ]; then iptables_filter_ip_len_min "$ip_len_min" is_l3_rule=1 fi #filter max. IP packet len. if [ -n "$ip_len_max" ]; then iptables_filter_ip_len_max "$ip_len_max" is_l3_rule=1 fi if [ -z "$is_l3_rule" ] || [ "$is_l3_rule" -eq 0 ] ; then return fi #set dscp mark [ -n "$dscp_mark" ] && iptables_set_dscp_mark "$dscp_mark" #set packet queue mark [ -n "$traffic_class" ] && iptables_set_traffic_class "$traffic_class" #write iptables rule for dscp marking [ -n "$IP_RULE" ] && [ -n "$dscp_mark" ] && append_rule_to_mangle_table "qos_forward" $ip_version if [ -n "$IP_RULE" ] && [ -n "$traffic_class" ]; then if [ "$ifname" == "lo" ]; then #write iptables rule for putting WAN directed internal packets in different queue append_rule_to_mangle_table "qos_output" $ip_version else #write iptables rule for putting WAN directed LAN packets in different queue append_rule_to_mangle_table "qos_prerouting" $ip_version fi fi } create_iptables_chains() { iptables -w -t mangle -N qos_forward ret=$? [ $ret -eq 0 ] && iptables -w -t mangle -I FORWARD -j qos_forward iptables -w -t mangle -N qos_prerouting ret=$? [ $ret -eq 0 ] && iptables -w -t mangle -I PREROUTING -j qos_prerouting iptables -w -t mangle -N qos_output ret=$? [ $ret -eq 0 ] && iptables -w -t mangle -I OUTPUT -j qos_output ip6tables -t mangle -N qos_forward ret=$? [ $ret -eq 0 ] && ip6tables -t mangle -I FORWARD -j qos_forward ip6tables -t mangle -N qos_prerouting ret=$? [ $ret -eq 0 ] && ip6tables -t mangle -I PREROUTING -j qos_prerouting ip6tables -t mangle -N qos_output ret=$? [ $ret -eq 0 ] && ip6tables -t mangle -I OUTPUT -j qos_output } flush_iptables_chains() { echo "iptables -w -t mangle -F qos_forward" > /tmp/qos/classify.iptables echo "iptables -w -t mangle -F qos_prerouting" >> /tmp/qos/classify.iptables echo "iptables -w -t mangle -F qos_output" >> /tmp/qos/classify.iptables echo "ip6tables -w -t mangle -F qos_forward" > /tmp/qos/classify.ip6tables echo "ip6tables -w -t mangle -F qos_prerouting" >> /tmp/qos/classify.ip6tables echo "ip6tables -w -t mangle -F qos_output" >> /tmp/qos/classify.ip6tables }