aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r--net/ipv4/fib_semantics.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index f8c7ec8171a8..b5c3937ca6ec 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1457,6 +1457,56 @@ static int call_fib_nh_notifiers(struct fib_nh *fib_nh,
1457 return NOTIFY_DONE; 1457 return NOTIFY_DONE;
1458} 1458}
1459 1459
1460/* Update the PMTU of exceptions when:
1461 * - the new MTU of the first hop becomes smaller than the PMTU
1462 * - the old MTU was the same as the PMTU, and it limited discovery of
1463 * larger MTUs on the path. With that limit raised, we can now
1464 * discover larger MTUs
1465 * A special case is locked exceptions, for which the PMTU is smaller
1466 * than the minimal accepted PMTU:
1467 * - if the new MTU is greater than the PMTU, don't make any change
1468 * - otherwise, unlock and set PMTU
1469 */
1470static void nh_update_mtu(struct fib_nh *nh, u32 new, u32 orig)
1471{
1472 struct fnhe_hash_bucket *bucket;
1473 int i;
1474
1475 bucket = rcu_dereference_protected(nh->nh_exceptions, 1);
1476 if (!bucket)
1477 return;
1478
1479 for (i = 0; i < FNHE_HASH_SIZE; i++) {
1480 struct fib_nh_exception *fnhe;
1481
1482 for (fnhe = rcu_dereference_protected(bucket[i].chain, 1);
1483 fnhe;
1484 fnhe = rcu_dereference_protected(fnhe->fnhe_next, 1)) {
1485 if (fnhe->fnhe_mtu_locked) {
1486 if (new <= fnhe->fnhe_pmtu) {
1487 fnhe->fnhe_pmtu = new;
1488 fnhe->fnhe_mtu_locked = false;
1489 }
1490 } else if (new < fnhe->fnhe_pmtu ||
1491 orig == fnhe->fnhe_pmtu) {
1492 fnhe->fnhe_pmtu = new;
1493 }
1494 }
1495 }
1496}
1497
1498void fib_sync_mtu(struct net_device *dev, u32 orig_mtu)
1499{
1500 unsigned int hash = fib_devindex_hashfn(dev->ifindex);
1501 struct hlist_head *head = &fib_info_devhash[hash];
1502 struct fib_nh *nh;
1503
1504 hlist_for_each_entry(nh, head, nh_hash) {
1505 if (nh->nh_dev == dev)
1506 nh_update_mtu(nh, dev->mtu, orig_mtu);
1507 }
1508}
1509
1460/* Event force Flags Description 1510/* Event force Flags Description
1461 * NETDEV_CHANGE 0 LINKDOWN Carrier OFF, not for scope host 1511 * NETDEV_CHANGE 0 LINKDOWN Carrier OFF, not for scope host
1462 * NETDEV_DOWN 0 LINKDOWN|DEAD Link down, not for scope host 1512 * NETDEV_DOWN 0 LINKDOWN|DEAD Link down, not for scope host