mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
qos: modularisation of qos code
This commit is contained in:
parent
8ff5a2870f
commit
920a7d0346
8 changed files with 583 additions and 1511 deletions
|
|
@ -1,97 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Install ebtables rules
|
# Install ebtables rules
|
||||||
|
|
||||||
BR_RULE=""
|
|
||||||
BR6_RULE=""
|
|
||||||
|
|
||||||
init_broute_rule() {
|
|
||||||
BR_RULE=""
|
|
||||||
BR6_RULE=""
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_src_if() {
|
|
||||||
BR_RULE="$BR_RULE --in-if $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_src_mac() {
|
|
||||||
BR_RULE="$BR_RULE --src $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_dst_mac() {
|
|
||||||
BR_RULE="$BR_RULE --dst $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_pcp() {
|
|
||||||
case "$BR_RULE" in
|
|
||||||
*proto*)
|
|
||||||
BR_RULE="$BR_RULE --vlan-prio $1"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
BR_RULE="$BR_RULE --proto 802_1Q --vlan-prio $1"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_ether_type() {
|
|
||||||
BR_RULE="$BR_RULE --proto $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_ether_type6() {
|
|
||||||
BR6_RULE="$BR6_RULE --proto IPv6"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_src_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip-src $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_dst_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip-dst $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_src_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip6-src $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_dst_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip6-dst $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ip_src_port() {
|
|
||||||
BR_RULE="$BR_RULE --ip-source-port $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ip_dst_port() {
|
|
||||||
BR_RULE="$BR_RULE --ip-destination-port $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_src_port() {
|
|
||||||
if [ -n "$BR6_RULE" ]; then
|
|
||||||
BR6_RULE="$BR6_RULE --ip6-source-port $1"
|
|
||||||
else
|
|
||||||
BR_RULE="$BR_RULE --ip6-source-port $1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_dst_port() {
|
|
||||||
if [ -n "$BR6_RULE" ]; then
|
|
||||||
BR6_RULE="$BR6_RULE --ip6-destination-port $1"
|
|
||||||
else
|
|
||||||
BR_RULE="$BR_RULE --ip6-destination-port $1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ip_protocol() {
|
|
||||||
BR_RULE="$BR_RULE --ip-proto $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_protocol() {
|
|
||||||
if [ -n "$BR6_RULE" ]; then
|
|
||||||
BR6_RULE="$BR6_RULE --ip6-proto $1"
|
|
||||||
else
|
|
||||||
BR_RULE="$BR_RULE --ip6-proto $1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_dscp() {
|
ebt_match_ipv6_dscp() {
|
||||||
if [ -n "$BR6_RULE" ]; then
|
if [ -n "$BR6_RULE" ]; then
|
||||||
BR6_RULE="$BR6_RULE --ip6-tclass $1"
|
BR6_RULE="$BR6_RULE --ip6-tclass $1"
|
||||||
|
|
@ -100,22 +9,6 @@ ebt_match_ipv6_dscp() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
broute_filter_on_vid() {
|
|
||||||
|
|
||||||
if [ -z "$1" ] || [ "$1" -lt 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$BR_RULE" in
|
|
||||||
*proto*)
|
|
||||||
BR_RULE="$BR_RULE --vlan-id $1"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
BR_RULE="$BR_RULE --proto 802_1Q --vlan-id $1"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_rule_set_traffic_class() {
|
broute_rule_set_traffic_class() {
|
||||||
BR_RULE="$BR_RULE -j mark --mark-or 0x${1}0 --mark-target ACCEPT"
|
BR_RULE="$BR_RULE -j mark --mark-or 0x${1}0 --mark-target ACCEPT"
|
||||||
if [ -n "$BR6_RULE" ]; then
|
if [ -n "$BR6_RULE" ]; then
|
||||||
|
|
@ -123,92 +16,6 @@ broute_rule_set_traffic_class() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
broute_append_rule() {
|
|
||||||
echo "ebtables -t broute -A qos $BR_RULE" >> /tmp/qos/classify.ebtables
|
|
||||||
if [ -n "$BR6_RULE" ]; then
|
|
||||||
echo "ebtables -t broute -A qos $BR6_RULE" >> /tmp/qos/classify.ebtables
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
set_ip_addr()
|
|
||||||
{
|
|
||||||
local cid="$1"
|
|
||||||
local match_src_ip_func="$2"
|
|
||||||
local match_dst_ip_func="$3"
|
|
||||||
|
|
||||||
config_get src_ip "$cid" "src_ip"
|
|
||||||
config_get dst_ip "$cid" "dest_ip"
|
|
||||||
|
|
||||||
if [ -n "$src_ip" ]; then
|
|
||||||
$match_src_ip_func "$src_ip"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$dst_ip" ]; then
|
|
||||||
$match_dst_ip_func "$dst_ip"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
set_ports()
|
|
||||||
{
|
|
||||||
local cid="$1"
|
|
||||||
local match_src_port_func="$2"
|
|
||||||
local match_dst_port_func="$3"
|
|
||||||
local src_port=""
|
|
||||||
local dst_port=""
|
|
||||||
local src_port_range=""
|
|
||||||
local dst_port_range=""
|
|
||||||
|
|
||||||
config_get src_port "$cid" "src_port"
|
|
||||||
config_get dst_port "$cid" "dest_port"
|
|
||||||
config_get src_port_range "$cid" "src_port_range"
|
|
||||||
config_get dst_port_range "$cid" "dest_port_range"
|
|
||||||
|
|
||||||
if [ -n "$src_port" ] && [ -n "$src_port_range" ] ; then
|
|
||||||
$match_src_port_func "$src_port:$src_port_range"
|
|
||||||
elif [ -n "$src_port" ] ; then
|
|
||||||
$match_src_port_func "$src_port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$dst_port" ] && [ -n "$dst_port_range" ] ; then
|
|
||||||
$match_dst_port_func "$dst_port:$dst_port_range"
|
|
||||||
elif [ -n "$dst_port" ] ; then
|
|
||||||
$match_dst_port_func "$dst_port"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol_string_to_num()
|
|
||||||
{
|
|
||||||
local value="-1"
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
*[0-9]*)
|
|
||||||
value="$1"
|
|
||||||
;;
|
|
||||||
TCP|tcp)
|
|
||||||
value=6
|
|
||||||
;;
|
|
||||||
UDP|udp)
|
|
||||||
value=17
|
|
||||||
;;
|
|
||||||
ICMP|icmp)
|
|
||||||
value=1
|
|
||||||
;;
|
|
||||||
ICMPv6|icmpv6)
|
|
||||||
value=58
|
|
||||||
;;
|
|
||||||
IGMP|igmp)
|
|
||||||
value=2
|
|
||||||
;;
|
|
||||||
SCTP|sctp)
|
|
||||||
value=132
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
value=-1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo $value
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_ipv4_rule_options()
|
broute_ipv4_rule_options()
|
||||||
{
|
{
|
||||||
local cid="$1"
|
local cid="$1"
|
||||||
|
|
@ -259,195 +66,3 @@ broute_ipv6_rule_options()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_ebtables_rules() {
|
|
||||||
local sid="$1"
|
|
||||||
local is_l2_rule=0
|
|
||||||
local src_dhcp_options=""
|
|
||||||
local dst_dhcp_options=""
|
|
||||||
local protocol=""
|
|
||||||
local ip_version=""
|
|
||||||
|
|
||||||
init_broute_rule
|
|
||||||
|
|
||||||
config_get src_if "$sid" "ifname"
|
|
||||||
config_get src_mac "$sid" "src_mac"
|
|
||||||
config_get dst_mac "$sid" "dst_mac"
|
|
||||||
config_get dscp_filter "$sid" "dscp_filter"
|
|
||||||
config_get pcp_check "$sid" "pcp_check"
|
|
||||||
config_get eth_type "$sid" "ethertype"
|
|
||||||
config_get vid "$sid" "vid_check"
|
|
||||||
config_get dhcp_type "$sid" "dhcp_type" # dhcpv4 or v6
|
|
||||||
config_get src_vcid "$sid" "src_vendor_class_id" # dhcp option 60
|
|
||||||
config_get dst_vcid "$sid" "dst_vendor_class_id" # dhcp option 60
|
|
||||||
config_get src_clid "$sid" "src_client_id" # dhcp option 61
|
|
||||||
config_get dst_clid "$sid" "dst_client_id" # dhcp option 61
|
|
||||||
config_get src_ucid "$sid" "src_user_class_id" # dhcp option 77
|
|
||||||
config_get dst_ucid "$sid" "dst_user_class_id" # dhcp option 77
|
|
||||||
config_get traffic_class "$sid" "traffic_class"
|
|
||||||
config_get protocol "$sid" "proto"
|
|
||||||
|
|
||||||
if [ -n "$src_if" ]; then
|
|
||||||
for interf in $(db -q get hw.board.ethernetPortOrder); do
|
|
||||||
if [ "$src_if" == "$interf" ]; then
|
|
||||||
src_if="$src_if+"
|
|
||||||
broute_filter_on_src_if "$src_if"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$src_mac" ]; then
|
|
||||||
broute_filter_on_src_mac "$src_mac"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$dst_mac" ]; then
|
|
||||||
broute_filter_on_dst_mac "$dst_mac"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$pcp_check" ]; then
|
|
||||||
broute_filter_on_pcp "$pcp_check"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$eth_type" ]; then
|
|
||||||
broute_filter_on_ether_type "$eth_type"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$vid" ]; then
|
|
||||||
broute_filter_on_vid "$vid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $eth_type in
|
|
||||||
IPv4|IPV4|0800)
|
|
||||||
ip_version=4
|
|
||||||
;;
|
|
||||||
IPv6|IPV6|86DD)
|
|
||||||
ip_version=6
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -z "$eth_type" ]; then
|
|
||||||
case "$src_ip$dst_ip" in
|
|
||||||
*.*)
|
|
||||||
ip_version=4
|
|
||||||
broute_filter_on_ether_type "IPv4"
|
|
||||||
;;
|
|
||||||
*:*)
|
|
||||||
ip_version=6
|
|
||||||
broute_filter_on_ether_type "IPv6"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -n "$protocol" ] || [ -n "$dscp_filter" ]; then
|
|
||||||
# Neither ether_type nor ip address used,
|
|
||||||
# ethertype is not configured by user, so install
|
|
||||||
# both proto IPv4 and IPv6 rule (version 1)
|
|
||||||
ip_version=1
|
|
||||||
BR6_RULE="$BR_RULE"
|
|
||||||
broute_filter_on_ether_type "IPv4"
|
|
||||||
broute_filter_on_ether_type6 "IPv6"
|
|
||||||
fi
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ "$ip_version" == "4" ] || [ "$ip_version" == "1" ]; then
|
|
||||||
broute_ipv4_rule_options "$sid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$ip_version" == "6" ] || [ "$ip_version" == "1" ]; then
|
|
||||||
broute_ipv6_rule_options "$sid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# first process options that will help figure our source mac address
|
|
||||||
# dhcp option for "vendor class id"
|
|
||||||
if [ -n "$src_vcid" ]; then
|
|
||||||
src_dhcp_options="$src_dhcp_options vcid=$src_vcid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "client id"
|
|
||||||
if [ -n "$src_clid" ]; then
|
|
||||||
src_dhcp_options="$src_dhcp_options clid=$src_clid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "user class id"
|
|
||||||
if [ -n "$src_ucid" ]; then
|
|
||||||
src_dhcp_options="$src_dhcp_options ucid=$src_ucid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if src mac is already a classification criteria, then it
|
|
||||||
# does not really make sense to add it as a criteria to
|
|
||||||
# filter packets again based on source mac
|
|
||||||
if [ -n "$src_dhcp_options" ] && [ -z "$src_mac" ]; then
|
|
||||||
comp="$(grep -i "$src_dhcp_options" /tmp/dhcp.client.options)"
|
|
||||||
if [ -n "$comp" ]; then
|
|
||||||
s_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
|
||||||
if [ -n "$s_mac_add" ]; then
|
|
||||||
broute_filter_on_src_mac "$s_mac_add"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Now process options that will help figure our destination mac address
|
|
||||||
# dhcp option for "vendor class id"
|
|
||||||
if [ -n "$dst_vcid" ]; then
|
|
||||||
dst_dhcp_options="$dst_dhcp_options vcid=$dst_vcid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "client id"
|
|
||||||
if [ -n "$dst_clid" ]; then
|
|
||||||
dst_dhcp_options="$dst_dhcp_options clid=$dst_clid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "user class id"
|
|
||||||
if [ -n "$dst_ucid" ]; then
|
|
||||||
dst_dhcp_options="$dst_dhcp_options ucid=$dst_ucid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if dst mac is already a classification criteria, then it
|
|
||||||
# does not really make sense to add it as a criteria to
|
|
||||||
# filter packets again based on destination mac
|
|
||||||
if [ -n "$dst_dhcp_options" ] && [ -z "$dst_mac" ] ; then
|
|
||||||
comp="$(grep -i "$dst_dhcp_options" /tmp/dhcp.client.options)"
|
|
||||||
if [ -n "$comp" ]; then
|
|
||||||
d_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
|
||||||
if [ -n "$d_mac_add" ]; then
|
|
||||||
broute_filter_on_dst_mac "$d_mac_add"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $is_l2_rule -eq 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -n "$traffic_class" ] && broute_rule_set_traffic_class "$traffic_class"
|
|
||||||
|
|
||||||
[ -n "$BR_RULE" ] && broute_append_rule
|
|
||||||
}
|
|
||||||
|
|
||||||
create_ebtables_chains() {
|
|
||||||
ebtables -t broute -N qos
|
|
||||||
ret=$?
|
|
||||||
if [ $ret -eq 0 ]; then
|
|
||||||
ebtables -t broute -I BROUTING -j qos
|
|
||||||
else
|
|
||||||
ebtables -t broute -D BROUTING -j qos
|
|
||||||
ebtables -t broute -I BROUTING -j qos
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_ebtables_chains() {
|
|
||||||
echo "ebtables -t broute -F qos" > /tmp/qos/classify.ebtables
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Set up or flush all chains
|
|
||||||
|
|
||||||
setup_qos() {
|
|
||||||
create_ebtables_chains
|
|
||||||
create_iptables_chains
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_chains() {
|
|
||||||
flush_ebtables_chains
|
|
||||||
flush_iptables_chains
|
|
||||||
}
|
|
||||||
|
|
@ -4,15 +4,15 @@
|
||||||
. /lib/functions.sh
|
. /lib/functions.sh
|
||||||
include /lib/ethernet
|
include /lib/ethernet
|
||||||
|
|
||||||
. /lib/qos/common/chains.sh
|
. /lib/qos/iptables.sh
|
||||||
. /lib/qos/common/chains.ebtables.sh
|
. /lib/qos/common/chains.ebtables.sh
|
||||||
. /lib/qos/common/chains.iptables.sh
|
. /lib/qos/ebtables.sh
|
||||||
. /lib/qos/common/classify.sh
|
. /lib/qos/ip_rule.sh
|
||||||
|
. /lib/qos/classify.sh
|
||||||
. /lib/qos/common/policer.sh
|
. /lib/qos/common/policer.sh
|
||||||
. /lib/qos/common/queue.sh
|
. /lib/qos/common/queue.sh
|
||||||
. /lib/qos/common/shaper.sh
|
. /lib/qos/common/shaper.sh
|
||||||
. /lib/qos/airoha.sh
|
. /lib/qos/airoha.sh
|
||||||
. /lib/qos/ip_rule.sh
|
|
||||||
|
|
||||||
configure_qos() {
|
configure_qos() {
|
||||||
# queue configuration is being done after shaper configuration,
|
# queue configuration is being done after shaper configuration,
|
||||||
|
|
@ -24,6 +24,9 @@ configure_qos() {
|
||||||
configure_queue
|
configure_queue
|
||||||
configure_policer
|
configure_policer
|
||||||
configure_classify
|
configure_classify
|
||||||
|
if [ -f "/tmp/qos/classify.ebtables" ]; then
|
||||||
|
sh /tmp/qos/classify.ebtables
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
reload_qos() {
|
reload_qos() {
|
||||||
|
|
@ -40,6 +43,9 @@ reload_qos() {
|
||||||
;;
|
;;
|
||||||
classify)
|
classify)
|
||||||
configure_classify
|
configure_classify
|
||||||
|
if [ -f "/tmp/qos/classify.ebtables" ]; then
|
||||||
|
sh /tmp/qos/classify.ebtables
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
policer)
|
policer)
|
||||||
configure_policer
|
configure_policer
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,14 @@ include /lib/ethernet
|
||||||
|
|
||||||
# include common code
|
# include common code
|
||||||
. /lib/qos/ip_rule.sh
|
. /lib/qos/ip_rule.sh
|
||||||
|
. /lib/qos/iptables.sh
|
||||||
IP_RULE=""
|
. /lib/qos/ebtables.sh
|
||||||
BR_RULE=""
|
. /lib/qos/classify.sh
|
||||||
BR6_RULE=""
|
|
||||||
|
|
||||||
POLICER_COUNT=0
|
POLICER_COUNT=0
|
||||||
Q_COUNT=0
|
Q_COUNT=0
|
||||||
SP_Q_PRIO=7
|
SP_Q_PRIO=7
|
||||||
|
|
||||||
#counter variable to assign classify order value if not added in config
|
|
||||||
temp_order=1
|
|
||||||
|
|
||||||
cfg_name=""
|
cfg_name=""
|
||||||
cfg_type=""
|
cfg_type=""
|
||||||
|
|
||||||
|
|
@ -172,217 +168,6 @@ handle_queue() {
|
||||||
Q_COUNT=$((Q_COUNT + 1))
|
Q_COUNT=$((Q_COUNT + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#function to handle a policer section
|
|
||||||
handle_policer() {
|
|
||||||
local p_sec="$1" # policer section ID
|
|
||||||
local dir=1 # default direction, upstream
|
|
||||||
|
|
||||||
config_get is_enable "$p_sec" "enable"
|
|
||||||
|
|
||||||
#no need to configure disabled policer
|
|
||||||
if [ $is_enable == '0' ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
config_get cir "$p_sec" "committed_rate"
|
|
||||||
config_get cbs "$p_sec" "committed_burst_size" -1
|
|
||||||
config_get ebs "$p_sec" "excess_burst_size" 0
|
|
||||||
config_get pir "$p_sec" "peak_rate" 0
|
|
||||||
config_get pbs "$p_sec" "peak_burst_size" 0
|
|
||||||
config_get meter "$p_sec" "meter_type" 0
|
|
||||||
|
|
||||||
# Call tmctl which is a broadcomm command to configure policer.
|
|
||||||
tmctl createpolicer --dir $dir --pid $POLICER_COUNT --ptype $meter --cir $cir --cbs $cbs --ebs $ebs --pir $pir --pbs $pbs
|
|
||||||
|
|
||||||
POLICER_COUNT=$((POLICER_COUNT + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
#function to handle a shaper section
|
|
||||||
handle_shaper() {
|
|
||||||
sid="$1" #queue section ID
|
|
||||||
|
|
||||||
config_get is_enable "$sid" "enable"
|
|
||||||
# no need to configure disabled queues
|
|
||||||
if [ $is_enable == '0' ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
config_get ifname "$sid" "ifname"
|
|
||||||
# if ifname is empty that is good enough to break
|
|
||||||
if [ -z "$ifname" ];then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
config_get rate "$sid" "rate"
|
|
||||||
# Convert the rate from bps to kbps.
|
|
||||||
if [ $rate -lt 1000 ];then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
rate=$(($rate / 1000))
|
|
||||||
config_get bs "$sid" "burst_size"
|
|
||||||
tmctl setportshaper --devtype 0 --if $ifname --shapingrate $rate --burstsize $bs
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_qos() {
|
|
||||||
if [ ! -d "/tmp/qos" ]; then
|
|
||||||
mkdir -p /tmp/qos
|
|
||||||
fi
|
|
||||||
if [ ! -f "/tmp/qos/qos" ]; then
|
|
||||||
touch /tmp/qos/qos
|
|
||||||
cp /etc/config/qos /tmp/qos/qos
|
|
||||||
fi
|
|
||||||
|
|
||||||
ebtables -t broute -N qos
|
|
||||||
ret=$?
|
|
||||||
if [ $ret -eq 0 ]; then
|
|
||||||
ebtables -t broute -I BROUTING -j qos
|
|
||||||
else
|
|
||||||
ebtables -t broute -D BROUTING -j qos
|
|
||||||
ebtables -t broute -I BROUTING -j qos
|
|
||||||
fi
|
|
||||||
|
|
||||||
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_chains() {
|
|
||||||
echo "ebtables -t broute -F qos" > /tmp/qos/classify.ebtables
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
init_broute_rule() {
|
|
||||||
BR_RULE=""
|
|
||||||
BR6_RULE=""
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_src_if() {
|
|
||||||
BR_RULE="$BR_RULE --in-if $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_src_mac() {
|
|
||||||
BR_RULE="$BR_RULE --src $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_dst_mac() {
|
|
||||||
BR_RULE="$BR_RULE --dst $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_pcp() {
|
|
||||||
# 5.04 onwards the vlan extension in ebtables is used for classification
|
|
||||||
# on the basis of vlan params which needs proto to be defined as 802_1Q in
|
|
||||||
# order to add a rule, now, proto can also be defined by specifying proto uci
|
|
||||||
# option as well as the rule may have a vlan id as well in which case the
|
|
||||||
# proto will already be present, hence, this check to not add --proto more
|
|
||||||
# than once
|
|
||||||
case "$BR_RULE" in
|
|
||||||
*proto*)
|
|
||||||
BR_RULE="$BR_RULE --vlan-prio $1"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
BR_RULE="$BR_RULE --proto 802_1Q --vlan-prio $1"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_ether_type() {
|
|
||||||
BR_RULE="$BR_RULE --proto $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_filter_on_ether_type6() {
|
|
||||||
BR6_RULE="$BR6_RULE --proto IPv6"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_src_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip-src $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_dst_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip-dst $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_src_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip6-src $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_dst_ip() {
|
|
||||||
BR_RULE="$BR_RULE --ip6-dst $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ip_src_port() {
|
|
||||||
BR_RULE="$BR_RULE --ip-source-port $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ip_dst_port() {
|
|
||||||
BR_RULE="$BR_RULE --ip-destination-port $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_src_port() {
|
|
||||||
#when ethertype is not configured by user then both proto rules of ipv4
|
|
||||||
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
|
||||||
#update BR_RULE only for installation of ipv6 proto rule only.
|
|
||||||
if [ ! -z "$BR6_RULE" ]; then
|
|
||||||
BR6_RULE="$BR6_RULE --ip6-source-port $1"
|
|
||||||
else
|
|
||||||
BR_RULE="$BR_RULE --ip6-source-port $1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_dst_port() {
|
|
||||||
#when ethertype is not configured by user then both proto rules of ipv4
|
|
||||||
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
|
||||||
#update BR_RULE only for installation of ipv6 proto rule only.
|
|
||||||
if [ ! -z "$BR6_RULE" ]; then
|
|
||||||
BR6_RULE="$BR6_RULE --ip6-destination-port $1"
|
|
||||||
else
|
|
||||||
BR_RULE="$BR_RULE --ip6-destination-port $1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ip_protocol() {
|
|
||||||
BR_RULE="$BR_RULE --ip-proto $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_protocol() {
|
|
||||||
#when ethertype is not configured by user then both proto rules of ipv4
|
|
||||||
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
|
||||||
#update BR_RULE only for installation of ipv6 proto rule only.
|
|
||||||
if [ ! -z "$BR6_RULE" ]; then
|
|
||||||
BR6_RULE="$BR6_RULE --ip6-proto $1"
|
|
||||||
else
|
|
||||||
BR_RULE="$BR_RULE --ip6-proto $1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ebt_match_ipv6_dscp() {
|
ebt_match_ipv6_dscp() {
|
||||||
#when ethertype is not configured by user then both proto rules of ipv4
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
||||||
|
|
@ -403,112 +188,6 @@ broute_filter_on_dscp() {
|
||||||
BR_RULE="$BR_RULE --ip-dscp-extend $tos_hex"
|
BR_RULE="$BR_RULE --ip-dscp-extend $tos_hex"
|
||||||
}
|
}
|
||||||
|
|
||||||
broute_filter_on_vid() {
|
|
||||||
|
|
||||||
if [ $1 -lt 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$BR_RULE" in
|
|
||||||
*proto*)
|
|
||||||
BR_RULE="$BR_RULE --vlan-id $1"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
BR_RULE="$BR_RULE --proto 802_1Q --vlan-id $1"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_rule_set_traffic_class() {
|
|
||||||
#when ethertype is not configured by user then both proto rules of ipv4
|
|
||||||
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
|
||||||
#update BR_RULE only for installation of ipv6 proto rule only.
|
|
||||||
BR_RULE="$BR_RULE -j mark --mark-or 0x$1 --mark-target ACCEPT"
|
|
||||||
if [ ! -z "$BR6_RULE" ]; then
|
|
||||||
BR6_RULE="$BR6_RULE -j mark --mark-or 0x$1 --mark-target ACCEPT"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_append_rule() {
|
|
||||||
#when ethertype is not configured by user then both proto rules of ipv4
|
|
||||||
#and ipv6 to be installed otherwise install ipv6 proto rule only.
|
|
||||||
echo "ebtables -t broute -A qos $BR_RULE" >> /tmp/qos/classify.ebtables
|
|
||||||
if [ -n "$BR6_RULE" ]; then
|
|
||||||
echo "ebtables -t broute -A qos $BR6_RULE" >> /tmp/qos/classify.ebtables
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
set_ip_addr()
|
|
||||||
{
|
|
||||||
local cid=$1
|
|
||||||
local match_src_ip_func=$2
|
|
||||||
local match_dst_ip_func=$3
|
|
||||||
|
|
||||||
config_get src_ip "$cid" "src_ip"
|
|
||||||
config_get dst_ip "$cid" "dest_ip"
|
|
||||||
|
|
||||||
if [ ! -z "$src_ip" ]; then
|
|
||||||
$match_src_ip_func "$src_ip"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -z "$dst_ip" ]; then
|
|
||||||
$match_dst_ip_func "$dst_ip"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
set_ports()
|
|
||||||
{
|
|
||||||
local cid=$1
|
|
||||||
local match_src_port_func=$2
|
|
||||||
local match_dst_port_func=$3
|
|
||||||
local src_port=""
|
|
||||||
local dst_port=""
|
|
||||||
local src_port_range=""
|
|
||||||
local dst_port_range=""
|
|
||||||
|
|
||||||
config_get src_port "$cid" "src_port"
|
|
||||||
config_get dst_port "$cid" "dest_port"
|
|
||||||
config_get src_port_range "$cid" "src_port_range"
|
|
||||||
config_get dst_port_range "$cid" "dest_port_range"
|
|
||||||
|
|
||||||
if ! [ -z $src_port ] && ! [ -z $src_port_range ]; then
|
|
||||||
$match_src_port_func "$src_port:$src_port_range"
|
|
||||||
elif [ ! -z $src_port ]; then
|
|
||||||
$match_src_port_func $src_port
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! [ -z $dst_port ] && ! [ -z $dst_port_range ]; then
|
|
||||||
$match_dst_port_func "$dst_port:$dst_port_range"
|
|
||||||
elif [ ! -z $dst_port ]; then
|
|
||||||
$match_dst_port_func $dst_port
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol_string_to_num()
|
|
||||||
{
|
|
||||||
local value=-1
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
*[0-9]*) value="$1"
|
|
||||||
;;
|
|
||||||
TCP|tcp) value=6
|
|
||||||
;;
|
|
||||||
UDP|udp) value=17
|
|
||||||
;;
|
|
||||||
ICMP|icmp) value=1
|
|
||||||
;;
|
|
||||||
ICMPv6|icmpv6) value=58
|
|
||||||
;;
|
|
||||||
IGMP|igmp) value=2
|
|
||||||
;;
|
|
||||||
SCTP|sctp) value=132
|
|
||||||
;;
|
|
||||||
*) value=-1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo $value
|
|
||||||
}
|
|
||||||
|
|
||||||
broute_ipv4_rule_options()
|
broute_ipv4_rule_options()
|
||||||
{
|
{
|
||||||
local cid=$1
|
local cid=$1
|
||||||
|
|
@ -561,371 +240,66 @@ broute_ipv6_rule_options()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_ebtables_rules() {
|
broute_rule_set_traffic_class() {
|
||||||
sid=$1
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
local is_l2_rule=0
|
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
||||||
local src_dhcp_options=""
|
#update BR_RULE only for installation of ipv6 proto rule only.
|
||||||
local dst_dhcp_options=""
|
BR_RULE="$BR_RULE -j mark --mark-or 0x$1 --mark-target ACCEPT"
|
||||||
local protocol=""
|
if [ ! -z "$BR6_RULE" ]; then
|
||||||
local ip_version=""
|
BR6_RULE="$BR6_RULE -j mark --mark-or 0x$1 --mark-target ACCEPT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
init_broute_rule
|
#function to handle a policer section
|
||||||
|
handle_policer() {
|
||||||
|
local p_sec="$1" # policer section ID
|
||||||
|
local dir=1 # default direction, upstream
|
||||||
|
|
||||||
config_get src_if "$sid" "ifname"
|
config_get is_enable "$p_sec" "enable"
|
||||||
config_get src_mac "$sid" "src_mac"
|
|
||||||
config_get dst_mac "$sid" "dst_mac"
|
|
||||||
config_get dscp_filter "$sid" "dscp_filter"
|
|
||||||
config_get pcp_check "$sid" "pcp_check"
|
|
||||||
config_get eth_type "$sid" "ethertype"
|
|
||||||
config_get vid "$sid" "vid_check"
|
|
||||||
config_get dhcp_type "$sid" "dhcp_type" # dhcpv4 or v6
|
|
||||||
config_get src_vcid "$sid" "src_vendor_class_id" # dhcp option 60
|
|
||||||
config_get dst_vcid "$sid" "dst_vendor_class_id" # dhcp option 60
|
|
||||||
config_get src_clid "$sid" "src_client_id" # dhcp option 61
|
|
||||||
config_get dst_clid "$sid" "dst_client_id" # dhcp option 61
|
|
||||||
config_get src_ucid "$sid" "src_user_class_id" # dhcp option 77
|
|
||||||
config_get dst_ucid "$sid" "dst_user_class_id" # dhcp option 77
|
|
||||||
config_get traffic_class "$sid" "traffic_class"
|
|
||||||
config_get protocol "$sid" "proto"
|
|
||||||
|
|
||||||
|
#no need to configure disabled policer
|
||||||
if [ -n "$src_if" ]; then
|
if [ $is_enable == '0' ]; then
|
||||||
for interf in $(db -q get hw.board.ethernetPortOrder); do
|
|
||||||
if [ "$src_if" == "$interf" ]; then
|
|
||||||
src_if="$src_if+"
|
|
||||||
broute_filter_on_src_if $src_if
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$src_mac" ]; then
|
|
||||||
broute_filter_on_src_mac $src_mac
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$dst_mac" ]; then
|
|
||||||
broute_filter_on_dst_mac $dst_mac
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$pcp_check" ]; then
|
|
||||||
broute_filter_on_pcp $pcp_check
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$eth_type" ]; then
|
|
||||||
broute_filter_on_ether_type $eth_type
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$vid" ]; then
|
|
||||||
broute_filter_on_vid $vid
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $eth_type in
|
|
||||||
IPv4|IPV4|0800)
|
|
||||||
ip_version=4
|
|
||||||
;;
|
|
||||||
IPv6|IPV6|86DD)
|
|
||||||
ip_version=6
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -z "$eth_type" ]; then
|
|
||||||
case $src_ip$dest_ip in
|
|
||||||
*.*)
|
|
||||||
ip_version=4
|
|
||||||
broute_filter_on_ether_type "IPv4"
|
|
||||||
;;
|
|
||||||
*:*)
|
|
||||||
ip_version=6
|
|
||||||
broute_filter_on_ether_type "IPv6"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -n "$protocol" ] || [ -n "$dscp_filter" ]; then
|
|
||||||
ip_version=1 #neither ether_type nor ip address used
|
|
||||||
#ethertype is not configured by user so install
|
|
||||||
#both proto ipv4 and ipv6 rule
|
|
||||||
BR6_RULE="$BR_RULE"
|
|
||||||
broute_filter_on_ether_type "IPv4"
|
|
||||||
broute_filter_on_ether_type6 "IPv6"
|
|
||||||
fi
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ "$ip_version" == "4" ] || [ "$ip_version" == "1" ]; then
|
|
||||||
broute_ipv4_rule_options "$sid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$ip_version" == "6" ] || [ "$ip_version" == "1" ]; then
|
|
||||||
broute_ipv6_rule_options "$sid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# first process options that will help figure our source mac address
|
|
||||||
# dhcp option for "vendor class id"
|
|
||||||
if [ -n "$src_vcid" ]; then
|
|
||||||
src_dhcp_options="$src_dhcp_options vcid=$src_vcid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "client id"
|
|
||||||
if [ -n "$src_clid" ]; then
|
|
||||||
src_dhcp_options="$src_dhcp_options clid=$src_clid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "user class id"
|
|
||||||
if [ -n "$src_ucid" ]; then
|
|
||||||
src_dhcp_options="$src_dhcp_options ucid=$src_ucid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if src mac is already a classification criteria, then it
|
|
||||||
# does not really make sense to add it as a criteria to
|
|
||||||
# filter packets again based on source mac
|
|
||||||
if [ -n "$src_dhcp_options" -a -z "$src_mac" ]; then
|
|
||||||
comp="$(grep -i "$src_dhcp_options" /tmp/dhcp.client.options)"
|
|
||||||
if [ -n "$comp" ]; then
|
|
||||||
s_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
|
||||||
if [ -n "$s_mac_add" ]; then
|
|
||||||
broute_filter_on_src_mac $s_mac_add
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Now process options that will help figure our destination mac address
|
|
||||||
# dhcp option for "vendor class id"
|
|
||||||
if [ -n "$dst_vcid" ]; then
|
|
||||||
dst_dhcp_options="$dst_dhcp_options vcid=$dst_vcid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "client id"
|
|
||||||
if [ -n "$dst_clid" ]; then
|
|
||||||
dst_dhcp_options="$dst_dhcp_options clid=$dst_clid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# dhcp option for "user class id"
|
|
||||||
if [ -n "$dst_ucid" ]; then
|
|
||||||
dst_dhcp_options="$dst_dhcp_options ucid=$dst_ucid"
|
|
||||||
is_l2_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if dst mac is already a classification criteria, then it
|
|
||||||
# does not really make sense to add it as a criteria to
|
|
||||||
# filter packets again based on dstination mac
|
|
||||||
if [ -n "$dst_dhcp_options" -a -z "$dst_mac" ]; then
|
|
||||||
comp="$(grep -i "$dst_dhcp_options" /tmp/dhcp.client.options)"
|
|
||||||
if [ -n "$comp" ]; then
|
|
||||||
d_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
|
||||||
if [ -n "$d_mac_add" ]; then
|
|
||||||
broute_filter_on_dst_mac $d_mac_add
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $is_l2_rule -eq 0 ]; then
|
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ -n "$traffic_class" ] && broute_rule_set_traffic_class $traffic_class
|
config_get cir "$p_sec" "committed_rate"
|
||||||
|
config_get cbs "$p_sec" "committed_burst_size" -1
|
||||||
|
config_get ebs "$p_sec" "excess_burst_size" 0
|
||||||
|
config_get pir "$p_sec" "peak_rate" 0
|
||||||
|
config_get pbs "$p_sec" "peak_burst_size" 0
|
||||||
|
config_get meter "$p_sec" "meter_type" 0
|
||||||
|
|
||||||
[ -n "$BR_RULE" ] && broute_append_rule
|
# Call tmctl which is a broadcomm command to configure policer.
|
||||||
|
tmctl createpolicer --dir $dir --pid $POLICER_COUNT --ptype $meter --cir $cir --cbs $cbs --ebs $ebs --pir $pir --pbs $pbs
|
||||||
|
|
||||||
|
POLICER_COUNT=$((POLICER_COUNT + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
init_iptables_rule() {
|
#function to handle a shaper section
|
||||||
IP_RULE=""
|
handle_shaper() {
|
||||||
}
|
sid="$1" #queue section ID
|
||||||
|
|
||||||
iptables_filter_intf() {
|
config_get is_enable "$sid" "enable"
|
||||||
IP_RULE="$IP_RULE -i $1"
|
# no need to configure disabled queues
|
||||||
}
|
if [ $is_enable == '0' ]; then
|
||||||
|
|
||||||
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"
|
|
||||||
}
|
|
||||||
|
|
||||||
iptables_set_traffic_class() {
|
|
||||||
IP_RULE="$IP_RULE -j MARK --set-xmark 0x$1/0x$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() {
|
|
||||||
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" -a -z "$dest_port_range" ]; then
|
|
||||||
iptables_filter_port_dest $dest_port
|
|
||||||
is_l3_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#filter src. port
|
|
||||||
if [ -n "$src_port" -a -z "$src_port_range" ]; then
|
|
||||||
iptables_filter_port_src $src_port
|
|
||||||
is_l3_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#filter dest. port range
|
|
||||||
if [ -n "$dest_port" -a -n "$dest_port_range" ]; then
|
|
||||||
iptables_filter_port_dest_range $dest_port $dest_port_range
|
|
||||||
is_l3_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#filter src. port range
|
|
||||||
if [ -n "$src_port" -a -n "$src_port_range" ]; then
|
|
||||||
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 [ $is_l3_rule -eq 0 ]; then
|
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#set dscp mark
|
config_get ifname "$sid" "ifname"
|
||||||
[ -n "$dscp_mark" ] && iptables_set_dscp_mark $dscp_mark
|
# if ifname is empty that is good enough to break
|
||||||
|
if [ -z "$ifname" ];then
|
||||||
#set packet queue mark
|
return
|
||||||
[ -n "$traffic_class" ] && iptables_set_traffic_class $traffic_class
|
|
||||||
|
|
||||||
#write iptables rule for dscp marking
|
|
||||||
[ -n "$IP_RULE" -a -n "$dscp_mark" ] && append_rule_to_mangle_table "qos_forward" $ip_version
|
|
||||||
|
|
||||||
if [ -n "$IP_RULE" -a -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
|
||||||
|
|
||||||
|
config_get rate "$sid" "rate"
|
||||||
|
# Convert the rate from bps to kbps.
|
||||||
|
if [ $rate -lt 1000 ];then
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rate=$(($rate / 1000))
|
||||||
|
config_get bs "$sid" "burst_size"
|
||||||
|
tmctl setportshaper --devtype 0 --if $ifname --shapingrate $rate --burstsize $bs
|
||||||
}
|
}
|
||||||
|
|
||||||
assign_policer_to_port() {
|
assign_policer_to_port() {
|
||||||
|
|
@ -1015,66 +389,6 @@ config_ingress_rate_limit() {
|
||||||
ethswctl -c rxratectrl -n $unit -p $port -x $ingress_rate -y $in_burst_size
|
ethswctl -c rxratectrl -n $unit -p $port -x $ingress_rate -y $in_burst_size
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to handle a classify order
|
|
||||||
handle_classify_order() {
|
|
||||||
local cid="$1" #classify section ID
|
|
||||||
|
|
||||||
config_get is_enable "$cid" "enable" 1
|
|
||||||
|
|
||||||
# No need to configure disabled classify
|
|
||||||
if [ $is_enable == '0' ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create classify file containing classify order
|
|
||||||
local corder_file="/tmp/qos/classify.order"
|
|
||||||
|
|
||||||
config_get c_order "$cid" "order"
|
|
||||||
|
|
||||||
if [ -z "$c_order" ]; then
|
|
||||||
c_order=$temp_order;
|
|
||||||
temp_order=$((temp_order + 1))
|
|
||||||
fi
|
|
||||||
|
|
||||||
value=${c_order}_${cid}
|
|
||||||
echo $value >> $corder_file
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sort classify, lower value in uci means higher precedence, so this
|
|
||||||
# function sorts the classify order in assending order
|
|
||||||
sort_classify_by_order() {
|
|
||||||
local corder_file="/tmp/qos/classify.order"
|
|
||||||
local tmp_corder_file="/tmp/qos/tmp_classify.order"
|
|
||||||
|
|
||||||
sort -n -k1 $corder_file > $tmp_corder_file
|
|
||||||
cp $tmp_corder_file $corder_file
|
|
||||||
rm -f $tmp_corder_file
|
|
||||||
}
|
|
||||||
|
|
||||||
#function to handle a classify section
|
|
||||||
handle_classify() {
|
|
||||||
|
|
||||||
local corder_file="/tmp/qos/classify.order"
|
|
||||||
|
|
||||||
while read -r line; do
|
|
||||||
line_cid=${line#*_}
|
|
||||||
|
|
||||||
# add ip rule only for classify rules which has non empty
|
|
||||||
# value forwarding policy option
|
|
||||||
# if forwarding policy option value empty then add iptables/
|
|
||||||
# ip6tables/ebtables/rate_limit rules
|
|
||||||
config_get fwding_policy "$line_cid" "forwarding_policy"
|
|
||||||
if [ -n "$fwding_policy" ]; then
|
|
||||||
handle_ip_rule $line_cid $fwding_policy
|
|
||||||
else
|
|
||||||
handle_ebtables_rules $line_cid
|
|
||||||
handle_iptables_rules $line_cid
|
|
||||||
handle_policer_rules $line_cid
|
|
||||||
fi
|
|
||||||
done < "$corder_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
configure_shaper() {
|
configure_shaper() {
|
||||||
# Delete existing shaper
|
# Delete existing shaper
|
||||||
for intf in $(db get hw.board.ethernetPortOrder); do
|
for intf in $(db get hw.board.ethernetPortOrder); do
|
||||||
|
|
@ -1086,49 +400,6 @@ configure_shaper() {
|
||||||
config_foreach handle_shaper shaper
|
config_foreach handle_shaper shaper
|
||||||
}
|
}
|
||||||
|
|
||||||
configure_classify() {
|
|
||||||
#processing classify section
|
|
||||||
# First remove old files
|
|
||||||
rm -f /tmp/qos/classify.ebtables
|
|
||||||
rm -f /tmp/qos/classify.iptables
|
|
||||||
rm -f /tmp/qos/classify.ip6tables
|
|
||||||
rm -f /tmp/qos/classify.order
|
|
||||||
rm -f /tmp/qos/tmp_classify.order
|
|
||||||
rm -f /tmp/qos/classify.iprule
|
|
||||||
|
|
||||||
#create files that will contain the rules if not present already
|
|
||||||
mkdir -p /tmp/qos/
|
|
||||||
touch /tmp/qos/classify.iptables
|
|
||||||
touch /tmp/qos/classify.ip6tables
|
|
||||||
touch /tmp/qos/classify.ebtables
|
|
||||||
touch /tmp/qos/classify.order
|
|
||||||
touch /tmp/qos/tmp_classify.order
|
|
||||||
touch /tmp/qos/classify.iprule
|
|
||||||
|
|
||||||
#add flush chain rules
|
|
||||||
flush_chains
|
|
||||||
|
|
||||||
#flush added ip rule
|
|
||||||
flush_ip_rule
|
|
||||||
|
|
||||||
# Load UCI file
|
|
||||||
config_load qos
|
|
||||||
config_foreach handle_classify_order classify
|
|
||||||
sort_classify_by_order
|
|
||||||
handle_classify
|
|
||||||
|
|
||||||
sh /tmp/qos/classify.ebtables
|
|
||||||
sh /tmp/qos/classify.iptables
|
|
||||||
sh /tmp/qos/classify.ip6tables
|
|
||||||
sh /tmp/qos/classify.iprule
|
|
||||||
|
|
||||||
# broadcom recommends that each time traffic class is set,
|
|
||||||
# the flows should be flushed for the new mapping to take
|
|
||||||
# effect, it then makes sense to make it a part of the
|
|
||||||
# qosmngr package itself.
|
|
||||||
fcctl flush
|
|
||||||
}
|
|
||||||
|
|
||||||
pre_configure_queue() {
|
pre_configure_queue() {
|
||||||
# Delete queues
|
# Delete queues
|
||||||
for intf in $(db get hw.board.ethernetPortOrder); do
|
for intf in $(db get hw.board.ethernetPortOrder); do
|
||||||
|
|
@ -1218,6 +489,14 @@ configure_qos() {
|
||||||
configure_queue
|
configure_queue
|
||||||
configure_policer
|
configure_policer
|
||||||
configure_classify
|
configure_classify
|
||||||
|
if [ -f "/tmp/qos/classify.ebtables" ]; then
|
||||||
|
sh /tmp/qos/classify.ebtables
|
||||||
|
fi
|
||||||
|
# broadcom recommends that each time traffic class is set,
|
||||||
|
# the flows should be flushed for the new mapping to take
|
||||||
|
# effect, it then makes sense to make it a part of the
|
||||||
|
# qosmngr package itself.
|
||||||
|
fcctl flush
|
||||||
}
|
}
|
||||||
|
|
||||||
reload_qos() {
|
reload_qos() {
|
||||||
|
|
@ -1236,6 +515,14 @@ reload_qos() {
|
||||||
configure_queue
|
configure_queue
|
||||||
elif [ "$service_name" == "classify" ]; then
|
elif [ "$service_name" == "classify" ]; then
|
||||||
configure_classify
|
configure_classify
|
||||||
|
if [ -f "/tmp/qos/classify.ebtables" ]; then
|
||||||
|
sh /tmp/qos/classify.ebtables
|
||||||
|
fi
|
||||||
|
# broadcom recommends that each time traffic class is set,
|
||||||
|
# the flows should be flushed for the new mapping to take
|
||||||
|
# effect, it then makes sense to make it a part of the
|
||||||
|
# qosmngr package itself.
|
||||||
|
fcctl flush
|
||||||
elif [ "$service_name" == "policer" ]; then
|
elif [ "$service_name" == "policer" ]; then
|
||||||
configure_policer
|
configure_policer
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ handle_classify() {
|
||||||
local corder_file="/tmp/qos/classify.order"
|
local corder_file="/tmp/qos/classify.order"
|
||||||
|
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
line_cid=$(echo $line | cut -d '_' -f 2)
|
line_cid=${line#*_}
|
||||||
|
|
||||||
# add ip rule only for classify rules which has non empty
|
# add ip rule only for classify rules which has non empty
|
||||||
# value forwarding policy option
|
# value forwarding policy option
|
||||||
|
|
@ -94,9 +94,25 @@ configure_classify() {
|
||||||
sort_classify_by_order
|
sort_classify_by_order
|
||||||
handle_classify
|
handle_classify
|
||||||
|
|
||||||
sh /tmp/qos/classify.ebtables
|
|
||||||
sh /tmp/qos/classify.iptables
|
sh /tmp/qos/classify.iptables
|
||||||
sh /tmp/qos/classify.ip6tables
|
sh /tmp/qos/classify.ip6tables
|
||||||
sh /tmp/qos/classify.iprule
|
sh /tmp/qos/classify.iprule
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_qos() {
|
||||||
|
if [ ! -d "/tmp/qos" ]; then
|
||||||
|
mkdir -p /tmp/qos
|
||||||
|
fi
|
||||||
|
if [ ! -f "/tmp/qos/qos" ]; then
|
||||||
|
touch /tmp/qos/qos
|
||||||
|
cp /etc/config/qos /tmp/qos/qos
|
||||||
|
fi
|
||||||
|
|
||||||
|
create_ebtables_chains
|
||||||
|
create_iptables_chains
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_chains() {
|
||||||
|
flush_ebtables_chains
|
||||||
|
flush_iptables_chains
|
||||||
}
|
}
|
||||||
405
qosmngr/files/common/lib/qos/ebtables.sh
Executable file
405
qosmngr/files/common/lib/qos/ebtables.sh
Executable file
|
|
@ -0,0 +1,405 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Install ebtables rules
|
||||||
|
|
||||||
|
BR_RULE=""
|
||||||
|
BR6_RULE=""
|
||||||
|
|
||||||
|
init_broute_rule() {
|
||||||
|
BR_RULE=""
|
||||||
|
BR6_RULE=""
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_src_if() {
|
||||||
|
BR_RULE="$BR_RULE --in-if $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_src_mac() {
|
||||||
|
BR_RULE="$BR_RULE --src $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_dst_mac() {
|
||||||
|
BR_RULE="$BR_RULE --dst $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_pcp() {
|
||||||
|
# 5.04 onwards the vlan extension in ebtables is used for classification
|
||||||
|
# on the basis of vlan params which needs proto to be defined as 802_1Q in
|
||||||
|
# order to add a rule, now, proto can also be defined by specifying proto uci
|
||||||
|
# option as well as the rule may have a vlan id as well in which case the
|
||||||
|
# proto will already be present, hence, this check to not add --proto more
|
||||||
|
# than once
|
||||||
|
case "$BR_RULE" in
|
||||||
|
*proto*)
|
||||||
|
BR_RULE="$BR_RULE --vlan-prio $1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
BR_RULE="$BR_RULE --proto 802_1Q --vlan-prio $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_ether_type() {
|
||||||
|
BR_RULE="$BR_RULE --proto $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_ether_type6() {
|
||||||
|
BR6_RULE="$BR6_RULE --proto IPv6"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_src_ip() {
|
||||||
|
BR_RULE="$BR_RULE --ip-src $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_dst_ip() {
|
||||||
|
BR_RULE="$BR_RULE --ip-dst $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ipv6_src_ip() {
|
||||||
|
BR_RULE="$BR_RULE --ip6-src $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ipv6_dst_ip() {
|
||||||
|
BR_RULE="$BR_RULE --ip6-dst $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ip_src_port() {
|
||||||
|
BR_RULE="$BR_RULE --ip-source-port $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ip_dst_port() {
|
||||||
|
BR_RULE="$BR_RULE --ip-destination-port $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ipv6_src_port() {
|
||||||
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
|
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
||||||
|
#update BR_RULE only for installation of ipv6 proto rule only.
|
||||||
|
if [ -n "$BR6_RULE" ]; then
|
||||||
|
BR6_RULE="$BR6_RULE --ip6-source-port $1"
|
||||||
|
else
|
||||||
|
BR_RULE="$BR_RULE --ip6-source-port $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ipv6_dst_port() {
|
||||||
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
|
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
||||||
|
#update BR_RULE only for installation of ipv6 proto rule only.
|
||||||
|
if [ -n "$BR6_RULE" ]; then
|
||||||
|
BR6_RULE="$BR6_RULE --ip6-destination-port $1"
|
||||||
|
else
|
||||||
|
BR_RULE="$BR_RULE --ip6-destination-port $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ip_protocol() {
|
||||||
|
BR_RULE="$BR_RULE --ip-proto $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ebt_match_ipv6_protocol() {
|
||||||
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
|
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
||||||
|
#update BR_RULE only for installation of ipv6 proto rule only.
|
||||||
|
if [ -n "$BR6_RULE" ]; then
|
||||||
|
BR6_RULE="$BR6_RULE --ip6-proto $1"
|
||||||
|
else
|
||||||
|
BR_RULE="$BR_RULE --ip6-proto $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_vid() {
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ "$1" -lt 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$BR_RULE" in
|
||||||
|
*proto*)
|
||||||
|
BR_RULE="$BR_RULE --vlan-id $1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
BR_RULE="$BR_RULE --proto 802_1Q --vlan-id $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_append_rule() {
|
||||||
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
|
#and ipv6 to be installed otherwise install ipv6 proto rule only.
|
||||||
|
echo "ebtables -t broute -A qos $BR_RULE" >> /tmp/qos/classify.ebtables
|
||||||
|
if [ -n "$BR6_RULE" ]; then
|
||||||
|
echo "ebtables -t broute -A qos $BR6_RULE" >> /tmp/qos/classify.ebtables
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ip_addr()
|
||||||
|
{
|
||||||
|
local cid="$1"
|
||||||
|
local match_src_ip_func="$2"
|
||||||
|
local match_dst_ip_func="$3"
|
||||||
|
|
||||||
|
config_get src_ip "$cid" "src_ip"
|
||||||
|
config_get dst_ip "$cid" "dest_ip"
|
||||||
|
|
||||||
|
if [ -n "$src_ip" ]; then
|
||||||
|
$match_src_ip_func "$src_ip"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$dst_ip" ]; then
|
||||||
|
$match_dst_ip_func "$dst_ip"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ports()
|
||||||
|
{
|
||||||
|
local cid="$1"
|
||||||
|
local match_src_port_func="$2"
|
||||||
|
local match_dst_port_func="$3"
|
||||||
|
local src_port=""
|
||||||
|
local dst_port=""
|
||||||
|
local src_port_range=""
|
||||||
|
local dst_port_range=""
|
||||||
|
|
||||||
|
config_get src_port "$cid" "src_port"
|
||||||
|
config_get dst_port "$cid" "dest_port"
|
||||||
|
config_get src_port_range "$cid" "src_port_range"
|
||||||
|
config_get dst_port_range "$cid" "dest_port_range"
|
||||||
|
|
||||||
|
if [ -n "$src_port" ] && [ -n "$src_port_range" ] ; then
|
||||||
|
$match_src_port_func "$src_port:$src_port_range"
|
||||||
|
elif [ -n "$src_port" ] ; then
|
||||||
|
$match_src_port_func "$src_port"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$dst_port" ] && [ -n "$dst_port_range" ] ; then
|
||||||
|
$match_dst_port_func "$dst_port:$dst_port_range"
|
||||||
|
elif [ -n "$dst_port" ] ; then
|
||||||
|
$match_dst_port_func "$dst_port"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_string_to_num()
|
||||||
|
{
|
||||||
|
local value="-1"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
*[0-9]*)
|
||||||
|
value="$1"
|
||||||
|
;;
|
||||||
|
TCP|tcp)
|
||||||
|
value=6
|
||||||
|
;;
|
||||||
|
UDP|udp)
|
||||||
|
value=17
|
||||||
|
;;
|
||||||
|
ICMP|icmp)
|
||||||
|
value=1
|
||||||
|
;;
|
||||||
|
ICMPv6|icmpv6)
|
||||||
|
value=58
|
||||||
|
;;
|
||||||
|
IGMP|igmp)
|
||||||
|
value=2
|
||||||
|
;;
|
||||||
|
SCTP|sctp)
|
||||||
|
value=132
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
value=-1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo $value
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_ebtables_rules() {
|
||||||
|
local sid="$1"
|
||||||
|
local is_l2_rule=0
|
||||||
|
local src_dhcp_options=""
|
||||||
|
local dst_dhcp_options=""
|
||||||
|
local protocol=""
|
||||||
|
local ip_version=""
|
||||||
|
|
||||||
|
init_broute_rule
|
||||||
|
|
||||||
|
config_get src_if "$sid" "ifname"
|
||||||
|
config_get src_mac "$sid" "src_mac"
|
||||||
|
config_get dst_mac "$sid" "dst_mac"
|
||||||
|
config_get dscp_filter "$sid" "dscp_filter"
|
||||||
|
config_get pcp_check "$sid" "pcp_check"
|
||||||
|
config_get eth_type "$sid" "ethertype"
|
||||||
|
config_get vid "$sid" "vid_check"
|
||||||
|
config_get dhcp_type "$sid" "dhcp_type" # dhcpv4 or v6
|
||||||
|
config_get src_vcid "$sid" "src_vendor_class_id" # dhcp option 60
|
||||||
|
config_get dst_vcid "$sid" "dst_vendor_class_id" # dhcp option 60
|
||||||
|
config_get src_clid "$sid" "src_client_id" # dhcp option 61
|
||||||
|
config_get dst_clid "$sid" "dst_client_id" # dhcp option 61
|
||||||
|
config_get src_ucid "$sid" "src_user_class_id" # dhcp option 77
|
||||||
|
config_get dst_ucid "$sid" "dst_user_class_id" # dhcp option 77
|
||||||
|
config_get traffic_class "$sid" "traffic_class"
|
||||||
|
config_get protocol "$sid" "proto"
|
||||||
|
|
||||||
|
if [ -n "$src_if" ]; then
|
||||||
|
for interf in $(db -q get hw.board.ethernetPortOrder); do
|
||||||
|
if [ "$src_if" == "$interf" ]; then
|
||||||
|
src_if="$src_if+"
|
||||||
|
broute_filter_on_src_if "$src_if"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$src_mac" ]; then
|
||||||
|
broute_filter_on_src_mac "$src_mac"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$dst_mac" ]; then
|
||||||
|
broute_filter_on_dst_mac "$dst_mac"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$pcp_check" ]; then
|
||||||
|
broute_filter_on_pcp "$pcp_check"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$eth_type" ]; then
|
||||||
|
broute_filter_on_ether_type "$eth_type"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$vid" ]; then
|
||||||
|
broute_filter_on_vid "$vid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $eth_type in
|
||||||
|
IPv4|IPV4|0800)
|
||||||
|
ip_version=4
|
||||||
|
;;
|
||||||
|
IPv6|IPV6|86DD)
|
||||||
|
ip_version=6
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [ -z "$eth_type" ]; then
|
||||||
|
case "$src_ip$dst_ip" in
|
||||||
|
*.*)
|
||||||
|
ip_version=4
|
||||||
|
broute_filter_on_ether_type "IPv4"
|
||||||
|
;;
|
||||||
|
*:*)
|
||||||
|
ip_version=6
|
||||||
|
broute_filter_on_ether_type "IPv6"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [ -n "$protocol" ] || [ -n "$dscp_filter" ]; then
|
||||||
|
# Neither ether_type nor ip address used,
|
||||||
|
# ethertype is not configured by user, so install
|
||||||
|
# both proto IPv4 and IPv6 rule (version 1)
|
||||||
|
ip_version=1
|
||||||
|
BR6_RULE="$BR_RULE"
|
||||||
|
broute_filter_on_ether_type "IPv4"
|
||||||
|
broute_filter_on_ether_type6 "IPv6"
|
||||||
|
fi
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$ip_version" == "4" ] || [ "$ip_version" == "1" ]; then
|
||||||
|
broute_ipv4_rule_options "$sid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ip_version" == "6" ] || [ "$ip_version" == "1" ]; then
|
||||||
|
broute_ipv6_rule_options "$sid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# first process options that will help figure our source mac address
|
||||||
|
# dhcp option for "vendor class id"
|
||||||
|
if [ -n "$src_vcid" ]; then
|
||||||
|
src_dhcp_options="$src_dhcp_options vcid=$src_vcid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# dhcp option for "client id"
|
||||||
|
if [ -n "$src_clid" ]; then
|
||||||
|
src_dhcp_options="$src_dhcp_options clid=$src_clid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# dhcp option for "user class id"
|
||||||
|
if [ -n "$src_ucid" ]; then
|
||||||
|
src_dhcp_options="$src_dhcp_options ucid=$src_ucid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if src mac is already a classification criteria, then it
|
||||||
|
# does not really make sense to add it as a criteria to
|
||||||
|
# filter packets again based on source mac
|
||||||
|
if [ -n "$src_dhcp_options" ] && [ -z "$src_mac" ]; then
|
||||||
|
comp="$(grep -i "$src_dhcp_options" /tmp/dhcp.client.options)"
|
||||||
|
if [ -n "$comp" ]; then
|
||||||
|
s_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
||||||
|
if [ -n "$s_mac_add" ]; then
|
||||||
|
broute_filter_on_src_mac "$s_mac_add"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now process options that will help figure our destination mac address
|
||||||
|
# dhcp option for "vendor class id"
|
||||||
|
if [ -n "$dst_vcid" ]; then
|
||||||
|
dst_dhcp_options="$dst_dhcp_options vcid=$dst_vcid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# dhcp option for "client id"
|
||||||
|
if [ -n "$dst_clid" ]; then
|
||||||
|
dst_dhcp_options="$dst_dhcp_options clid=$dst_clid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# dhcp option for "user class id"
|
||||||
|
if [ -n "$dst_ucid" ]; then
|
||||||
|
dst_dhcp_options="$dst_dhcp_options ucid=$dst_ucid"
|
||||||
|
is_l2_rule=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if dst mac is already a classification criteria, then it
|
||||||
|
# does not really make sense to add it as a criteria to
|
||||||
|
# filter packets again based on destination mac
|
||||||
|
if [ -n "$dst_dhcp_options" ] && [ -z "$dst_mac" ] ; then
|
||||||
|
comp="$(grep -i "$dst_dhcp_options" /tmp/dhcp.client.options)"
|
||||||
|
if [ -n "$comp" ]; then
|
||||||
|
d_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
||||||
|
if [ -n "$d_mac_add" ]; then
|
||||||
|
broute_filter_on_dst_mac "$d_mac_add"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $is_l2_rule -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -n "$traffic_class" ] && broute_rule_set_traffic_class "$traffic_class"
|
||||||
|
|
||||||
|
[ -n "$BR_RULE" ] && broute_append_rule
|
||||||
|
}
|
||||||
|
|
||||||
|
create_ebtables_chains() {
|
||||||
|
ebtables -t broute -N qos
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -eq 0 ]; then
|
||||||
|
ebtables -t broute -I BROUTING -j qos
|
||||||
|
else
|
||||||
|
ebtables -t broute -D BROUTING -j qos
|
||||||
|
ebtables -t broute -I BROUTING -j qos
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_ebtables_chains() {
|
||||||
|
echo "ebtables -t broute -F qos" > /tmp/qos/classify.ebtables
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,17 +4,16 @@
|
||||||
|
|
||||||
# include common code
|
# include common code
|
||||||
. /lib/qos/ip_rule.sh
|
. /lib/qos/ip_rule.sh
|
||||||
|
. /lib/qos/iptables.sh
|
||||||
|
. /lib/qos/ebtables.sh
|
||||||
|
. /lib/qos/classify.sh
|
||||||
|
|
||||||
IP_RULE=""
|
|
||||||
MAJOR=""
|
MAJOR=""
|
||||||
|
|
||||||
POLICER_COUNT=0
|
POLICER_COUNT=0
|
||||||
Q_COUNT=0
|
Q_COUNT=0
|
||||||
SP_Q_PRIO=7
|
SP_Q_PRIO=7
|
||||||
|
|
||||||
#counter variable to assign classify order value if not added in config
|
|
||||||
temp_order=1
|
|
||||||
|
|
||||||
# Function to handle a queue order and
|
# Function to handle a queue order and
|
||||||
# update total number of queues
|
# update total number of queues
|
||||||
handle_q_order() {
|
handle_q_order() {
|
||||||
|
|
@ -144,6 +143,88 @@ handle_queue() {
|
||||||
Q_COUNT=$((Q_COUNT + 1))
|
Q_COUNT=$((Q_COUNT + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ebt_match_ipv6_dscp() {
|
||||||
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
|
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
||||||
|
#update BR_RULE only for installation of ipv6 proto rule only.
|
||||||
|
if [ ! -z "$BR6_RULE" ]; then
|
||||||
|
BR6_RULE="$BR6_RULE --ip6-tclass $1"
|
||||||
|
else
|
||||||
|
BR_RULE="$BR_RULE --ip6-tclass $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_filter_on_dscp() {
|
||||||
|
# The broadcom option --ip-dscp-extend actually accepts tos
|
||||||
|
# and not dscp and that too in hex, hence, perform the conversion
|
||||||
|
# from dscp in uci to tos first and then convert to hex
|
||||||
|
tos_val=$(($1<<2))
|
||||||
|
tos_hex=$(printf "%x" $tos_val)
|
||||||
|
BR_RULE="$BR_RULE --ip-dscp-extend $tos_hex"
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_ipv4_rule_options()
|
||||||
|
{
|
||||||
|
local cid=$1
|
||||||
|
config_get protocol "$cid" "proto"
|
||||||
|
config_get dscp_filter "$cid" "dscp_filter"
|
||||||
|
|
||||||
|
set_ip_addr $cid ebt_match_src_ip ebt_match_dst_ip
|
||||||
|
|
||||||
|
if [ ! -z $dscp_filter ]; then
|
||||||
|
broute_filter_on_dscp "$dscp_filter"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z $protocol ]; then
|
||||||
|
local proto_num=$(protocol_string_to_num "$protocol")
|
||||||
|
ebt_match_ip_protocol "$proto_num"
|
||||||
|
|
||||||
|
#port installation for protol tcp/udp/sctp
|
||||||
|
if [ $proto_num = "6" ] || [ $proto_num = "17" ] || [ $proto_num = "132" ] ; then
|
||||||
|
set_ports "$cid" ebt_match_ip_src_port ebt_match_ip_dst_port
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_ipv6_rule_options()
|
||||||
|
{
|
||||||
|
local cid=$1
|
||||||
|
|
||||||
|
config_get protocol "$cid" "proto"
|
||||||
|
config_get dscp_filter "$cid" "dscp_filter"
|
||||||
|
|
||||||
|
set_ip_addr $cid ebt_match_ipv6_src_ip ebt_match_ipv6_dst_ip
|
||||||
|
|
||||||
|
if [ ! -z $dscp_filter ]; then
|
||||||
|
local tos_val
|
||||||
|
local tos_hex
|
||||||
|
|
||||||
|
tos_val=$(($dscp_filter<<2))
|
||||||
|
tos_hex=$(printf "%x" $tos_val)
|
||||||
|
ebt_match_ipv6_dscp "$tos_hex"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z $protocol ]; then
|
||||||
|
local proto_num=$(protocol_string_to_num "$protocol")
|
||||||
|
ebt_match_ipv6_protocol "$proto_num"
|
||||||
|
|
||||||
|
#port installation for protol tcp/udp/sctp
|
||||||
|
if [ $proto_num = "6" ] || [ $proto_num = "17" ] || [ $proto_num = "132" ]; then
|
||||||
|
set_ports "$cid" ebt_match_ipv6_src_port ebt_match_ipv6_dst_port
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
broute_rule_set_traffic_class() {
|
||||||
|
#when ethertype is not configured by user then both proto rules of ipv4
|
||||||
|
#and ipv6 to be installed so update BR6_RULE string as well otherwise
|
||||||
|
#update BR_RULE only for installation of ipv6 proto rule only.
|
||||||
|
BR_RULE="$BR_RULE -j mark --mark-or 0x$1 --mark-target ACCEPT"
|
||||||
|
if [ ! -z "$BR6_RULE" ]; then
|
||||||
|
BR6_RULE="$BR6_RULE -j mark --mark-or 0x$1 --mark-target ACCEPT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
#function to handle a policer section
|
#function to handle a policer section
|
||||||
handle_policer() {
|
handle_policer() {
|
||||||
local p_sec="$1" # policer section ID
|
local p_sec="$1" # policer section ID
|
||||||
|
|
@ -159,243 +240,6 @@ handle_policer() {
|
||||||
POLICER_COUNT=$((POLICER_COUNT + 1))
|
POLICER_COUNT=$((POLICER_COUNT + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_qos() {
|
|
||||||
if [ ! -d "/tmp/qos" ]; then
|
|
||||||
mkdir -p /tmp/qos
|
|
||||||
fi
|
|
||||||
|
|
||||||
ebtables -t broute -N qos
|
|
||||||
ret=$?
|
|
||||||
if [ $ret -eq 0 ]; then
|
|
||||||
ebtables -t broute -I BROUTING -j qos
|
|
||||||
else
|
|
||||||
ebtables -t broute -D BROUTING -j qos
|
|
||||||
ebtables -t broute -I BROUTING -j qos
|
|
||||||
fi
|
|
||||||
|
|
||||||
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_forward
|
|
||||||
ret=$?
|
|
||||||
[ $ret -eq 0 ] && iptables -w -t mangle -I FORWARD -j qos_forward
|
|
||||||
|
|
||||||
iptables -w -t mangle -N qos_output
|
|
||||||
ret=$?
|
|
||||||
[ $ret -eq 0 ] && iptables -w -t mangle -I OUTPUT -j qos_output
|
|
||||||
|
|
||||||
ip6tables -w -t mangle -N qos_prerouting
|
|
||||||
ret=$?
|
|
||||||
[ $ret -eq 0 ] && ip6tables -w -t mangle -I PREROUTING -j qos_prerouting
|
|
||||||
|
|
||||||
ip6tables -t mangle -N qos_forward
|
|
||||||
ret=$?
|
|
||||||
[ $ret -eq 0 ] && ip6tables -t mangle -I FORWARD -j qos_forward
|
|
||||||
|
|
||||||
ip6tables -t mangle -N qos_output
|
|
||||||
ret=$?
|
|
||||||
[ $ret -eq 0 ] && ip6tables -t mangle -I OUTPUT -j qos_output
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_chains() {
|
|
||||||
echo "iptables -w -t mangle -F qos_forward" > /tmp/qos/classify.iptables
|
|
||||||
echo "iptables -w -t mangle -F qos_output" >> /tmp/qos/classify.iptables
|
|
||||||
echo "iptables -w -t mangle -F qos_prerouting" >> /tmp/qos/classify.iptables
|
|
||||||
|
|
||||||
echo "ip6tables -w -t mangle -F qos_forward" > /tmp/qos/classify.ip6tables
|
|
||||||
echo "ip6tables -w -t mangle -F qos_output" >> /tmp/qos/classify.ip6tables
|
|
||||||
echo "ip6tables -w -t mangle -F qos_prerouting" >> /tmp/qos/classify.ip6tables
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
|
||||||
}
|
|
||||||
|
|
||||||
iptables_set_traffic_class() {
|
|
||||||
IP_RULE="$IP_RULE -j MARK --set-mark $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() {
|
|
||||||
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" -a -z "$dest_port_range" ]; then
|
|
||||||
iptables_filter_port_dest $dest_port
|
|
||||||
is_l3_rule=1
|
|
||||||
fi
|
|
||||||
#filter src. port
|
|
||||||
if [ -n "$src_port" -a -z "$src_port_range" ]; then
|
|
||||||
iptables_filter_port_src $src_port
|
|
||||||
is_l3_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#filter dest. port range
|
|
||||||
if [ -n "$dest_port" -a -n "$dest_port_range" ]; then
|
|
||||||
iptables_filter_port_dest_range $dest_port $dest_port_range
|
|
||||||
is_l3_rule=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#filter src. port range
|
|
||||||
if [ -n "$src_port" -a -n "$src_port_range" ]; then
|
|
||||||
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 [ $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" -a -n "$dscp_mark" ] && append_rule_to_mangle_table "qos_forward" $ip_version
|
|
||||||
if [ -n "$IP_RULE" -a -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
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_policer_rules() {
|
handle_policer_rules() {
|
||||||
local c_sec=$1
|
local c_sec=$1
|
||||||
local policer_name
|
local policer_name
|
||||||
|
|
@ -471,94 +315,6 @@ config_ingress_rate_limit() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to handle a classify order
|
|
||||||
handle_classify_order() {
|
|
||||||
local cid="$1" #classify section ID
|
|
||||||
|
|
||||||
config_get is_enable "$cid" "enable" 1
|
|
||||||
|
|
||||||
# No need to configure disabled classify
|
|
||||||
if [ $is_enable == '0' ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create classify file containing classify order
|
|
||||||
local corder_file="/tmp/qos/classify.order"
|
|
||||||
|
|
||||||
config_get c_order "$cid" "order"
|
|
||||||
|
|
||||||
if [ -z "$c_order" ]; then
|
|
||||||
c_order=$temp_order;
|
|
||||||
temp_order=$((temp_order + 1))
|
|
||||||
fi
|
|
||||||
|
|
||||||
value=${c_order}_${cid}
|
|
||||||
echo $value >> $corder_file
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sort classify, lower value in uci means higher precedence, so this
|
|
||||||
# function sorts the classify order in assending order
|
|
||||||
sort_classify_by_order() {
|
|
||||||
local corder_file="/tmp/qos/classify.order"
|
|
||||||
local tmp_corder_file="/tmp/qos/tmp_classify.order"
|
|
||||||
|
|
||||||
sort -n -k1 $corder_file > $tmp_corder_file
|
|
||||||
cp $tmp_corder_file $corder_file
|
|
||||||
rm -f $tmp_corder_file
|
|
||||||
}
|
|
||||||
|
|
||||||
#function to handle a classify section
|
|
||||||
handle_classify() {
|
|
||||||
local corder_file="/tmp/qos/classify.order"
|
|
||||||
while read -r line; do
|
|
||||||
line_cid=$(echo $line | cut -d '_' -f 2)
|
|
||||||
# add ip rule only for classify rules which has non empty
|
|
||||||
# value forwarding policy option
|
|
||||||
# if forwarding policy option value empty then add iptables/
|
|
||||||
# ip6tables/ebtables/rate_limit rules
|
|
||||||
config_get fwding_policy "$line_cid" "forwarding_policy"
|
|
||||||
|
|
||||||
if [ -n "$fwding_policy" ]; then
|
|
||||||
handle_ip_rule $line_cid $fwding_policy
|
|
||||||
else
|
|
||||||
handle_iptables_rules $line_cid
|
|
||||||
handle_policer_rules $line_cid
|
|
||||||
fi
|
|
||||||
done < "$corder_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
configure_classify() {
|
|
||||||
#processing classify section
|
|
||||||
rm -f /tmp/qos/classify.iptables
|
|
||||||
rm -f /tmp/qos/classify.ip6tables
|
|
||||||
rm -f /tmp/qos/classify.order
|
|
||||||
rm -f /tmp/qos/classify.iprule
|
|
||||||
|
|
||||||
# create files that will contain the rules if not present already
|
|
||||||
mkdir -p /tmp/qos/
|
|
||||||
touch /tmp/qos/classify.iptables
|
|
||||||
touch /tmp/qos/classify.ip6tables
|
|
||||||
touch /tmp/qos/classify.order
|
|
||||||
touch /tmp/qos/classify.iprule
|
|
||||||
|
|
||||||
flush_chains
|
|
||||||
|
|
||||||
#flush added ip rule
|
|
||||||
flush_ip_rule
|
|
||||||
|
|
||||||
# Load UCI file
|
|
||||||
config_load qos
|
|
||||||
config_foreach handle_classify_order classify
|
|
||||||
sort_classify_by_order
|
|
||||||
handle_classify
|
|
||||||
|
|
||||||
sh /tmp/qos/classify.iptables
|
|
||||||
sh /tmp/qos/classify.ip6tables
|
|
||||||
sh /tmp/qos/classify.iprule
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pre_configure_queue() {
|
pre_configure_queue() {
|
||||||
# Delete queues
|
# Delete queues
|
||||||
for intf in $(db get hw.board.ethernetPortOrder); do
|
for intf in $(db get hw.board.ethernetPortOrder); do
|
||||||
|
|
@ -676,7 +432,6 @@ configure_policer() {
|
||||||
echo $POLICER_COUNT > /tmp/qos/max_policer_inst
|
echo $POLICER_COUNT > /tmp/qos/max_policer_inst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
configure_qos() {
|
configure_qos() {
|
||||||
pre_configure_queue
|
pre_configure_queue
|
||||||
configure_queue
|
configure_queue
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue