bbf: Update mcastmngr to handle mld config

The mcast manager can now configure mld snooping and proxy
This commit is contained in:
Rahul 2020-04-23 12:20:35 +05:30
parent ea87bfe337
commit c7f037fdd7
3 changed files with 237 additions and 99 deletions

View file

@ -15,7 +15,7 @@ service_triggers() {
start_service() {
if [ -f "/etc/config/mcast" ]; then
configure_mcast_igmp
configure_mcast
fi
procd_open_instance

View file

@ -7,8 +7,16 @@ generate_igmp_global_params(){
uci rename mcast.@igmp[-1]="igmp"
uci set mcast.@igmp[-1].max_membership="20"
uci set mcast.@igmp[-1].max_msf="10"
uci set mcast.@igmp[-1].max_qrv="2"
uci set mcast.@igmp[-1].qrv="2"
uci set mcast.@igmp[-1].force_version="0"
uci add mcast mld
uci rename mcast.@mld[-1]="mld"
uci set mcast.@mld[-1].mldv1_unsolicited_report_interval="10"
uci set mcast.@mld[-1].mldv2_unsolicited_report_interval="1"
uci set mcast.@mld[-1].qrv="2"
uci set mcast.@mld[-1].force_version="0"
uci commit mcast
}

View file

@ -9,30 +9,50 @@ CONFFILE=/var/mcpd.conf
PROG_EXE=/usr/sbin/mcpd
# Parameters available in snooping configuration
s_enable=0
s_version=2
s_robustness=2
s_interface=""
s_exceptions=""
igmp_s_enable=0
igmp_s_version=2
igmp_s_robustness=2
igmp_s_iface=""
igmp_s_exceptions=""
# Parameters available in proxy configuration
p_enable=0
p_version=2
query_interval=125
q_resp_interval=100
last_mem_q_int=10
mld_s_enable=0
mld_s_version=2
mld_s_robustness=2
mld_s_iface=""
mld_s_exceptions=""
# Global params
max_groups=25
max_msf=10
max_members=25
fast_leave=1
p_robustness=2
p_up_interfaces=""
p_down_interfaces=""
p_exceptions=""
mldv1_unsolicited_report_interval=10
mldv2_unsolicited_report_interval=1
# Parameters available in proxy configuration
igmp_p_enable=0
igmp_p_version=2
igmp_query_interval=125
igmp_q_resp_interval=100
igmp_last_mem_q_int=10
igmp_fast_leave=1
igmp_p_robustness=2
igmp_p_up_interfaces=""
igmp_p_down_interfaces=""
igmp_p_exceptions=""
mld_p_enable=0
mld_p_version=1
mld_query_interval=125
mld_q_resp_interval=100
mld_last_mem_q_int=10
mld_fast_leave=1
mld_p_robustness=2
mld_p_up_interfaces=""
mld_p_down_interfaces=""
mld_p_exceptions=""
# Standard parameters need by BCM's multicast daemon
l_2_l_mcast=0
bcm_mcast_p=1
allow_brdevice=0
proxdevs=""
@ -40,60 +60,109 @@ ethwan="$(db -q get hw.board.ethernetWanPort)"
read_snooping() {
local config="$1"
config_get s_enable "$config" enable 0
local sec_enable
local proto
if [ "$s_enable" == "0" ]; then
config_get sec_enable "$config" enable 0
config_get proto "$config" proto
if [ "$sec_enable" == "0" ]; then
return
fi
config_get s_version "$config" version 2
config_get s_robustness "$config" robustness 2
config_get s_interface "$config" interface
config_get s_exceptions "$config" filter
if [ "$proto" == "igmp" ]; then
igmp_s_enable=$sec_enable
config_get igmp_s_version "$config" version 2
config_get igmp_s_robustness "$config" robustness 2
config_get igmp_s_iface "$config" interface
config_get igmp_s_exceptions "$config" filter
return
fi
if [ "$proto" == "mld" ]; then
mld_s_enable=$sec_enable
config_get mld_s_version "$config" version 2
config_get mld_s_robustness "$config" robustness 2
config_get mld_s_iface "$config" interface
config_get mld_s_exceptions "$config" filter
return
fi
}
read_proxy() {
local config="$1"
config_get p_enable "$config" enable 0
local sec_enable
local proto
if [ "$p_enable" == "0" ]; then
config_get sec_enable "$config" enable 0
config_get proto "$config" proto
if [ "$sec_enable" == "0" ]; then
return
fi
config_get p_version "$config" version 2
config_get query_interval "$config" query_interval
config_get q_resp_interval "$config" query_response_interval
config_get last_mem_q_int "$config" last_member_query_interval
config_get fast_leave "$config" fast_leave 1
config_get p_robustness "$config" robustness 2
config_get p_up_interfaces "$config" upstream_interface
config_get p_down_interfaces "$config" downstream_interface
config_get p_exceptions "$config" filter
if [ "$proto" == "igmp" ]; then
igmp_p_enable=$sec_enable
config_get igmp_p_version "$config" version 2
config_get igmp_query_interval "$config" query_interval
config_get igmp_q_resp_interval "$config" query_response_interval
config_get igmp_last_mem_q_int "$config" last_member_query_interval
config_get igmp_fast_leave "$config" fast_leave 1
config_get igmp_p_robustness "$config" robustness 2
config_get igmp_p_up_interfaces "$config" upstream_interface
config_get igmp_p_down_interfaces "$config" downstream_interface
config_get igmp_p_exceptions "$config" filter
return
fi
if [ "$proto" == "mld" ]; then
mld_p_enable=$sec_enable
config_get mld_p_version "$config" version 2
config_get mld_query_interval "$config" query_interval
config_get mld_q_resp_interval "$config" query_response_interval
config_get mld_last_mem_q_int "$config" last_member_query_interval
config_get mld_fast_leave "$config" fast_leave 1
config_get mld_p_robustness "$config" robustness 2
config_get mld_p_up_interfaces "$config" upstream_interface
config_get mld_p_down_interfaces "$config" downstream_interface
config_get mld_p_exceptions "$config" filter
return
fi
}
config_igmps_common_params() {
echo "igmp-default-version $1" >> $CONFFILE
echo "igmp-robustness-value $2" >> $CONFFILE
echo "igmp-max-groups $max_groups" >> $CONFFILE
echo "igmp-max-sources $max_msf" >> $CONFFILE
echo "igmp-max-members $max_members" >> $CONFFILE
echo "igmp-snooping-enable $3" >> $CONFFILE
config_snooping_common_params() {
local protocol="$1"
echo "${protocol}-default-version $2" >> $CONFFILE
echo "${protocol}-robustness-value $3" >> $CONFFILE
echo "${protocol}-max-groups $max_groups" >> $CONFFILE
echo "${protocol}-max-sources $max_msf" >> $CONFFILE
echo "${protocol}-max-members $max_members" >> $CONFFILE
echo "${protocol}-snooping-enable $4" >> $CONFFILE
}
config_igmp_querier_params() {
echo "igmp-query-interval $query_interval" >> $CONFFILE
echo "igmp-query-response-interval $q_resp_interval" >> $CONFFILE
echo "igmp-last-member-query-interval $last_mem_q_int" >> $CONFFILE
config_mcast_querier_params() {
local protocol="$1"
local query_interval=$2
local q_resp_interval=$3
local last_mem_q_int=$4
echo "${protocol}-query-interval $query_interval" >> $CONFFILE
echo "${protocol}-query-response-interval $q_resp_interval" >> $CONFFILE
echo "${protocol}-last-member-query-interval $last_mem_q_int" >> $CONFFILE
}
config_snooping_on_bridge() {
echo "igmp-snooping-interfaces $1" >> $CONFFILE
local protocol="$1"
local bcm_mcast_p=1
echo "${protocol}-snooping-interfaces $2" >> $CONFFILE
for snpif in $1; do
[ "$protocol" == "mld" ] && bcm_mcast_p=2
for snpif in $2; do
case "$snpif" in
br-*)
# set snooping mode on the bridge
bcmmcastctl mode -i $snpif -p $bcm_mcast_p -m $2
bcmmcastctl mode -i $snpif -p $bcm_mcast_p -m $3
# set L2L snooping mode on the bridge
bcmmcastctl l2l -i $snpif -p $bcm_mcast_p -e $l_2_l_mcast # set L2L snooping mode on the bridge
;;
@ -102,13 +171,21 @@ config_snooping_on_bridge() {
}
handle_bridged_proxy_interface() {
bridged=1
local p2="$1"
local p_enable=0
if [ "$p2" == "igmp" ]; then
p_enable=$igmp_p_enable
else
p_enable=$mld_p_enable
fi
if [ $p_enable -eq 1 -a $allow_brdevice -eq 1 ]
then
proxdevs="$proxdevs $1"
echo "upstream-interface $1" >>$CONFFILE
proxdevs="$proxdevs $2"
echo "upstream-interface $2" >>$CONFFILE
else
json_load "$(devstatus $1)"
json_load "$(devstatus $2)"
itr=1
json_select bridge-members
while json_get_var dev $itr; do
@ -126,13 +203,21 @@ handle_bridged_proxy_interface() {
fi
}
config_igmp_proxy_interface() {
config_mcast_proxy_interface() {
local itr
local p1="$1"
local p_enable
for proxif in $1; do
if [ "$p1" == "igmp" ]; then
p_enable=$igmp_p_enable
else
p_enable=$mld_p_enable
fi
for proxif in $2; do
case "$proxif" in
br-*)
handle_bridged_proxy_interface $proxif
handle_bridged_proxy_interface $p1 $proxif
;;
*)
proxdevs="$proxdevs $proxif"
@ -141,97 +226,142 @@ config_igmp_proxy_interface() {
done
if [ $p_enable -eq 1 ]; then
echo "igmp-proxy-interfaces $proxdevs" >> $CONFFILE
echo "${p1}-proxy-interfaces $proxdevs" >> $CONFFILE
fi
[ -n "$proxdevs" ] && echo "igmp-mcast-interfaces $proxdevs" >> $CONFFILE
[ -n "$proxdevs" ] && echo "${p1}-mcast-interfaces $proxdevs" >> $CONFFILE
}
configure_mcpd_snooping() {
local protocol="$1"
local exceptions
# Configure snooping related params
config_igmps_common_params $s_version $s_robustness $s_enable
echo "igmp-proxy-enable 0" >> $CONFFILE
if [ "$protocol" == "igmp" ]; then
config_snooping_common_params $protocol $igmp_p_version $igmp_p_robustness $igmp_s_enable
config_mcast_querier_params $protocol $igmp_query_interval $igmp_q_resp_interval $igmp_last_mem_q_int
config_mcast_proxy_interface $protocol $igmp_s_iface
config_snooping_on_bridge $protocol $igmp_s_iface $igmp_s_enable
exceptions=$igmp_s_exceptions
elif [ "$protocol" == "mld" ]; then
config_snooping_common_params $protocol $mld_p_version $mld_p_robustness $mld_s_enable
config_mcast_querier_params $protocol $mld_query_interval $mld_q_resp_interval $mld_last_mem_q_int
config_mcast_proxy_interface $protocol $mld_s_iface
config_snooping_on_bridge $protocol $mld_s_iface $mld_s_enable
exceptions=$mld_s_exceptions
fi
# BCM's mcpd always acts as queries, so configure some default values to prevent flooding
# of queries towards the clients or early leaves even in pure snooping with what will be
# default values for these params
config_igmp_querier_params
config_igmp_proxy_interface $s_interface
# set snooping mode on the bridge
config_snooping_on_bridge $s_interface $s_enable
[ -n "$s_exceptions" ] && echo "igmp-mcast-snoop-exceptions $s_exceptions" >> $CONFFILE
echo "${protocol}-proxy-enable 0" >> $CONFFILE
[ -n "$exceptions" ] && echo "${protocol}-mcast-snoop-exceptions $exceptions" >> $CONFFILE
}
configure_mcpd_proxy() {
local s_mode=2
local protocol="$1"
local fast_leave=0
local exceptions=""
# Configure snooping related params
config_igmps_common_params $p_version $p_robustness $s_mode
echo "igmp-proxy-enable $p_enable" >> $CONFFILE
echo "igmp-fast-leave $fast_leave" >> $CONFFILE
if [ "$protocol" == "igmp" ]; then
config_snooping_common_params $protocol $igmp_p_version $igmp_p_robustness $s_mode
config_mcast_querier_params $protocol $igmp_query_interval $igmp_q_resp_interval $igmp_last_mem_q_int
config_mcast_proxy_interface $protocol $igmp_p_up_interfaces
config_snooping_on_bridge $protocol $igmp_p_down_interfaces $s_mode
fast_leave=$igmp_fast_leave
exceptions=$igmp_p_exceptions
elif [ "$protocol" == "mld" ]; then
config_snooping_common_params $protocol $mld_p_version $mld_p_robustness $s_mode
config_mcast_querier_params $protocol $mld_query_interval $mld_q_resp_interval $mld_last_mem_q_int
config_mcast_proxy_interface $protocol $mld_p_up_interfaces
config_snooping_on_bridge $protocol $mld_p_down_interfaces $s_mode
fast_leave=$mld_fast_leave
exceptions=$mld_p_exceptions
fi
config_igmp_querier_params
# This function will only be hit in case proxy is enabled, so hard coding
# proxy enable should not be a problem
echo "${protocol}-proxy-enable 1" >> $CONFFILE
echo "${protocol}-fast-leave $fast_leave" >> $CONFFILE
config_igmp_proxy_interface $p_up_interfaces
config_snooping_on_bridge $p_down_interfaces $s_mode
[ -n "$p_exceptions" ] && echo "igmp-mcast-snoop-exceptions $p_exceptions" >> $CONFFILE
[ -n "$exceptions" ] && echo "$protocol-mcast-snoop-exceptions $exceptions" >> $CONFFILE
}
configure_mcpd() {
disable_snooping() {
local bcm_mcast_p=$1
for br in $(brctl show | grep 'br-' | awk '{print$1}' | tr '\n' ' '); do
bcmmcastctl mode -i $br -p $bcm_mcast_p -m 0 # disable snooping on all bridges
bcmmcastctl l2l -i $br -p $bcm_mcast_p -e 0 # disable L2L snooping on all bridges
done
}
configure_mcpd() {
disable_snooping 1
disable_snooping 2
# BCM's mcpd does not allow configuration of proxy and L2 snooping simultaneously, hence
# here, if proxy is to be configured then the configuration params of snooping are ignored.
if [ "$p_enable" == "1" ]; then
configure_mcpd_proxy
elif [ "$s_enable" == "1" ]; then
configure_mcpd_snooping
if [ "$igmp_p_enable" == "1" ]; then
configure_mcpd_proxy igmp
elif [ "$igmp_s_enable" == "1" ]; then
configure_mcpd_snooping igmp
fi
proxdevs=""
if [ "$mld_p_enable" == "1" ]; then
configure_mcpd_proxy mld
elif [ "$mld_s_enable" == "1" ]; then
configure_mcpd_snooping mld
fi
}
read_igmp_snooping_params() {
read_mcast_snooping_params() {
config_load mcast
config_foreach read_snooping snooping
}
read_igmp_proxy_params() {
read_mcast_proxy_params() {
config_load mcast
config_foreach read_proxy proxy
}
config_global_igmp_params() {
local qrv
local force_version
config_global_params() {
local igmp_qrv
local igmp_force_version
local mld_qrv
local mld_force_version
config_load mcast
config_get max_msf igmp max_msf 10
config_get max_groups igmp max_membership 25
config_get qrv igmp qrv 2
config_get force_version igmp force_version 0
config_get igmp_qrv igmp qrv 2
config_get igmp_force_version igmp force_version 0
config_get mld_qrv mld qrv 2
config_get mldv1_unsolicited_report_interval mld mldv1_unsolicited_report_interval 10
config_get mldv2_unsolicited_report_interval mld mldv2_unsolicited_report_interval 1
config_get mld_force_version mld force_version 0
# mcpd internally writes max_groups and max_msf, no need to modify
# here directly
echo $qrv > /proc/sys/net/ipv4/igmp_qrv
echo $force_version > /proc/sys/net/ipv4/conf/all/force_igmp_version
echo $igmp_qrv > /proc/sys/net/ipv4/igmp_qrv
echo $igmp_force_version > /proc/sys/net/ipv4/conf/all/force_igmp_version
echo $mld_qrv > /proc/sys/net/ipv6/mld_qrv
echo $mld_force_version > /proc/sys/net/ipv6/conf/all/force_mld_version
echo $mldv1_unsolicited_report_interval > /proc/sys/net/ipv6/conf/all/mldv1_unsolicited_report_interval
echo $mldv2_unsolicited_report_interval > /proc/sys/net/ipv6/conf/all/mldv2_unsolicited_report_interval
}
configure_mcast_igmp() {
configure_mcast() {
rm -f $CONFFILE
touch $CONFFILE
config_global_igmp_params
config_global_params
read_igmp_snooping_params
read_igmp_proxy_params
read_mcast_snooping_params
read_mcast_proxy_params
configure_mcpd
}