iopsys-feed/mcastmngr/files/linux/lib/mcast/linux.sh
Rohit Topno dd55c60bd6 mcastmngr: fixed uci syntax error in init script
Problem description:
Multiple device section name fetched due
to wild card grep command.

Fix: modified grep command which gets exact device
section name based on device name.
2024-02-06 16:10:01 +00:00

424 lines
10 KiB
Bash
Executable file

#!/bin/sh
. /lib/mcast/common.sh
. /lib/functions/network.sh
include /lib/network
CONFFILE=
PROG_EXE=/usr/sbin/mcproxy
PROG_PARAMS=
PROG_PARAMS_SEPARATOR=:
snooping_bridges=
__device_is_bridge() {
local device="$2"
local devsec__="$(uci show network | grep -F ".name='$device'" | cut -d'.' -f2)"
local sectype="$(uci -q get network.$devsec__)"
local devtype="$(uci -q get network.$devsec__.type)"
[ "$sectype" != "device" -o "$devtype" != "bridge" ] && return 1
eval "$1=$devsec__"
}
device_is_bridge() {
local device="$1"
local devsec=
__device_is_bridge devsec "$device" || return 1
}
device_ports() {
local device="$1"
local devsec=
if __device_is_bridge devsec "$device"; then
echo "$(uci get network.$devsec.ports)"
else
echo "$device"
fi
}
device_has_ip() {
local protocol="$1"
local device="$2"
# Read the openwrt interface for the device.
# Device can have multiple logical interfaces like wan and wan6
# but same l3 device
# NB. Don't use 'get_network_of' here.
# This function fails in some uci configurations for interfaces that refer
# to a device indirectly.
local ifaces=$(ubus call network.interface dump | jsonfilter -e "@.interface[@.device='$device'].interface")
for iface in $ifaces; do
local ip=
case "$protocol" in
"igmp") network_get_ipaddr ip "$iface" ;;
"mld") network_get_ipaddr6 ip "$iface" ;;
esac
[ -n "$ip" ] && return
done
return 1
}
config_mcproxy_interfaces() {
local protocol="$1"
local upstreams="$2"
local downstreams="$3"
local exceptions="$4"
if [ -z "$upstreams" ] || [ -z "$downstreams" ]; then
return 1
fi
local str_up=""
for upstream in $upstreams; do
device_has_ip "$protocol" "$upstream" || continue
str_up="$str_up \"$upstream\""
done
[ -z "$str_up" ] && return 1
local str_down=""
for downstream in $downstreams; do
device_has_ip "$protocol" "$downstream" || continue
str_down="$str_down \"$downstream\""
done
[ -z "$str_down" ] && return 1
echo -e "pinstance main:$str_up ==>$str_down;\n" >> $CONFFILE
for excp in $exceptions; do
local filter=""
case $excp in
*/*)
ip_start="$(ipcalc.sh $excp | grep IP | awk '{print substr($0,4)}')"
ip_end="$(ipcalc.sh $excp | grep BROADCAST | awk '{print substr($0,11)}')"
filter="$filter ($ip_start - $ip_end | *)"
;;
*)
filter="$filter ($excp | *)"
;;
esac
for upstream in $str_up; do
echo "pinstance main upstream $upstream in blacklist table{$filter };" >> $CONFFILE
echo "pinstance main upstream $upstream out blacklist table{$filter };" >> $CONFFILE
done
for downstream in $str_down; do
echo "pinstance main downstream $downstream in blacklist table{$filter };" >> $CONFFILE
echo "pinstance main downstream $downstream out blacklist table{$filter };" >> $CONFFILE
done
done
}
config_sysfs_mcast_snooping() {
local downstreams="$1"
local snooping="$2"
for downstream in $downstreams; do
if device_is_bridge "$downstream"; then
echo $snooping > /sys/class/net/$downstream/bridge/multicast_snooping
fi
done
}
config_sysfs_mcast_fastleave() {
local downstreams="$1"
local fastleave="$2"
local prt
for downstream in $downstreams; do
for prt in $(device_ports $downstream); do
if [ -f /sys/class/net/$prt/brport/multicast_fast_leave ]; then
echo $fastleave > /sys/class/net/$prt/brport/multicast_fast_leave
fi
done
done
}
config_sysfs_mcast_version() {
local protocol="$1"
local interfaces="$2"
local version="$3"
for iface in $interfaces; do
echo $version > /sys/class/net/$iface/bridge/multicast_"$protocol"_version
done
}
config_sysfs_mcast_robustness() {
local interfaces="$1"
local robustness="$2"
for iface in $interfaces; do
echo $robustness > /sys/class/net/$iface/bridge/multicast_last_member_count
done
}
config_sysfs_mcast_query_interval() {
local interfaces="$1"
local query_interval="$2"
for iface in $interfaces; do
echo $query_interval > /sys/class/net/$iface/bridge/multicast_query_interval
done
}
config_sysfs_mcast_q_resp_interval() {
local interfaces="$1"
local q_resp_interval="$2"
for iface in $interfaces; do
echo $q_resp_interval > /sys/class/net/$iface/bridge/multicast_query_response_interval
done
}
config_sysfs_mcast_last_mem_q_int() {
local interfaces="$1"
local last_mem_q_int="$2"
for iface in $interfaces; do
echo $last_mem_q_int > /sys/class/net/$iface/bridge/multicast_last_member_interval
done
}
config_sysfs_mcast_flood() {
local downstreams=$1
local mcast_mode=$2
local prt
local mcast_flood=
if [ $mcast_mode == "2" ]; then # disable mcast flood
mcast_flood=0
else
mcast_flood=1
fi
for downstream in $downstreams; do
for prt in $(device_ports $downstream); do
if [ -f /sys/class/net/$prt/brport/multicast_flood ]; then
echo $mcast_flood > /sys/class/net/$prt/brport/multicast_flood
fi
done
done
}
config_snooping_mode() {
local interfaces="$1"
local snooping="$2"
# snooping_mode:
# 0 - snooping is disabled
# 1 - multicast flood is enabled
# 2 - multicast flood is disabled
[ -z "$snooping_mode" ] && snooping_mode=2
if [ "$snooping_mode" == 0 ]; then
config_sysfs_mcast_snooping "$interfaces" 0
else
config_sysfs_mcast_snooping "$interfaces" 1
fi
config_sysfs_mcast_flood "$interfaces" "$snooping_mode"
}
config_mcproxy_instance() {
local protocol="$1"
local version="$2"
local robustness=
local query_interval=
local q_resp_interval=
local last_mem_q_int=
local fast_leave=0
local exceptions=
local upstreams=
local downstreams=
local mcast_mode=2 # default value 2 is for blocking mode
CONFFILE=/var/etc/mcproxy_"$protocol".conf
rm -f $CONFFILE
touch $CONFFILE
if [ "$protocol" == "igmp" ]; then
case "$version" in
[1-3])
echo -e "protocol IGMPv${version};\n" >> $CONFFILE
;;
*)
echo -e "protocol IGMPv2;\n" >> $CONFFILE
;;
esac
robustness=$igmp_p_robustness
query_interval=$igmp_query_interval
q_resp_interval=$igmp_q_resp_interval
last_mem_q_int=$igmp_last_mem_q_int
fast_leave=$igmp_fast_leave
exceptions=$igmp_p_exceptions
upstreams=$igmp_p_up_interfaces
downstreams=$igmp_p_down_interfaces
mcast_mode=$igmp_p_mode
# mcproxy reserves two multicast subscriptions for igmp router service groups
local mg=$(cat /proc/sys/net/ipv4/igmp_max_memberships)
mg=$((mg+2))
echo $mg > /proc/sys/net/ipv4/igmp_max_memberships
elif [ "$protocol" == "mld" ]; then
case "$version" in
[1-2])
echo -e "protocol MLDv${version};\n" >> $CONFFILE
;;
*)
echo -e "protocol MLDv2;\n" >> $CONFFILE
;;
esac
robustness=$mld_p_robustness
query_interval=$mld_query_interval
q_resp_interval=$mld_q_resp_interval
last_mem_q_int=$mld_last_mem_q_int
fast_leave=$mld_fast_leave
exceptions=$mld_p_exceptions
upstreams=$mld_p_up_interfaces
downstreams=$mld_p_down_interfaces
mcast_mode=$mld_p_mode
fi
[ -n "$max_groups" ] && echo -e "max_groups $max_groups;" >> $CONFFILE
[ -n "$robustness" ] && echo -e "rv $robustness;" >> $CONFFILE
[ -n "$query_interval" ] && echo -e "qi $query_interval;" >> $CONFFILE
[ -n "$q_resp_interval" ] && echo -e "qri $q_resp_interval;" >> $CONFFILE
[ -n "$last_mem_q_int" ] && echo -e "lmqi $last_mem_q_int;" >> $CONFFILE
[ -n "$fast_leave" ] && echo -e "fastleave $fast_leave;\n" >> $CONFFILE
config_mcproxy_interfaces "$protocol" "$upstreams" "$downstreams" "$exceptions" || return
# for snooping to work we should enable it on the bridge, doing it from
# here instead of from inside network config
if [ "$downstreams" != "$snooping_bridges" ]; then
config_sysfs_mcast_snooping "$downstreams" 1
[ -n $fast_leave ] &&
config_sysfs_mcast_fastleave "$downstreams" "$fast_leave"
config_sysfs_mcast_flood "$downstreams" "$mcast_mode"
fi
PROG_PARAMS="${PROG_PARAMS} -f ${CONFFILE}${PROG_PARAMS_SEPARATOR}"
}
disable_snooping_iface() {
local iface="$(uci -q get network.$1.name)"
config_sysfs_mcast_snooping "$iface" 0
}
disable_snooping() {
config_load network
config_foreach disable_snooping_iface device
}
config_snooping() {
local protocol="$1"
local version=
local robustness=
local query_interval=
local q_resp_interval=
local last_mem_q_int=
local fast_leave=0
local snooping_mode=
local interfaces=
local HZ=100
local all_interfaces=
if [ "$protocol" == "igmp" ]; then
all_interfaces=$igmp_s_iface
elif [ "$protocol" == "mld" ]; then
all_interfaces=$mld_s_iface
fi
for iface in $all_interfaces; do
device_is_bridge "$iface" || continue
interfaces="$interfaces $iface"
done
[ -z "$interfaces" ] && return
snooping_bridges="$interfaces"
if [ "$protocol" == "igmp" ]; then
case "$igmp_s_version" in
[1-3])
version="$igmp_s_version"
;;
*)
version="2"
;;
esac
robustness=$igmp_s_robustness
query_interval=$(( igmp_s_query_interval * HZ ))
q_resp_interval=$(( igmp_s_q_resp_interval * HZ / 10 ))
last_mem_q_int=$(( igmp_s_last_mem_q_int * HZ / 10 ))
fast_leave=$igmp_s_fast_leave
snooping_mode=$igmp_s_mode
elif [ "$protocol" == "mld" ]; then
case "$mld_s_version" in
[1-2])
version="$mld_s_version"
;;
*)
version="2"
;;
esac
robustness=$mld_s_robustness
query_interval=$(( mld_s_query_interval * HZ ))
q_resp_interval=$(( mld_s_q_resp_interval * HZ / 10 ))
last_mem_q_int=$(( mld_s_last_mem_q_int * HZ / 10 ))
fast_leave=$mld_s_fast_leave
snooping_mode=$mld_s_mode
fi
config_snooping_mode "$interfaces" "$snooping_mode"
[ -n "$version" ] && config_sysfs_mcast_version "$protocol" "$interfaces" "$version"
[ -n "$robustness" ] && config_sysfs_mcast_robustness "$interfaces" "$robustness"
[ -n "$query_interval" ] && config_sysfs_mcast_query_interval "$interfaces" "$query_interval"
[ -n "$q_resp_interval" ] && config_sysfs_mcast_q_resp_interval "$interfaces" "$q_resp_interval"
[ -n "$last_mem_q_int" ] && config_sysfs_mcast_last_mem_q_int "$interfaces" "$last_mem_q_int"
[ -n "$fast_leave" ] && config_sysfs_mcast_fastleave "$interfaces" "$fast_leave"
}
config_mcproxy() {
disable_snooping
if [ "$igmp_p_enable" == "1" ]; then
config_mcproxy_instance igmp "$igmp_p_version"
elif [ "$igmp_s_enable" == "1" ]; then
config_snooping igmp "$igmp_s_version"
fi
if [ "$mld_p_enable" == "1" ]; then
config_mcproxy_instance mld "$mld_p_version"
elif [ "$mld_s_enable" == "1" ]; then
config_snooping mld "$mld_s_version"
fi
}
setup_mcast_mode() {
:
}
configure_mcast() {
config_global_params "set_max_groups_and_sources"
read_mcast_snooping_params
read_mcast_proxy_params
config_mcproxy
if [ -z "${PROG_PARAMS}" ]; then
exit 0
fi
}