mcastmngr: Implement L2 stats over UBUS.

Implement support for L2 mcast stats over UBUS.
This commit is contained in:
Markus Gothe 2024-10-16 18:06:33 +02:00 committed by Rahul Thakur
parent 9fba09f00a
commit 4e2adf77cb
2 changed files with 133 additions and 24 deletions

View file

@ -3,8 +3,42 @@
. /usr/share/libubox/jshn.sh
. /lib/functions.sh
read_mcast_stats() {
cat /proc/net/igmp_snooping > /tmp/igmp_stats
readonly TEMPFILE="/tmp/snooping_stats_"$$
splitup_ipv6addr() {
local inaddr="$1"
local lowaddr=""
local hiaddr=""
local subaddr=""
local outaddr=""
OIFS=$IFS
IFS=":"
for subaddr in $inaddr; do
loaddr="$(printf "%x\n" 0x$(echo -n "$subaddr" | cut -b5-8))"
hiaddr="$(printf "%x\n" 0x$(echo -n "$subaddr" | cut -b1-4))"
if [ -z "$outaddr" ]; then
outaddr="${hiaddr}:${loaddr}"
else
outaddr="${outaddr}:${hiaddr}:${loaddr}"
fi
done
IFS=$OIFS
echo "$outaddr" | sed -e 's/0000/0/g' -e 's/00/0/g' -e 's/000/0/g'
}
meld_files() {
local type="$1"
if [ "$type" = "mld" ]; then
cat "/proc/net/${type}_snooping" | awk -F' ' '{ print $1 " " $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " NULL " $9 " " $10 " " $11 " " $12 " " $13 " " $12 }' >> "$TEMPFILE"
else
cat "/proc/net/${type}_snooping" >> "$TEMPFILE"
fi
}
read_snooping_file() {
local mcast_addrs=""
local ifaces=""
@ -33,7 +67,7 @@ read_mcast_stats() {
fi
;;
esac
done < /tmp/igmp_stats
done < "$TEMPFILE"
while read line; do
# reading each line
@ -41,6 +75,7 @@ read_mcast_stats() {
br-*)
found_ip=0
grp_ip="$(echo $line | awk -F ' ' '{ print $10 }')"
if [ -z "$mcast_addrs" ]; then
mcast_addrs="$grp_ip"
continue
@ -60,10 +95,8 @@ read_mcast_stats() {
fi
;;
esac
done < /tmp/igmp_stats
done < "$TEMPFILE"
json_init
json_add_array "snooping"
IFS=" "
for intf in $ifaces; do
json_add_object ""
@ -86,7 +119,12 @@ read_mcast_stats() {
fi
if [ $grp_obj_added -eq 0 ]; then
json_add_object ""
gip="$(ipcalc.sh $gip_addr | grep IP | awk '{print substr($0,4)}')"
if [ -n "$(echo $gip_addr | grep -oE "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$")" ]; then
gip="$(ipcalc.sh $gip_addr | grep IP | awk '{print substr($0,4)}')"
else
gip_addr=$(splitup_ipv6addr "$gip_addr")
gip="$(echo $gip_addr | grep -oE '^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$')"
fi
json_add_string "groupaddr" "$gip"
json_add_array "clients"
grp_obj_added=1
@ -94,7 +132,12 @@ read_mcast_stats() {
json_add_object ""
host_ip="$(echo $line | awk -F ' ' '{ print $14 }')"
h_ip="$(ipcalc.sh $host_ip | grep IP | awk '{print substr($0,4)}')"
if [ -n "$(echo $host_ip | grep -oE "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$")" ]; then
h_ip="$(ipcalc.sh $host_ip | grep IP | awk '{print substr($0,4)}')"
else
host_ip=$(splitup_ipv6addr "$host_ip")
h_ip="$(echo $host_ip | grep -oE '^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$')"
fi
json_add_string "ipaddr" "$h_ip"
src_port="$(echo $line | awk -F ' ' '{ print $2 }')"
json_add_string "device" "$src_port"
@ -103,7 +146,7 @@ read_mcast_stats() {
json_close_object #close the associated device object
;;
esac
done < /tmp/igmp_stats
done < "$TEMPFILE"
if [ $grp_obj_added -eq 1 ]; then
json_close_array #close the associated devices array
json_close_object # close the groups object
@ -112,10 +155,20 @@ read_mcast_stats() {
json_close_array #close the groups array
json_close_object # close the snooping object
done # close the loop for interfaces
}
read_mcast_stats() {
echo -n > "$TEMPFILE"
json_init
json_add_array "snooping"
meld_files "igmp"
meld_files "mld"
read_snooping_file
json_close_array # close the snooping array
json_dump
rm -f /tmp/igmp_stats
rm -f "$TEMPFILE"
}
case "$1" in
@ -129,7 +182,7 @@ case "$1" in
if [ -z "${out}" ]; then
echo '{}'
else
echo ${out}
echo "${out}"
fi
;;
esac

View file

@ -3,12 +3,46 @@
. /usr/share/libubox/jshn.sh
. /lib/functions.sh
read_mcast_stats() {
local temp_igmp_file='/tmp/igmp_stats_'$$
local snooping_stats='/tmp/igmp_snooping_stats'
readonly TEMPFILE="/tmp/snooping_stats_"$$
mcast_snooping_interface() {
local interface intf gip vid port
config_get interface "$1" interface
for intf in $interface; do
[ -z "$(bridge mdb show dev "$intf" 2> /dev/null | grep -v -F "port ${intf} " | xargs)" ] && continue
json_add_object ""
json_add_string "interface" "$intf"
json_add_array "groups"
for gip in $(bridge mdb show dev "$intf" | grep -v -F "port ${intf} " | cut -f6 -d' ' | sort -u | xargs); do
json_add_object ""
json_add_string "groupaddr" "$gip"
json_add_array "clients"
for port in $(bridge mdb show dev "$intf" | grep -v -F "port ${intf} " | grep -F "grp ${gip} " | cut -f4 -d' ' | sort -u | xargs); do
json_add_object ""
json_add_string "device" "$port"
for vid in $(bridge mdb show dev "$intf" | grep -F "port ${port} grp ${gip} " | grep -F ' vid ' | cut -f9 -d' ' | sort -u | xargs); do
json_add_object ""
json_add_string "vid" "$vid"
json_close_object #close the associated vid object
done
json_close_object #close the associated device object
done
json_close_array #close the associated devices array
json_close_object # close the groups object
done # close the loop for group addresses
json_close_array #close the groups array
json_close_object # close the snooping object
done # close the loop for interfaces
}
meld_files() {
local type="$1"
local snooping_stats="/tmp/${type}_snooping_stats"
local old_mod_time=$(date +%s 2>/dev/null -r "$snooping_stats")
# Sending signal to mcproxy to dump multicast data in /tmp/igmp_snooping_stats
# Sending signal to mcproxy to dump multicast data in /tmp/${type}_snooping_stats
local mcast_pids=$(pidof mcproxy)
for pid in $mcast_pids
do
@ -24,8 +58,11 @@ read_mcast_stats() {
done
fi
cat "$snooping_stats" > "$temp_igmp_file"
[ ! -e "$snooping_stats" ] && return 0
cat "$snooping_stats" >> "$TEMPFILE"
}
read_snooping_file() {
local mcast_addrs=""
local ifaces=""
@ -54,7 +91,7 @@ read_mcast_stats() {
fi
;;
esac
done < "$temp_igmp_file"
done < "$TEMPFILE"
while read line; do
# reading each line
@ -81,10 +118,8 @@ read_mcast_stats() {
fi
;;
esac
done < "$temp_igmp_file"
done < "$TEMPFILE"
json_init
json_add_array "snooping"
IFS=" "
for intf in $ifaces; do
json_add_object ""
@ -107,7 +142,11 @@ read_mcast_stats() {
fi
if [ $grp_obj_added -eq 0 ]; then
json_add_object ""
gip="$(ipcalc.sh $gip_addr | grep IP | awk '{print substr($0,4)}')"
if [ -n "$(echo $gip_addr | grep -oE "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$")" ]; then
gip="$(ipcalc.sh $gip_addr | grep IP | awk '{print substr($0,4)}')"
else
gip="$(echo $gip_addr | grep -oE '^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$')"
fi
json_add_string "groupaddr" "$gip"
json_add_array "clients"
grp_obj_added=1
@ -115,7 +154,11 @@ read_mcast_stats() {
json_add_object ""
host_ip="$(echo $line | awk -F ' ' '{ print $3 }')"
h_ip="$(ipcalc.sh $host_ip | grep IP | awk '{print substr($0,4)}')"
if [ -n "$(echo $host_ip | grep -oE "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$")" ]; then
h_ip="$(ipcalc.sh $host_ip | grep IP | awk '{print substr($0,4)}')"
else
h_ip="$(echo $host_ip | grep -oE '^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$')"
fi
json_add_string "ipaddr" "$h_ip"
src_port="$(echo $line | awk -F ' ' '{ print $4 }')"
json_add_string "device" "$src_port"
@ -124,7 +167,7 @@ read_mcast_stats() {
json_close_object #close the associated device object
;;
esac
done < "$temp_igmp_file"
done < "$TEMPFILE"
if [ $grp_obj_added -eq 1 ]; then
json_close_array #close the associated devices array
json_close_object # close the groups object
@ -133,10 +176,23 @@ read_mcast_stats() {
json_close_array #close the groups array
json_close_object # close the snooping object
done # close the loop for interfaces
}
read_mcast_stats() {
echo -n > "$TEMPFILE"
json_init
json_add_array "snooping"
meld_files "igmp"
meld_files "mld"
read_snooping_file
# L2 Snooping goes here
config_load mcast
config_foreach mcast_snooping_interface "snooping"
json_close_array # close the snooping array
json_dump
rm -f "$temp_igmp_file"
rm -f "$TEMPFILE"
}
case "$1" in