mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
Implement a stub for setup_mcast_mode() on non-Broadcom platforms. Change-Id: Idd0c75f564f0de5fe698c1fc32088a32a029ac96
268 lines
6.5 KiB
Bash
Executable file
268 lines
6.5 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=:
|
|
|
|
|
|
__device_is_bridge() {
|
|
local device="$2"
|
|
local devsec__="$(uci show network | grep 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"
|
|
|
|
for downstream in $downstreams; do
|
|
if device_is_bridge "$downstream"; then
|
|
echo 1 > /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_mode() {
|
|
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_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
|
|
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
|
|
config_sysfs_mcast_snooping "$downstreams"
|
|
[ -n $fast_leave ] &&
|
|
config_sysfs_mcast_fastleave "$downstreams" "$fast_leave"
|
|
config_sysfs_mcast_mode "$downstreams" "$mcast_mode"
|
|
|
|
PROG_PARAMS="${PROG_PARAMS} -f ${CONFFILE}${PROG_PARAMS_SEPARATOR}"
|
|
}
|
|
|
|
config_mcproxy() {
|
|
if [ "$igmp_p_enable" == "1" ]; then
|
|
config_mcproxy_instance igmp "$igmp_p_version"
|
|
fi
|
|
|
|
if [ "$mld_p_enable" == "1" ]; then
|
|
config_mcproxy_instance mld "$mld_p_version"
|
|
fi
|
|
}
|
|
|
|
setup_mcast_mode() {
|
|
:
|
|
}
|
|
|
|
configure_mcast() {
|
|
config_global_params "set_max_groups_and_sources"
|
|
|
|
# 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
|
|
|
|
read_mcast_snooping_params
|
|
read_mcast_proxy_params
|
|
config_mcproxy
|
|
|
|
if [ -z "${PROG_PARAMS}" ]; then
|
|
exit 0
|
|
fi
|
|
}
|