From 04be1d3efd4f4d81bc6ac5e787dbe8a9e7e4d6fe Mon Sep 17 00:00:00 2001 From: Markus Gothe Date: Thu, 30 May 2024 11:53:44 +0200 Subject: [PATCH] qosmngr: Add option to match on ICMP/ICMPv6 type. --- .../files/airoha/lib/qos/chains.ebtables.sh | 6 ++ qosmngr/files/broadcom/lib/qos/qos.sh | 6 ++ qosmngr/files/common/lib/qos/ebtables.sh | 23 ++++++-- qosmngr/files/common/lib/qos/iptables.sh | 55 ++++++++++++++++++- qosmngr/files/linux/lib/qos/qos.sh | 6 ++ 5 files changed, 91 insertions(+), 5 deletions(-) diff --git a/qosmngr/files/airoha/lib/qos/chains.ebtables.sh b/qosmngr/files/airoha/lib/qos/chains.ebtables.sh index cb3e6911e..48306ff1d 100755 --- a/qosmngr/files/airoha/lib/qos/chains.ebtables.sh +++ b/qosmngr/files/airoha/lib/qos/chains.ebtables.sh @@ -25,6 +25,7 @@ broute_ipv4_rule_options() local cid="$1" config_get protocol "$cid" "proto" config_get dscp_filter "$cid" "dscp_filter" + config_get icmp_type "$cid" "icmp_type" set_ip_addr "$cid" ebt_match_src_ip ebt_match_dst_ip @@ -43,6 +44,8 @@ broute_ipv4_rule_options() if [ "$proto_num" == "6" ] || [ "$proto_num" == "17" ] || [ "$proto_num" = "132" ] ; then set_ports "$cid" ebt_match_ip_src_port ebt_match_ip_dst_port + elif [ "$proto_num" = "1" -a -n "$icmp_type" ]; then + ebt_match_ip_icmp_type "$icmp_type" fi fi } @@ -53,6 +56,7 @@ broute_ipv6_rule_options() config_get protocol "$cid" "proto" config_get dscp_filter "$cid" "dscp_filter" + config_get icmp_type "$cid" "icmp_type" set_ip_addr "$cid" ebt_match_ipv6_src_ip ebt_match_ipv6_dst_ip @@ -71,6 +75,8 @@ broute_ipv6_rule_options() if [ "$proto_num" = "6" ] || [ "$proto_num" = "17" ] || [ "$proto_num" = "132" ] ; then set_ports "$cid" ebt_match_ipv6_src_port ebt_match_ipv6_dst_port + elif [ "$proto_num" = "58" -a -n "$icmp_type" ]; then + ebt_match_ipv6_icmp_type "$icmp_type" fi fi } diff --git a/qosmngr/files/broadcom/lib/qos/qos.sh b/qosmngr/files/broadcom/lib/qos/qos.sh index e34c64ce7..4b20c7414 100755 --- a/qosmngr/files/broadcom/lib/qos/qos.sh +++ b/qosmngr/files/broadcom/lib/qos/qos.sh @@ -223,6 +223,7 @@ broute_ipv4_rule_options() local cid=$1 config_get protocol "$cid" "proto" config_get dscp_filter "$cid" "dscp_filter" + config_get icmp_type "$cid" "icmp_type" set_ip_addr $cid ebt_match_src_ip ebt_match_dst_ip @@ -237,6 +238,8 @@ broute_ipv4_rule_options() #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 + elif [ "$proto_num" = "1" -a -n "$icmp_type" ]; then + ebt_match_ip_icmp_type "$icmp_type" fi fi } @@ -247,6 +250,7 @@ broute_ipv6_rule_options() config_get protocol "$cid" "proto" config_get dscp_filter "$cid" "dscp_filter" + config_get icmp_type "$cid" "icmp_type" set_ip_addr $cid ebt_match_ipv6_src_ip ebt_match_ipv6_dst_ip @@ -266,6 +270,8 @@ broute_ipv6_rule_options() #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 + elif [ "$proto_num" = "58" -a -n "$icmp_type" ]; then + ebt_match_ipv6_icmp_type "$icmp_type" fi fi } diff --git a/qosmngr/files/common/lib/qos/ebtables.sh b/qosmngr/files/common/lib/qos/ebtables.sh index b1044b126..35e624841 100755 --- a/qosmngr/files/common/lib/qos/ebtables.sh +++ b/qosmngr/files/common/lib/qos/ebtables.sh @@ -93,7 +93,11 @@ ebt_match_ipv6_dst_port() { } ebt_match_ip_protocol() { - BR_RULE="$BR_RULE --ip-proto $1" + BR_RULE="$BR_RULE --ip-proto $1" +} + +ebt_match_ip_icmp_type() { + BR_RULE="$BR_RULE --ip-icmp-type $1" } ebt_match_ipv6_protocol() { @@ -107,6 +111,17 @@ ebt_match_ipv6_protocol() { fi } +ebt_match_ipv6_icmp_type() { + #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-icmp-type $1" + else + BR_RULE="$BR_RULE --ip6-icmp-type $1" + fi +} + broute_filter_on_vid() { if [ -z "$1" ] || [ "$1" -lt 0 ]; then @@ -183,9 +198,6 @@ protocol_string_to_num() local value="-1" case "$1" in - *[0-9]*) - value="$1" - ;; TCP|tcp) value=6 ;; @@ -204,6 +216,9 @@ protocol_string_to_num() SCTP|sctp) value=132 ;; + *[0-9]*) + value="$1" + ;; *) value=-1 ;; diff --git a/qosmngr/files/common/lib/qos/iptables.sh b/qosmngr/files/common/lib/qos/iptables.sh index 260f4dbaa..5a2febb27 100755 --- a/qosmngr/files/common/lib/qos/iptables.sh +++ b/qosmngr/files/common/lib/qos/iptables.sh @@ -15,6 +15,14 @@ iptables_filter_proto() { IP_RULE="$IP_RULE -p $1" } +iptables_filter_icmp() { + IP_RULE="$IP_RULE --icmp-type $1" +} + +iptables_filter_icmpv6() { + IP_RULE="$IP_RULE --icmpv6-type $1" +} + iptables_filter_ip_src() { IP_RULE="$IP_RULE -s $1" } @@ -66,10 +74,44 @@ append_rule_to_mangle_table() { fi } +protocol_string_to_num() +{ + local value="-1" + + case "$1" in + TCP|tcp) + value=6 + ;; + UDP|udp) + value=17 + ;; + ICMP|icmp) + value=1 + ;; + ICMPv6|icmpv6) + value=58 + ;; + IGMP|igmp) + value=2 + ;; + SCTP|sctp) + value=132 + ;; + *[0-9]*) + value="$1" + ;; + *) + value=-1 + ;; + esac + echo $value +} + handle_iptables_rules() { local cid="$1" local ip_version=0 local is_l3_rule=0 + local proto_num=-1 traffic_class=$2 init_iptables_rule @@ -94,6 +136,7 @@ handle_iptables_rules() { config_get ip_len_max "$cid" "ip_len_max" config_get ifname "$cid" "ifname" config_get all_interfaces "$cid" "all_interfaces" + config_get icmp_type "$cid" "icmp_type" #check version of ip case $src_ip$dest_ip in @@ -116,7 +159,17 @@ handle_iptables_rules() { # filter proto if [ -n "$proto" ]; then - iptables_filter_proto "$proto" + proto_num=$(protocol_string_to_num "$proto") + iptables_filter_proto "$proto_num" + if [ -n "$icmp_type" -a \( "$proto_num" = "58" -o "$proto_num" = "1" \) ]; then + if [ "$proto_num" = "1" ]; then + iptables_filter_icmp "$icmp_type" + ip_version=4 + else + iptables_filter_icmpv6 "$icmp_type" + ip_version=6 + fi + fi is_l3_rule=1 fi diff --git a/qosmngr/files/linux/lib/qos/qos.sh b/qosmngr/files/linux/lib/qos/qos.sh index 2370259f0..eef8828a0 100755 --- a/qosmngr/files/linux/lib/qos/qos.sh +++ b/qosmngr/files/linux/lib/qos/qos.sh @@ -221,6 +221,7 @@ broute_ipv4_rule_options() local cid=$1 config_get protocol "$cid" "proto" config_get dscp_filter "$cid" "dscp_filter" + config_get icmp_type "$cid" "icmp_type" set_ip_addr $cid ebt_match_src_ip ebt_match_dst_ip @@ -240,6 +241,8 @@ broute_ipv4_rule_options() #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 + elif [ "$proto_num" = "1" -a -n "$icmp_type" ]; then + ebt_match_ip_icmp_type "$icmp_type" fi fi } @@ -250,6 +253,7 @@ broute_ipv6_rule_options() config_get protocol "$cid" "proto" config_get dscp_filter "$cid" "dscp_filter" + config_get icmp_type "$cid" "icmp_type" set_ip_addr $cid ebt_match_ipv6_src_ip ebt_match_ipv6_dst_ip @@ -269,6 +273,8 @@ broute_ipv6_rule_options() #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 + elif [ "$proto_num" = "58" -a -n "$icmp_type" ]; then + ebt_match_ipv6_icmp_type "$icmp_type" fi fi }