Skip to content

Commit f5bbe7e

Browse files
tracywwnjdavem330
authored andcommitted
ipv6: prepare rt6_mtu_change() for exception table
If we move all cached dst into the exception table under the main route, current rt6_mtu_change() will no longer be able to access them. This commit makes rt6_mtu_change_route() function to also go through all cached routes in the exception table under the main route and do proper updates on the mtu. This is a preparation in order to move all cached routes into the exception table. Signed-off-by: Wei Wang <[email protected]> Signed-off-by: Martin KaFai Lau <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 60006a4 commit f5bbe7e

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

net/ipv6/route.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,14 @@ static int rt6_insert_exception(struct rt6_info *nrt,
12691269
* in rt6_remove_prefsrc()
12701270
*/
12711271
nrt->rt6i_prefsrc = ort->rt6i_prefsrc;
1272+
/* rt6_mtu_change() might lower mtu on ort.
1273+
* Only insert this exception route if its mtu
1274+
* is less than ort's mtu value.
1275+
*/
1276+
if (nrt->rt6i_pmtu >= dst_mtu(&ort->dst)) {
1277+
err = -EINVAL;
1278+
goto out;
1279+
}
12721280

12731281
rt6_ex = __rt6_find_exception_spinlock(&bucket, &nrt->rt6i_dst.addr,
12741282
src_key);
@@ -1457,6 +1465,32 @@ static void rt6_exceptions_remove_prefsrc(struct rt6_info *rt)
14571465
}
14581466
}
14591467

1468+
static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu)
1469+
{
1470+
struct rt6_exception_bucket *bucket;
1471+
struct rt6_exception *rt6_ex;
1472+
int i;
1473+
1474+
bucket = rcu_dereference_protected(rt->rt6i_exception_bucket,
1475+
lockdep_is_held(&rt6_exception_lock));
1476+
1477+
if (bucket) {
1478+
for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) {
1479+
hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) {
1480+
struct rt6_info *entry = rt6_ex->rt6i;
1481+
/* For RTF_CACHE with rt6i_pmtu == 0
1482+
* (i.e. a redirected route),
1483+
* the metrics of its rt->dst.from has already
1484+
* been updated.
1485+
*/
1486+
if (entry->rt6i_pmtu && entry->rt6i_pmtu > mtu)
1487+
entry->rt6i_pmtu = mtu;
1488+
}
1489+
bucket++;
1490+
}
1491+
}
1492+
}
1493+
14601494
struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
14611495
int oif, struct flowi6 *fl6, int flags)
14621496
{
@@ -3296,6 +3330,10 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
32963330
if (rt->dst.dev == arg->dev &&
32973331
dst_metric_raw(&rt->dst, RTAX_MTU) &&
32983332
!dst_metric_locked(&rt->dst, RTAX_MTU)) {
3333+
spin_lock_bh(&rt6_exception_lock);
3334+
/* This case will be removed once the exception table
3335+
* is hooked up.
3336+
*/
32993337
if (rt->rt6i_flags & RTF_CACHE) {
33003338
/* For RTF_CACHE with rt6i_pmtu == 0
33013339
* (i.e. a redirected route),
@@ -3309,6 +3347,8 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
33093347
dst_mtu(&rt->dst) == idev->cnf.mtu6)) {
33103348
dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
33113349
}
3350+
rt6_exceptions_update_pmtu(rt, arg->mtu);
3351+
spin_unlock_bh(&rt6_exception_lock);
33123352
}
33133353
return 0;
33143354
}

0 commit comments

Comments
 (0)