diff options
-rw-r--r-- | sys/netinet/in.c | 8 | ||||
-rwxr-xr-x | tests/sys/netinet/fibs_test.sh | 94 |
2 files changed, 99 insertions, 3 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 13cce0f..be26ecd 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -987,11 +987,9 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) { struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; - int error = 0, fibnum; + int error = 0; struct sockaddr_in prefix0, mask0; - fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; - /* * Remove the loopback route to the interface address. * The "useloopback" setting is not consulted because if the @@ -1046,6 +1044,10 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) } if ((target->ia_flags & IFA_ROUTE) == 0) { + int fibnum; + + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : + target->ia_ifp->if_fib; rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum); return (0); } diff --git a/tests/sys/netinet/fibs_test.sh b/tests/sys/netinet/fibs_test.sh index 95a8faa..72ebcfc 100755 --- a/tests/sys/netinet/fibs_test.sh +++ b/tests/sys/netinet/fibs_test.sh @@ -213,6 +213,98 @@ default_route_with_multiple_fibs_on_same_subnet_cleanup() } +# Regression test for PR kern/189089 +# Create two tap interfaces and assign them both the same IP address but with +# different netmasks, and both on the default FIB. Then remove one's IP +# address. Hopefully the machine won't panic. +atf_test_case same_ip_multiple_ifaces_fib0 cleanup +same_ip_multiple_ifaces_fib0_head() +{ + atf_set "descr" "Can remove an IP alias from an interface when the same IP is also assigned to another interface." + atf_set "require.user" "root" + atf_set "require.config" "fibs" +} +same_ip_multiple_ifaces_fib0_body() +{ + ADDR="192.0.2.2" + MASK0="24" + MASK1="32" + + # Unlike most of the tests in this file, this is applicable regardless + # of net.add_addr_allfibs + + # Setup the interfaces, then remove one alias. It should not panic. + setup_tap 0 ${ADDR} ${MASK0} + TAP0=${TAP} + setup_tap 0 ${ADDR} ${MASK1} + TAP1=${TAP} + ifconfig ${TAP1} -alias ${ADDR} + + # Do it again, in the opposite order. It should not panic. + setup_tap 0 ${ADDR} ${MASK0} + TAP0=${TAP} + setup_tap 0 ${ADDR} ${MASK1} + TAP1=${TAP} + ifconfig ${TAP0} -alias ${ADDR} +} +same_ip_multiple_ifaces_fib0_cleanup() +{ + cleanup_tap +} + +# Regression test for PR kern/189088 +# Test that removing an IP address works even if the same IP is assigned to a +# different interface, on a different FIB. Tests the same code that whose +# panic was regressed by same_ip_multiple_ifaces_fib0. +# Create two tap interfaces and assign them both the same IP address but with +# different netmasks, and on different FIBs. Then remove one's IP +# address. Hopefully the machine won't panic. Also, the IP's hostroute should +# dissappear from the correct fib. +atf_test_case same_ip_multiple_ifaces cleanup +same_ip_multiple_ifaces_head() +{ + atf_set "descr" "Can remove an IP alias from an interface when the same IP is also assigned to another interface, on non-default FIBs." + atf_set "require.user" "root" + atf_set "require.config" "fibs" +} +same_ip_multiple_ifaces_body() +{ + atf_expect_fail "kern/189088 Assigning the same IP to multiple interfaces in different FIBs creates a host route for only one" + ADDR="192.0.2.2" + MASK0="24" + MASK1="32" + + # Unlike most of the tests in this file, this is applicable regardless + # of net.add_addr_allfibs + get_fibs 2 + + # Setup the interfaces, then remove one alias. It should not panic. + setup_tap ${FIB0} ${ADDR} ${MASK0} + TAP0=${TAP} + setup_tap ${FIB1} ${ADDR} ${MASK1} + TAP1=${TAP} + ifconfig ${TAP1} -alias ${ADDR} + atf_check -o not-match:"^${ADDR}[[:space:]]" \ + setfib ${FIB1} netstat -rn -f inet + + # Do it again, in the opposite order. It should not panic. + setup_tap ${FIB0} ${ADDR} ${MASK0} + TAP0=${TAP} + setup_tap ${FIB1} ${ADDR} ${MASK1} + TAP1=${TAP} + ifconfig ${TAP0} -alias ${ADDR} + atf_check -o not-match:"^${ADDR}[[:space:]]" \ + setfib ${FIB0} netstat -rn -f inet +} +same_ip_multiple_ifaces_cleanup() +{ + # Due to PR kern/189088, we must destroy the interfaces in LIFO order + # in order for the routes to be correctly cleaned up. + for TAPD in `tail -r "tap_devices_to_cleanup"`; do + ifconfig ${TAPD} destroy + done +} + # Regression test for kern/187550 atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup subnet_route_with_multiple_fibs_on_same_subnet_head() @@ -322,6 +414,8 @@ atf_init_test_cases() atf_add_test_case arpresolve_checks_interface_fib atf_add_test_case loopback_and_network_routes_on_nondefault_fib atf_add_test_case default_route_with_multiple_fibs_on_same_subnet + atf_add_test_case same_ip_multiple_ifaces_fib0 + atf_add_test_case same_ip_multiple_ifaces atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet atf_add_test_case udp_dontroute } |