Commit 453abc48 authored by Kirill Smelkov's avatar Kirill Smelkov

My debug scripts/programs used to debug multicast routing in Linux kernel and overall

parent 3e684fcf
......@@ -2,3 +2,4 @@ A
B
C
D
pim-dm_*.yaml
#!/bin/bash
~/src/wendelin/wendelin.core/t/qemu-runlinux -v \
~/src/linux/obj-qemu_debug/arch/x86/boot/bzImage \
./linux-dbg.sh
#!/bin/bash
mount -t tmpfs none t
cd t
../topo-mr-debug.sh test_local
#!/bin/bash -e
# topo mr-debug creates simple A-B topology as a playground for multicast routing debugging
# on A routes are setup in fully static way - without smcrouted
# on B smcrouted is running
#
# run as e.g. ./topo-mr-debug test_locallocal
# whether to use use mcast_rx/mcast_tx interfaces instead of lo
# see
#
# https://lab.nexedi.com/kirr/linux/commit/25bcc76020c5 and
# https://lab.nexedi.com/kirr/linux/commit/43eadf90a7a6
#
# for why lo does not work out of the box.
use_mcast_rxtx_instead_of_lo=y
# whether to use IPv4 or IPv6 for tests
IPvX=6
tx=tx$IPvX
rx=rx$IPvX
txrx=txrx$IPvX
# ----------------------------------------
. $(dirname $0)/lib.sh
if [ $# = 0 ]; then
echo "Usage: $0 test_<...>"
exit 1
fi
xnewhost A
xnewhost B
xlink A B
# Bshow ... displays ... and runs it inside B.
Bshow() {
echo -e "\n>>>" "$@"
xnsenter B -- "$@"
}
if [ $use_mcast_rxtx_instead_of_lo = n ]; then
mrx=lo
mtx=lo
else
mrx=mcast-rx
mtx=mcast-tx
# mrx <-> mtx veth pair
xnsenter B -- ip link add $mrx type veth peer name $mtx
xnsenter B -- ip link set $mrx up
xnsenter B -- ip link set $mtx up
# programs from local host will be sending multicast via mtx (having default route for multicast addresses)
# those packets will be delivered back to local delivery via mrx <- mtx
# tell IPv4 routing not to reject them
# NOTE IPv6 does not need this
xnsenter B -- sysctl net.ipv4.conf.mcast-rx.accept_local=1
fi
xnsenter A -- ip addr add 1.0.0.1/24 dev a-b
xnsenter A -- ip addr add 1::1/16 dev a-b
# A: hardcoded route to send multicast to (no need for IPv6 - it gets setup'ed automatically via A-B MLD)
xnsenter A -- ip r add 224.0.0.0/4 dev a-b
xnsenter B -- ip addr add 2.0.0.2/24 dev $mtx scope global
xnsenter B -- ip addr add 2::2/16 dev $mtx scope global
# sleep a bit so that IPv6 address is activated for real on $mtx
# if we don't delay - vvv `ip -6 route ... dev $mtx src ...` fails with "Error: Invalid source address".
#
# XXX isn't it a kernel bug that we have to delay?
# XXX and why delay 3s? (with 1s it always fails, with 2s it still fails sometimes)
sleep 3
# from-external multicast traffic goes to lo
# from-us multicast traffic is sent to the world via lo too
# add explicit rule to route global multicast traffic to lo instead of relying on ad-hoc hack inside Linux kernel:
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/route.c?id=v5.18-rc5-28-ga7391ad35724#n2747
# (see "Apparently, routing tables are wrong. Assume, that the destination is on link." there)
# (present starting from very long ago: Linux 2.1.68 year=1997)
#
# As we are establishing route for multicast, also explicitly specify preferred
# source address with which to send from-us multicast traffic with.
#
# For table local pref ... - see IPv6 case vvv for the rationale. Probably for
# IPv4 this is not strictly required, but we still do it just in case.
xnsenter B -- ip r add multicast 224.0.0.0/4 oif $mtx dev $mtx scope global \
table local pref high metric 1 \
src 2.0.0.2
# for IPv6 similar explicit mcast route -> lo is required, because IPv6 routing does not have in-kernel ad-hoc that IPv4 has.
# NOTE Linux, unless patched, turns such lo-routes into rejects, so it won't work without patch to the kernel:
# https://lab.nexedi.com/kirr/linux/commit/25bcc76020c5
#
# Put this route into "local" table with highest possible preference to force
# the kernel to use it even if a neighbour node advertises via MLD its multicast capabilities.
# Upon receiving MLD messages the kernel creates `pref medium` routes in `table
# local`, so if we don't adjust "priority" of our route, it will become ignored.
#
# Also explicitly specify source address.
xnsenter B -- ip r add multicast ff1e::/16 oif $mtx dev $mtx scope global \
table local pref high metric 1 \
src 2::2 \
# debug dump of setup routing
Bdebug() {
Bshow ip link
Bshow ip addr
Bshow ip rule
Bshow ip route show table all ;
# Bshow ip r get 2.0.0.17
Bshow ip -d r get 224.1.1.1
Bshow ip -d r get 224.1.1.1 fibmatch
Bshow ip -d r get 224.1.1.1 oif $mtx
Bshow ip -d r get 224.1.1.1 oif $mtx fibmatch # NOTE: fails without explicit multicast -> lo route
Bshow ip -6 r show table local
Bshow ip -6 r show table main
Bshow ip -6 r show cache
Bshow ip -d r get ff1e::1
Bshow ip -d r get ff1e::1 fibmatch
Bshow ip -d r get ff1e::1 oif $mtx
Bshow ip -d r get ff1e::1 oif $mtx fibmatch
Bshow ip -6 r show cache
Bshow ip mr
Bshow ip -6 mr
}
#Bdebug
echo
echo '---------------------------'
echo
# B: start and setup mrouted
Bstartmrouted() {
xnsenter B -- smcrouted -n -l debug &
sleep 1
xnsenter B -- smcroutectl add b-a 1.0.0.1 224.0.0.0/4 $mtx
xnsenter B -- smcroutectl add b-a 1::1 ff1e::/16 $mtx
# multicast originating from local host is forwarded to external interfaces
# NOTE when we are sending via mtx, the kernel does not notify mrouted about
# mtx - only about packets on mrx - so we hook into mrx instead of directly
# into mtx.
xnsenter B -- smcroutectl add $mrx 2.0.0.2 224.0.0.0/4 b-a
xnsenter B -- smcroutectl add $mrx 2::2 ff1e::/16 b-a
#(sleep 4 && Bmrtdump ) &
}
# debug dump from inside about what happens with (m)routing
Bmrtdump() {
Bshow smcroutectl
Bshow ip rule
Bshow ip route show table all
Bshow ip mr
Bshow ip r get 224.1.1.1 oif b-a
Bshow ip r get 224.1.1.1 oif $mtx ;
#Bshow ip r get 224.1.1.1 from 1.0.0.1 oif lo # Network is unreachable
Bshow ip r get 224.1.1.1 from 1.0.0.1 iif b-a
#Bshow ip r get 224.1.1.1 iif b-a Invalid argument
#Bshow ip r get 224.1.1.1 Network is unreachable
#Bshow ip r get 224.1.1.1 fibmatch Network is unreachable
Bshow ip -6 mr
Bshow ip -6 r get ff1e::1 fibmatch
Bshow ip -6 r get ff1e::1
#Bshow cat /proc/net/route
#Bshow cat /proc/net/fib_trie
#Bshow cat /proc/net/ipv6_route
}
# local->local delivery
test_locallocal() {
# Bstartmrouted - not started
#xnsenter B -- tshark -lni $mtx &
xnsenter B -- $(dirname $0)/tmcast.py $txrx B
}
# test ext->local delivery
test_extlocal() {
Bstartmrouted
( sleep 2 && echo -e "\n\n\n\n\n" && xnsenter A -- $(dirname $0)/tmcast.py $tx A ) &
xnsenter B -- $(dirname $0)/tmcast.py $rx
}
# test ext<-local
test_localext() {
Bstartmrouted
( echo -e "\n\n\n\n\n" && xnsenter A -- $(dirname $0)/tmcast.py $rx ) &
sleep 2; xnsenter B -- $(dirname $0)/tmcast.py $tx B
}
# eval commandline arguments
"$*"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment