mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Merge branch 'ipv6-honor-oif-when-choosing-nexthop-for-locally-generated-traffic'
Ido Schimmel says: ==================== ipv6: Honor oif when choosing nexthop for locally generated traffic Patch #1 is a preparation patch following the comment from Sashiko on v2. See details in the commit message. Patch #2 aligns IPv6 with IPv4 and changes IPv6 route lookup to prefer a nexthop whose nexthop device matches the specified oif. Patch #3 adds a selftest. ==================== Link: https://patch.msgid.link/20260611154605.992528-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
48ecce1f33
|
|
@ -819,9 +819,11 @@ static int rt6_nh_find_match(struct fib6_nh *nh, void *_arg)
|
|||
{
|
||||
struct fib6_nh_frl_arg *arg = _arg;
|
||||
|
||||
arg->nh = nh;
|
||||
return find_match(nh, arg->flags, arg->oif, arg->strict,
|
||||
arg->mpri, arg->do_rr);
|
||||
if (find_match(nh, arg->flags, arg->oif, arg->strict, arg->mpri,
|
||||
arg->do_rr))
|
||||
arg->nh = nh;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __find_rr_leaf(struct fib6_info *f6i_start,
|
||||
|
|
@ -861,11 +863,10 @@ static void __find_rr_leaf(struct fib6_info *f6i_start,
|
|||
res->nh = nexthop_fib6_nh(f6i->nh);
|
||||
return;
|
||||
}
|
||||
if (nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match,
|
||||
&arg)) {
|
||||
matched = true;
|
||||
nh = arg.nh;
|
||||
}
|
||||
nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match,
|
||||
&arg);
|
||||
matched = !!arg.nh;
|
||||
nh = arg.nh;
|
||||
} else {
|
||||
nh = f6i->fib6_nh;
|
||||
if (find_match(nh, f6i->fib6_flags, oif, strict,
|
||||
|
|
@ -2275,6 +2276,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
|
|||
{
|
||||
struct fib6_result res = {};
|
||||
struct rt6_info *rt = NULL;
|
||||
bool have_oif_match;
|
||||
int strict = 0;
|
||||
|
||||
WARN_ON_ONCE((flags & RT6_LOOKUP_F_DST_NOREF) &&
|
||||
|
|
@ -2291,7 +2293,9 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
|
|||
if (res.f6i == net->ipv6.fib6_null_entry)
|
||||
goto out;
|
||||
|
||||
fib6_select_path(net, &res, fl6, oif, false, skb, strict);
|
||||
have_oif_match = fl6->flowi6_iif == LOOPBACK_IFINDEX &&
|
||||
oif == res.nh->fib_nh_dev->ifindex;
|
||||
fib6_select_path(net, &res, fl6, oif, have_oif_match, skb, strict);
|
||||
|
||||
/*Search through exception table */
|
||||
rt = rt6_find_cached_rt(&res, &fl6->daddr, &fl6->saddr);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
|
|||
ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
|
||||
ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
|
||||
ipv4_mpath_list ipv6_mpath_list ipv4_mpath_balance ipv6_mpath_balance \
|
||||
ipv4_mpath_balance_preferred fib6_ra_to_static fib6_temp_addr_renewal"
|
||||
ipv4_mpath_balance_preferred ipv4_mpath_oif ipv4_mpath_oif_nh \
|
||||
ipv4_mpath_oif_vrf ipv6_mpath_oif ipv6_mpath_oif_nh ipv6_mpath_oif_vrf \
|
||||
fib6_ra_to_static fib6_temp_addr_renewal"
|
||||
|
||||
VERBOSE=0
|
||||
PAUSE_ON_FAIL=no
|
||||
|
|
@ -2971,6 +2973,247 @@ ipv6_mpath_balance_test()
|
|||
forwarding_cleanup
|
||||
}
|
||||
|
||||
ipv4_mpath_oif_test_common()
|
||||
{
|
||||
local get_param=$1; shift
|
||||
local expected_oif=$1; shift
|
||||
local test_name=$1; shift
|
||||
local tmp_file
|
||||
|
||||
tmp_file=$(mktemp)
|
||||
|
||||
for i in {1..100}; do
|
||||
$IP route get 203.0.113.${i} $get_param >> "$tmp_file"
|
||||
done
|
||||
|
||||
[[ $(grep "$expected_oif" "$tmp_file" | wc -l) -eq 100 ]]
|
||||
log_test $? 0 "$test_name"
|
||||
|
||||
rm "$tmp_file"
|
||||
}
|
||||
|
||||
ipv4_mpath_oif_test()
|
||||
{
|
||||
echo
|
||||
echo "IPv4 multipath oif test"
|
||||
|
||||
setup
|
||||
|
||||
set -e
|
||||
$IP link add dummy1 up type dummy
|
||||
$IP address add 192.0.2.1/28 dev dummy1
|
||||
$IP address add 192.0.2.17/32 dev lo
|
||||
|
||||
$IP route add 203.0.113.0/24 \
|
||||
nexthop via 198.51.100.2 dev dummy0 \
|
||||
nexthop via 192.0.2.2 dev dummy1
|
||||
set +e
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy0" "dummy0" \
|
||||
"IPv4 multipath via first nexthop"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy1" "dummy1" \
|
||||
"IPv4 multipath via second nexthop"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy0 from 192.0.2.17" "dummy0" \
|
||||
"IPv4 multipath via first nexthop with source address"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy1 from 192.0.2.17" "dummy1" \
|
||||
"IPv4 multipath via second nexthop with source address"
|
||||
|
||||
cleanup
|
||||
}
|
||||
|
||||
ipv4_mpath_oif_nh_test()
|
||||
{
|
||||
echo
|
||||
echo "IPv4 multipath oif with nexthop object test"
|
||||
|
||||
setup
|
||||
|
||||
set -e
|
||||
$IP link add dummy1 up type dummy
|
||||
$IP address add 192.0.2.1/28 dev dummy1
|
||||
$IP address add 192.0.2.17/32 dev lo
|
||||
|
||||
$IP nexthop add id 1 via 198.51.100.2 dev dummy0
|
||||
$IP nexthop add id 2 via 192.0.2.2 dev dummy1
|
||||
$IP nexthop add id 3 group 1/2
|
||||
$IP route add 203.0.113.0/24 nhid 3
|
||||
set +e
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy0" "dummy0" \
|
||||
"IPv4 multipath via first nexthop"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy1" "dummy1" \
|
||||
"IPv4 multipath via second nexthop"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy0 from 192.0.2.17" "dummy0" \
|
||||
"IPv4 multipath via first nexthop with source address"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy1 from 192.0.2.17" "dummy1" \
|
||||
"IPv4 multipath via second nexthop with source address"
|
||||
|
||||
cleanup
|
||||
}
|
||||
|
||||
ipv4_mpath_oif_vrf_test()
|
||||
{
|
||||
echo
|
||||
echo "IPv4 multipath oif with VRF test"
|
||||
|
||||
setup
|
||||
|
||||
set -e
|
||||
$IP -4 rule add pref 32765 table local
|
||||
$IP -4 rule del pref 0
|
||||
$IP link add name vrf-123 up type vrf table 123
|
||||
$IP link set dev dummy0 master vrf-123
|
||||
$IP link add dummy1 up master vrf-123 type dummy
|
||||
$IP address add 192.0.2.1/28 dev dummy1
|
||||
$IP address add 192.0.2.17/32 dev vrf-123
|
||||
|
||||
$IP route add 203.0.113.0/24 vrf vrf-123 \
|
||||
nexthop via 198.51.100.2 dev dummy0 \
|
||||
nexthop via 192.0.2.2 dev dummy1
|
||||
set +e
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy0" "dummy0" \
|
||||
"IPv4 multipath via first nexthop"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy1" "dummy1" \
|
||||
"IPv4 multipath via second nexthop"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy0 from 192.0.2.17" "dummy0" \
|
||||
"IPv4 multipath via first nexthop with source address"
|
||||
|
||||
ipv4_mpath_oif_test_common "oif dummy1 from 192.0.2.17" "dummy1" \
|
||||
"IPv4 multipath via second nexthop with source address"
|
||||
|
||||
cleanup
|
||||
}
|
||||
|
||||
ipv6_mpath_oif_test_common()
|
||||
{
|
||||
local get_param=$1; shift
|
||||
local expected_oif=$1; shift
|
||||
local test_name=$1; shift
|
||||
local tmp_file
|
||||
|
||||
tmp_file=$(mktemp)
|
||||
|
||||
for i in {1..100}; do
|
||||
$IP route get 2001:db8:10::${i} $get_param >> "$tmp_file"
|
||||
done
|
||||
|
||||
[[ $(grep "$expected_oif" "$tmp_file" | wc -l) -eq 100 ]]
|
||||
log_test $? 0 "$test_name"
|
||||
|
||||
rm "$tmp_file"
|
||||
}
|
||||
|
||||
ipv6_mpath_oif_test()
|
||||
{
|
||||
echo
|
||||
echo "IPv6 multipath oif test"
|
||||
|
||||
setup
|
||||
|
||||
set -e
|
||||
$IP link add dummy1 up type dummy
|
||||
$IP address add 2001:db8:2::1/64 dev dummy1
|
||||
$IP address add 2001:db8:100::1/128 dev lo
|
||||
|
||||
$IP route add 2001:db8:10::/64 \
|
||||
nexthop via 2001:db8:1::2 dev dummy0 \
|
||||
nexthop via 2001:db8:2::2 dev dummy1
|
||||
set +e
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy0" "dummy0" \
|
||||
"IPv6 multipath via first nexthop"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy1" "dummy1" \
|
||||
"IPv6 multipath via second nexthop"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy0 from 2001:db8:100::1" "dummy0" \
|
||||
"IPv6 multipath via first nexthop with source address"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy1 from 2001:db8:100::1" "dummy1" \
|
||||
"IPv6 multipath via second nexthop with source address"
|
||||
|
||||
cleanup
|
||||
}
|
||||
|
||||
ipv6_mpath_oif_nh_test()
|
||||
{
|
||||
echo
|
||||
echo "IPv6 multipath oif with nexthop object test"
|
||||
|
||||
setup
|
||||
|
||||
set -e
|
||||
$IP link add dummy1 up type dummy
|
||||
$IP address add 2001:db8:2::1/64 dev dummy1
|
||||
$IP address add 2001:db8:100::1/128 dev lo
|
||||
|
||||
$IP nexthop add id 1 via 2001:db8:1::2 dev dummy0
|
||||
$IP nexthop add id 2 via 2001:db8:2::2 dev dummy1
|
||||
$IP nexthop add id 3 group 1/2
|
||||
$IP route add 2001:db8:10::/64 nhid 3
|
||||
set +e
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy0" "dummy0" \
|
||||
"IPv6 multipath via first nexthop"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy1" "dummy1" \
|
||||
"IPv6 multipath via second nexthop"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy0 from 2001:db8:100::1" "dummy0" \
|
||||
"IPv6 multipath via first nexthop with source address"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy1 from 2001:db8:100::1" "dummy1" \
|
||||
"IPv6 multipath via second nexthop with source address"
|
||||
|
||||
cleanup
|
||||
}
|
||||
|
||||
ipv6_mpath_oif_vrf_test()
|
||||
{
|
||||
echo
|
||||
echo "IPv6 multipath oif with VRF test"
|
||||
|
||||
setup
|
||||
|
||||
set -e
|
||||
$NS_EXEC sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
|
||||
$IP -6 rule add pref 32765 table local
|
||||
$IP -6 rule del pref 0
|
||||
$IP link add name vrf-123 up type vrf table 123
|
||||
$IP link set dev dummy0 master vrf-123
|
||||
$IP link add dummy1 up master vrf-123 type dummy
|
||||
$IP address add 2001:db8:2::1/64 dev dummy1
|
||||
$IP address add 2001:db8:100::1/128 dev vrf-123
|
||||
|
||||
$IP route add 2001:db8:10::/64 vrf vrf-123 \
|
||||
nexthop via 2001:db8:1::2 dev dummy0 \
|
||||
nexthop via 2001:db8:2::2 dev dummy1
|
||||
set +e
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy0" "dummy0" \
|
||||
"IPv6 multipath via first nexthop"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy1" "dummy1" \
|
||||
"IPv6 multipath via second nexthop"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy0 from 2001:db8:100::1" "dummy0" \
|
||||
"IPv6 multipath via first nexthop with source address"
|
||||
|
||||
ipv6_mpath_oif_test_common "oif dummy1 from 2001:db8:100::1" "dummy1" \
|
||||
"IPv6 multipath via second nexthop with source address"
|
||||
|
||||
cleanup
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# usage
|
||||
|
||||
|
|
@ -3057,6 +3300,12 @@ do
|
|||
ipv4_mpath_balance) ipv4_mpath_balance_test;;
|
||||
ipv6_mpath_balance) ipv6_mpath_balance_test;;
|
||||
ipv4_mpath_balance_preferred) ipv4_mpath_balance_preferred_test;;
|
||||
ipv4_mpath_oif) ipv4_mpath_oif_test;;
|
||||
ipv4_mpath_oif_nh) ipv4_mpath_oif_nh_test;;
|
||||
ipv4_mpath_oif_vrf) ipv4_mpath_oif_vrf_test;;
|
||||
ipv6_mpath_oif) ipv6_mpath_oif_test;;
|
||||
ipv6_mpath_oif_nh) ipv6_mpath_oif_nh_test;;
|
||||
ipv6_mpath_oif_vrf) ipv6_mpath_oif_vrf_test;;
|
||||
fib6_ra_to_static) fib6_ra_to_static;;
|
||||
fib6_temp_addr_renewal) fib6_temp_addr_renewal;;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user