1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-21 07:15:49 +00:00

netinet: handle blackhole routes

If during ip_forward() we find a blackhole (or reject) route we should stop
processing and count this in the 'cantforward' counter, just like we already do
for IPv6.
Blackhole routes are set to use the loopback interface, so we don't actually
incorrectly forward traffic, but we do fail to count it as unroutable.

Test this, both for IPv4 and IPv6.

Reviewed by:	melifaro
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D47529
This commit is contained in:
Kristof Provost 2024-11-12 16:55:50 +01:00
parent 4b65481ac6
commit e27970ae8f
3 changed files with 119 additions and 0 deletions

View File

@ -942,6 +942,18 @@ ip_forward(struct mbuf *m, int srcrt)
flowid = m->m_pkthdr.flowid; flowid = m->m_pkthdr.flowid;
ro.ro_nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_REF, flowid); ro.ro_nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_REF, flowid);
if (ro.ro_nh != NULL) { if (ro.ro_nh != NULL) {
if (ro.ro_nh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) {
IPSTAT_INC(ips_cantforward);
m_freem(m);
NH_FREE(ro.ro_nh);
return;
}
if (ro.ro_nh->nh_flags & NHF_REJECT) {
IPSTAT_INC(ips_cantforward);
NH_FREE(ro.ro_nh);
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
return;
}
ia = ifatoia(ro.ro_nh->nh_ifa); ia = ifatoia(ro.ro_nh->nh_ifa);
} else } else
ia = NULL; ia = NULL;

View File

@ -259,6 +259,58 @@ fwd_ip_icmp_gw_slow_success_cleanup() {
vnet_cleanup vnet_cleanup
} }
atf_test_case "fwd_ip_blackhole" "cleanup"
fwd_ip_blackhole_head() {
atf_set descr 'Test blackhole routes'
atf_set require.user root
}
fwd_ip_blackhole_body() {
jname="v4t-fwd_ip_blackhole"
vnet_init
epair=$(vnet_mkepair)
epair_out=$(vnet_mkepair)
ifconfig ${epair}a 192.0.2.2/24 up
vnet_mkjail ${jname} ${epair}b ${epair_out}b
jexec ${jname} ifconfig lo0 127.0.0.1/8 up
jexec ${jname} ifconfig ${epair}b 192.0.2.1/24 up
jexec ${jname} ifconfig ${epair_out}b 198.51.100.1/24 up
jexec ${jname} sysctl net.inet.ip.forwarding=1
route add default 192.0.2.1
atf_check -s exit:2 -o ignore \
ping -c 1 -t 1 198.51.100.2
atf_check -s exit:0 -o match:"0 packets not forwardable" \
jexec ${jname} netstat -s -p ip
# Create blackhole route
jexec ${jname} /sbin/route add 198.51.100.2 -blackhole -fib 0
jexec ${jname} netstat -rn
# Include an IP option to ensure slow path
atf_check -s exit:2 -o ignore \
ping -c 1 -t 1 -R 198.51.100.2
atf_check -s exit:0 -o match:"1 packet not forwardable" \
jexec ${jname} netstat -s -p ip
# Now try via the fast path
atf_check -s exit:2 -o ignore \
ping -c 1 -t 1 198.51.100.2
atf_check -s exit:0 -o match:"2 packets not forwardable" \
jexec ${jname} netstat -s -p ip
}
fwd_ip_blackhole_cleanup() {
vnet_cleanup
}
atf_init_test_cases() atf_init_test_cases()
{ {
@ -266,6 +318,7 @@ atf_init_test_cases()
atf_add_test_case "fwd_ip_icmp_gw_fast_success" atf_add_test_case "fwd_ip_icmp_gw_fast_success"
atf_add_test_case "fwd_ip_icmp_iface_slow_success" atf_add_test_case "fwd_ip_icmp_iface_slow_success"
atf_add_test_case "fwd_ip_icmp_gw_slow_success" atf_add_test_case "fwd_ip_icmp_gw_slow_success"
atf_add_test_case "fwd_ip_blackhole"
} }
# end # end

View File

@ -466,6 +466,59 @@ fwd_ip6_gu_icmp_gw_ll_slow_success_cleanup() {
vnet_cleanup vnet_cleanup
} }
atf_test_case "fwd_ip6_blackhole" "cleanup"
fwd_ip6_blackhole_head() {
atf_set descr 'Test blackhole routing'
atf_set require.user root
}
fwd_ip6_blackhole_body() {
jname="v6t-fwd_ip6_blackhole"
vnet_init
epair=$(vnet_mkepair)
epair_out=$(vnet_mkepair)
ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad
vnet_mkjail ${jname} ${epair}b ${epair_out}b
jexec ${jname} ifconfig lo0 inet6 ::1/128 up no_dad
jexec ${jname} ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad
jexec ${jname} ifconfig ${epair_out}b inet6 2001:db8:1::1/64 up no_dad
jexec ${jname} sysctl net.inet6.ip6.forwarding=1
route -6 add default 2001:db8::1
atf_check -s exit:2 -o ignore \
ping6 -c 1 -t 1 2001:db8:1::2
atf_check -s exit:0 -o match:"0 packets not forwardable" \
jexec ${jname} netstat -s -p ip6
# Create blackhole route
jexec ${jname} route -6 add 2001:db8:1::2 -blackhole
# Force slow path
jexec ${jname} sysctl net.inet6.ip6.redirect=1
atf_check -s exit:2 -o ignore \
ping6 -c 1 -t 1 2001:db8:1::2
atf_check -s exit:0 -o match:"1 packet not forwardable" \
jexec ${jname} netstat -s -p ip6
# Now try the fast path
jexec ${jname} sysctl net.inet6.ip6.redirect=0
atf_check -s exit:2 -o ignore \
ping6 -c 1 -t 1 2001:db8:1::2
atf_check -s exit:0 -o match:"2 packets not forwardable" \
jexec ${jname} netstat -s -p ip6
}
fwd_ip6_blackhole_cleanup() {
vnet_cleanup
}
atf_init_test_cases() atf_init_test_cases()
{ {
@ -475,6 +528,7 @@ atf_init_test_cases()
atf_add_test_case "fwd_ip6_gu_icmp_iface_slow_success" atf_add_test_case "fwd_ip6_gu_icmp_iface_slow_success"
atf_add_test_case "fwd_ip6_gu_icmp_gw_gu_slow_success" atf_add_test_case "fwd_ip6_gu_icmp_gw_gu_slow_success"
atf_add_test_case "fwd_ip6_gu_icmp_gw_ll_slow_success" atf_add_test_case "fwd_ip6_gu_icmp_gw_ll_slow_success"
atf_add_test_case "fwd_ip6_blackhole"
} }
# end # end