diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 82d7acdd0710..e00f3b77c74c 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -942,6 +942,18 @@ ip_forward(struct mbuf *m, int srcrt) flowid = m->m_pkthdr.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->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); } else ia = NULL; diff --git a/tests/sys/netinet/forward.sh b/tests/sys/netinet/forward.sh index e16927a27d07..3ae83eb3edc5 100755 --- a/tests/sys/netinet/forward.sh +++ b/tests/sys/netinet/forward.sh @@ -259,6 +259,58 @@ fwd_ip_icmp_gw_slow_success_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() { @@ -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_iface_slow_success" atf_add_test_case "fwd_ip_icmp_gw_slow_success" + atf_add_test_case "fwd_ip_blackhole" } # end diff --git a/tests/sys/netinet6/forward6.sh b/tests/sys/netinet6/forward6.sh index b3ccd30aea62..40d17837d6f2 100755 --- a/tests/sys/netinet6/forward6.sh +++ b/tests/sys/netinet6/forward6.sh @@ -466,6 +466,59 @@ fwd_ip6_gu_icmp_gw_ll_slow_success_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() { @@ -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_gw_gu_slow_success" atf_add_test_case "fwd_ip6_gu_icmp_gw_ll_slow_success" + atf_add_test_case "fwd_ip6_blackhole" } # end