#!/bin/sh . /lib/mcast/common.sh . /lib/functions/network.sh include /lib/network CONFFILE= PROG_EXE=/usr/sbin/mcproxy PROG_PARAMS= PROG_PARAMS_SEPARATOR=: setup_mcast_mode() { unused(){ :;} } config_mcproxy_interfaces() { local upstreams="$1" local downstreams="$2" local exceptions="$3" local str_up="" if [ -n "$upstreams" ]; then for upstream in $upstreams; do str_up="$str_up \"$upstream\"" done fi local str_down="" if [ -n "$downstreams" ]; then for downstream in $downstreams; do str_down="$str_down \"$downstream\"" done fi if [ ! -z $downstream ]; then echo -e "pinstance main:$str_up ==>$str_down;\n" >> $CONFFILE fi if [ -z "$exceptions" ] || [ -z "$upstreams" ]; then return fi 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 $upstreams; 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 $downstreams; 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 devsec= local sectype= local devtype= local ports= for downstream in $downstreams; do devsec="$(uci show network | grep name=.*$downstream | cut -d'.' -f2)" sectype="$(uci -q get network.$devsec)" devtype="$(uci -q get network.$devsec.type)" if [ "$sectype" == "device" -a "$devtype" == "bridge" ]; then echo 1 > /sys/class/net/$downstream/bridge/multicast_snooping fi 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 intf_has_ip= 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 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 fi # 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 [ -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 if [[ -n $fast_leave ]]; then echo -e "fastleave $fast_leave;\n" >> $CONFFILE config_sysfs_mcast_fastleave $fast_leave fi [ -n "$upstreams" ] && [ -n "$downstreams" ] && config_mcproxy_interfaces "$upstreams" "$downstreams" "$exceptions" # In case on proxy, upstreams is a list. Iterating and running the mcproxy # for each valid upstream interface for upstream_device in $upstreams; do # Read the upstream interface for the upstream device # upstream device can have multiple logical interfaces like wan and wan6 # but same l3 device local upstream_ifaces=$(get_network_of $upstream_device) for iface in $upstream_ifaces; do if [ "$protocol" == "igmp" ]; then network_get_ipaddr upstream_ip $iface if [ ! -z "${upstream_ip}" ]; then intf_has_ip=1 break fi fi if [ "$protocol" == "mld" ]; then network_get_ipaddr6 upstream_ip $iface if [ ! -z "${upstream_ip}" ]; then intf_has_ip=1 break fi fi done if [ -z "${intf_has_ip}" ]; then continue fi PROG_PARAMS="${PROG_PARAMS} -f ${CONFFILE}${PROG_PARAMS_SEPARATOR}" done } 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 } config_sysfs_mcast_fastleave() { local devsec= local sectype= local devtype= local ports= for downstream in $downstreams; do devsec="$(uci show network | grep name=.*$downstream | cut -d'.' -f2)" sectype="$(uci -q get network.$devsec)" devtype="$(uci -q get network.$devsec.type)" if [ "$sectype" == "device" -a "$devtype" == "bridge" ]; then ports="$(uci get network.$devsec.ports)" for prt in $ports; do echo $1 > /sys/class/net/$prt/brport/multicast_fast_leave done else [[ -f /sys/class/net/$downstream/brport/multicast_fast_leave ]] && echo $1 > /sys/class/net/$downstream/brport/multicast_fast_leave fi done } 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 }