diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-10 09:58:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-11 01:40:14 -0400 |
commit | 5943634fc5592037db0693b261f7f4bea6bb9457 (patch) | |
tree | 4fdaf67e5be0df3c3067ff2a7febd28f118f02be | |
parent | 87a50699cb6d169591cc776fb82683a2c77cecac (diff) |
ipv4: Maintain redirect and PMTU info in struct rtable again.
Maintaining this in the inetpeer entries was not the right way to do
this at all.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/inetpeer.h | 4 | ||||
-rw-r--r-- | include/net/route.h | 2 | ||||
-rw-r--r-- | net/ipv4/inetpeer.c | 3 | ||||
-rw-r--r-- | net/ipv4/route.c | 185 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 1 |
5 files changed, 41 insertions, 154 deletions
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 1119f6f6cdb4..53f464d7cddc 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h | |||
@@ -36,10 +36,6 @@ struct inet_peer { | |||
36 | u32 metrics[RTAX_MAX]; | 36 | u32 metrics[RTAX_MAX]; |
37 | u32 rate_tokens; /* rate limiting for ICMP */ | 37 | u32 rate_tokens; /* rate limiting for ICMP */ |
38 | unsigned long rate_last; | 38 | unsigned long rate_last; |
39 | unsigned long pmtu_expires; | ||
40 | u32 pmtu_orig; | ||
41 | u32 pmtu_learned; | ||
42 | struct inetpeer_addr_base redirect_learned; | ||
43 | union { | 39 | union { |
44 | struct list_head gc_list; | 40 | struct list_head gc_list; |
45 | struct rcu_head gc_rcu; | 41 | struct rcu_head gc_rcu; |
diff --git a/include/net/route.h b/include/net/route.h index 635d7a99d199..c27449466d18 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -65,7 +65,7 @@ struct rtable { | |||
65 | __be32 rt_gateway; | 65 | __be32 rt_gateway; |
66 | 66 | ||
67 | /* Miscellaneous cached information */ | 67 | /* Miscellaneous cached information */ |
68 | u32 rt_peer_genid; | 68 | u32 rt_pmtu; |
69 | unsigned long _peer; /* long-living peer info */ | 69 | unsigned long _peer; /* long-living peer info */ |
70 | struct fib_info *fi; /* for client ref to shared metrics */ | 70 | struct fib_info *fi; /* for client ref to shared metrics */ |
71 | }; | 71 | }; |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index f457bcb41350..e1e0a4e8fd34 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -511,9 +511,6 @@ relookup: | |||
511 | p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; | 511 | p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; |
512 | p->rate_tokens = 0; | 512 | p->rate_tokens = 0; |
513 | p->rate_last = 0; | 513 | p->rate_last = 0; |
514 | p->pmtu_expires = 0; | ||
515 | p->pmtu_orig = 0; | ||
516 | memset(&p->redirect_learned, 0, sizeof(p->redirect_learned)); | ||
517 | INIT_LIST_HEAD(&p->gc_list); | 514 | INIT_LIST_HEAD(&p->gc_list); |
518 | 515 | ||
519 | /* Link the node. */ | 516 | /* Link the node. */ |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 67b08745daf9..677d65253e4c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -669,7 +669,7 @@ static inline int rt_fast_clean(struct rtable *rth) | |||
669 | static inline int rt_valuable(struct rtable *rth) | 669 | static inline int rt_valuable(struct rtable *rth) |
670 | { | 670 | { |
671 | return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) || | 671 | return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) || |
672 | (rt_has_peer(rth) && rt_peer_ptr(rth)->pmtu_expires); | 672 | rth->dst.expires; |
673 | } | 673 | } |
674 | 674 | ||
675 | static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2) | 675 | static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2) |
@@ -1242,13 +1242,6 @@ skip_hashing: | |||
1242 | return rt; | 1242 | return rt; |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | static atomic_t __rt_peer_genid = ATOMIC_INIT(0); | ||
1246 | |||
1247 | static u32 rt_peer_genid(void) | ||
1248 | { | ||
1249 | return atomic_read(&__rt_peer_genid); | ||
1250 | } | ||
1251 | |||
1252 | void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) | 1245 | void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) |
1253 | { | 1246 | { |
1254 | struct inet_peer_base *base; | 1247 | struct inet_peer_base *base; |
@@ -1262,8 +1255,6 @@ void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) | |||
1262 | if (peer) { | 1255 | if (peer) { |
1263 | if (!rt_set_peer(rt, peer)) | 1256 | if (!rt_set_peer(rt, peer)) |
1264 | inet_putpeer(peer); | 1257 | inet_putpeer(peer); |
1265 | else | ||
1266 | rt->rt_peer_genid = rt_peer_genid(); | ||
1267 | } | 1258 | } |
1268 | } | 1259 | } |
1269 | 1260 | ||
@@ -1323,30 +1314,6 @@ static void rt_del(unsigned int hash, struct rtable *rt) | |||
1323 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1314 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1324 | } | 1315 | } |
1325 | 1316 | ||
1326 | static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | ||
1327 | { | ||
1328 | struct rtable *rt = (struct rtable *) dst; | ||
1329 | __be32 orig_gw = rt->rt_gateway; | ||
1330 | struct neighbour *n; | ||
1331 | |||
1332 | dst_confirm(&rt->dst); | ||
1333 | |||
1334 | rt->rt_gateway = peer->redirect_learned.a4; | ||
1335 | |||
1336 | n = ipv4_neigh_lookup(&rt->dst, NULL, &rt->rt_gateway); | ||
1337 | if (!n) { | ||
1338 | rt->rt_gateway = orig_gw; | ||
1339 | return; | ||
1340 | } | ||
1341 | if (!(n->nud_state & NUD_VALID)) { | ||
1342 | neigh_event_send(n, NULL); | ||
1343 | } else { | ||
1344 | rt->rt_flags |= RTCF_REDIRECTED; | ||
1345 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); | ||
1346 | } | ||
1347 | neigh_release(n); | ||
1348 | } | ||
1349 | |||
1350 | /* called in rcu_read_lock() section */ | 1317 | /* called in rcu_read_lock() section */ |
1351 | void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | 1318 | void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, |
1352 | __be32 saddr, struct net_device *dev) | 1319 | __be32 saddr, struct net_device *dev) |
@@ -1355,7 +1322,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1355 | struct in_device *in_dev = __in_dev_get_rcu(dev); | 1322 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
1356 | __be32 skeys[2] = { saddr, 0 }; | 1323 | __be32 skeys[2] = { saddr, 0 }; |
1357 | int ikeys[2] = { dev->ifindex, 0 }; | 1324 | int ikeys[2] = { dev->ifindex, 0 }; |
1358 | struct inet_peer *peer; | ||
1359 | struct net *net; | 1325 | struct net *net; |
1360 | 1326 | ||
1361 | if (!in_dev) | 1327 | if (!in_dev) |
@@ -1388,6 +1354,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1388 | rthp = &rt_hash_table[hash].chain; | 1354 | rthp = &rt_hash_table[hash].chain; |
1389 | 1355 | ||
1390 | while ((rt = rcu_dereference(*rthp)) != NULL) { | 1356 | while ((rt = rcu_dereference(*rthp)) != NULL) { |
1357 | struct neighbour *n; | ||
1358 | |||
1391 | rthp = &rt->dst.rt_next; | 1359 | rthp = &rt->dst.rt_next; |
1392 | 1360 | ||
1393 | if (rt->rt_key_dst != daddr || | 1361 | if (rt->rt_key_dst != daddr || |
@@ -1401,13 +1369,16 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1401 | rt->rt_gateway != old_gw) | 1369 | rt->rt_gateway != old_gw) |
1402 | continue; | 1370 | continue; |
1403 | 1371 | ||
1404 | peer = rt_get_peer_create(rt, rt->rt_dst); | 1372 | n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); |
1405 | if (peer) { | 1373 | if (n) { |
1406 | if (peer->redirect_learned.a4 != new_gw) { | 1374 | if (!(n->nud_state & NUD_VALID)) { |
1407 | peer->redirect_learned.a4 = new_gw; | 1375 | neigh_event_send(n, NULL); |
1408 | atomic_inc(&__rt_peer_genid); | 1376 | } else { |
1377 | rt->rt_gateway = new_gw; | ||
1378 | rt->rt_flags |= RTCF_REDIRECTED; | ||
1379 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); | ||
1409 | } | 1380 | } |
1410 | check_peer_redir(&rt->dst, peer); | 1381 | neigh_release(n); |
1411 | } | 1382 | } |
1412 | } | 1383 | } |
1413 | } | 1384 | } |
@@ -1425,23 +1396,6 @@ reject_redirect: | |||
1425 | ; | 1396 | ; |
1426 | } | 1397 | } |
1427 | 1398 | ||
1428 | static bool peer_pmtu_expired(struct inet_peer *peer) | ||
1429 | { | ||
1430 | unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); | ||
1431 | |||
1432 | return orig && | ||
1433 | time_after_eq(jiffies, orig) && | ||
1434 | cmpxchg(&peer->pmtu_expires, orig, 0) == orig; | ||
1435 | } | ||
1436 | |||
1437 | static bool peer_pmtu_cleaned(struct inet_peer *peer) | ||
1438 | { | ||
1439 | unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); | ||
1440 | |||
1441 | return orig && | ||
1442 | cmpxchg(&peer->pmtu_expires, orig, 0) == orig; | ||
1443 | } | ||
1444 | |||
1445 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | 1399 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) |
1446 | { | 1400 | { |
1447 | struct rtable *rt = (struct rtable *)dst; | 1401 | struct rtable *rt = (struct rtable *)dst; |
@@ -1451,16 +1405,13 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
1451 | if (dst->obsolete > 0) { | 1405 | if (dst->obsolete > 0) { |
1452 | ip_rt_put(rt); | 1406 | ip_rt_put(rt); |
1453 | ret = NULL; | 1407 | ret = NULL; |
1454 | } else if (rt->rt_flags & RTCF_REDIRECTED) { | 1408 | } else if ((rt->rt_flags & RTCF_REDIRECTED) || |
1409 | rt->dst.expires) { | ||
1455 | unsigned int hash = rt_hash(rt->rt_key_dst, rt->rt_key_src, | 1410 | unsigned int hash = rt_hash(rt->rt_key_dst, rt->rt_key_src, |
1456 | rt->rt_oif, | 1411 | rt->rt_oif, |
1457 | rt_genid(dev_net(dst->dev))); | 1412 | rt_genid(dev_net(dst->dev))); |
1458 | rt_del(hash, rt); | 1413 | rt_del(hash, rt); |
1459 | ret = NULL; | 1414 | ret = NULL; |
1460 | } else if (rt_has_peer(rt)) { | ||
1461 | struct inet_peer *peer = rt_peer_ptr(rt); | ||
1462 | if (peer_pmtu_expired(peer)) | ||
1463 | dst_metric_set(dst, RTAX_MTU, peer->pmtu_orig); | ||
1464 | } | 1415 | } |
1465 | } | 1416 | } |
1466 | return ret; | 1417 | return ret; |
@@ -1604,50 +1555,17 @@ out: kfree_skb(skb); | |||
1604 | return 0; | 1555 | return 0; |
1605 | } | 1556 | } |
1606 | 1557 | ||
1607 | static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer) | ||
1608 | { | ||
1609 | unsigned long expires = ACCESS_ONCE(peer->pmtu_expires); | ||
1610 | |||
1611 | if (!expires) | ||
1612 | return; | ||
1613 | if (time_before(jiffies, expires)) { | ||
1614 | u32 orig_dst_mtu = dst_mtu(dst); | ||
1615 | if (peer->pmtu_learned < orig_dst_mtu) { | ||
1616 | if (!peer->pmtu_orig) | ||
1617 | peer->pmtu_orig = dst_metric_raw(dst, RTAX_MTU); | ||
1618 | dst_metric_set(dst, RTAX_MTU, peer->pmtu_learned); | ||
1619 | } | ||
1620 | } else if (cmpxchg(&peer->pmtu_expires, expires, 0) == expires) | ||
1621 | dst_metric_set(dst, RTAX_MTU, peer->pmtu_orig); | ||
1622 | } | ||
1623 | |||
1624 | static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | 1558 | static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) |
1625 | { | 1559 | { |
1626 | struct rtable *rt = (struct rtable *) dst; | 1560 | struct rtable *rt = (struct rtable *) dst; |
1627 | struct inet_peer *peer; | ||
1628 | 1561 | ||
1629 | dst_confirm(dst); | 1562 | dst_confirm(dst); |
1630 | 1563 | ||
1631 | peer = rt_get_peer_create(rt, rt->rt_dst); | 1564 | if (mtu < ip_rt_min_pmtu) |
1632 | if (peer) { | 1565 | mtu = ip_rt_min_pmtu; |
1633 | unsigned long pmtu_expires = ACCESS_ONCE(peer->pmtu_expires); | ||
1634 | |||
1635 | if (mtu < ip_rt_min_pmtu) | ||
1636 | mtu = ip_rt_min_pmtu; | ||
1637 | if (!pmtu_expires || mtu < peer->pmtu_learned) { | ||
1638 | |||
1639 | pmtu_expires = jiffies + ip_rt_mtu_expires; | ||
1640 | if (!pmtu_expires) | ||
1641 | pmtu_expires = 1UL; | ||
1642 | |||
1643 | peer->pmtu_learned = mtu; | ||
1644 | peer->pmtu_expires = pmtu_expires; | ||
1645 | 1566 | ||
1646 | atomic_inc(&__rt_peer_genid); | 1567 | rt->rt_pmtu = mtu; |
1647 | rt->rt_peer_genid = rt_peer_genid(); | 1568 | dst_set_expires(&rt->dst, ip_rt_mtu_expires); |
1648 | } | ||
1649 | check_peer_pmtu(dst, peer); | ||
1650 | } | ||
1651 | } | 1569 | } |
1652 | 1570 | ||
1653 | void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, | 1571 | void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, |
@@ -1679,30 +1597,12 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1679 | } | 1597 | } |
1680 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); | 1598 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); |
1681 | 1599 | ||
1682 | static void ipv4_validate_peer(struct rtable *rt) | ||
1683 | { | ||
1684 | if (rt->rt_peer_genid != rt_peer_genid()) { | ||
1685 | struct inet_peer *peer = rt_get_peer(rt, rt->rt_dst); | ||
1686 | |||
1687 | if (peer) { | ||
1688 | check_peer_pmtu(&rt->dst, peer); | ||
1689 | |||
1690 | if (peer->redirect_learned.a4 && | ||
1691 | peer->redirect_learned.a4 != rt->rt_gateway) | ||
1692 | check_peer_redir(&rt->dst, peer); | ||
1693 | } | ||
1694 | |||
1695 | rt->rt_peer_genid = rt_peer_genid(); | ||
1696 | } | ||
1697 | } | ||
1698 | |||
1699 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | 1600 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) |
1700 | { | 1601 | { |
1701 | struct rtable *rt = (struct rtable *) dst; | 1602 | struct rtable *rt = (struct rtable *) dst; |
1702 | 1603 | ||
1703 | if (rt_is_expired(rt)) | 1604 | if (rt_is_expired(rt)) |
1704 | return NULL; | 1605 | return NULL; |
1705 | ipv4_validate_peer(rt); | ||
1706 | return dst; | 1606 | return dst; |
1707 | } | 1607 | } |
1708 | 1608 | ||
@@ -1728,11 +1628,8 @@ static void ipv4_link_failure(struct sk_buff *skb) | |||
1728 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); | 1628 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); |
1729 | 1629 | ||
1730 | rt = skb_rtable(skb); | 1630 | rt = skb_rtable(skb); |
1731 | if (rt && rt_has_peer(rt)) { | 1631 | if (rt) |
1732 | struct inet_peer *peer = rt_peer_ptr(rt); | 1632 | dst_set_expires(&rt->dst, 0); |
1733 | if (peer_pmtu_cleaned(peer)) | ||
1734 | dst_metric_set(&rt->dst, RTAX_MTU, peer->pmtu_orig); | ||
1735 | } | ||
1736 | } | 1633 | } |
1737 | 1634 | ||
1738 | static int ip_rt_bug(struct sk_buff *skb) | 1635 | static int ip_rt_bug(struct sk_buff *skb) |
@@ -1812,7 +1709,13 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst) | |||
1812 | static unsigned int ipv4_mtu(const struct dst_entry *dst) | 1709 | static unsigned int ipv4_mtu(const struct dst_entry *dst) |
1813 | { | 1710 | { |
1814 | const struct rtable *rt = (const struct rtable *) dst; | 1711 | const struct rtable *rt = (const struct rtable *) dst; |
1815 | unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); | 1712 | unsigned int mtu = rt->rt_pmtu; |
1713 | |||
1714 | if (mtu && time_after_eq(jiffies, rt->dst.expires)) | ||
1715 | mtu = 0; | ||
1716 | |||
1717 | if (!mtu) | ||
1718 | mtu = dst_metric_raw(dst, RTAX_MTU); | ||
1816 | 1719 | ||
1817 | if (mtu && rt_is_output_route(rt)) | 1720 | if (mtu && rt_is_output_route(rt)) |
1818 | return mtu; | 1721 | return mtu; |
@@ -1843,19 +1746,10 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, | |||
1843 | peer = inet_getpeer_v4(base, rt->rt_dst, 0); | 1746 | peer = inet_getpeer_v4(base, rt->rt_dst, 0); |
1844 | if (peer) { | 1747 | if (peer) { |
1845 | __rt_set_peer(rt, peer); | 1748 | __rt_set_peer(rt, peer); |
1846 | rt->rt_peer_genid = rt_peer_genid(); | ||
1847 | if (inet_metrics_new(peer)) | 1749 | if (inet_metrics_new(peer)) |
1848 | memcpy(peer->metrics, fi->fib_metrics, | 1750 | memcpy(peer->metrics, fi->fib_metrics, |
1849 | sizeof(u32) * RTAX_MAX); | 1751 | sizeof(u32) * RTAX_MAX); |
1850 | dst_init_metrics(&rt->dst, peer->metrics, false); | 1752 | dst_init_metrics(&rt->dst, peer->metrics, false); |
1851 | |||
1852 | check_peer_pmtu(&rt->dst, peer); | ||
1853 | |||
1854 | if (peer->redirect_learned.a4 && | ||
1855 | peer->redirect_learned.a4 != rt->rt_gateway) { | ||
1856 | rt->rt_gateway = peer->redirect_learned.a4; | ||
1857 | rt->rt_flags |= RTCF_REDIRECTED; | ||
1858 | } | ||
1859 | } else { | 1753 | } else { |
1860 | if (fi->fib_metrics != (u32 *) dst_default_metrics) { | 1754 | if (fi->fib_metrics != (u32 *) dst_default_metrics) { |
1861 | rt->fi = fi; | 1755 | rt->fi = fi; |
@@ -1955,8 +1849,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1955 | rth->rt_iif = dev->ifindex; | 1849 | rth->rt_iif = dev->ifindex; |
1956 | rth->rt_oif = 0; | 1850 | rth->rt_oif = 0; |
1957 | rth->rt_mark = skb->mark; | 1851 | rth->rt_mark = skb->mark; |
1852 | rth->rt_pmtu = 0; | ||
1958 | rth->rt_gateway = daddr; | 1853 | rth->rt_gateway = daddr; |
1959 | rth->rt_peer_genid = 0; | ||
1960 | rt_init_peer(rth, dev_net(dev)->ipv4.peers); | 1854 | rt_init_peer(rth, dev_net(dev)->ipv4.peers); |
1961 | rth->fi = NULL; | 1855 | rth->fi = NULL; |
1962 | if (our) { | 1856 | if (our) { |
@@ -2081,8 +1975,8 @@ static int __mkroute_input(struct sk_buff *skb, | |||
2081 | rth->rt_iif = in_dev->dev->ifindex; | 1975 | rth->rt_iif = in_dev->dev->ifindex; |
2082 | rth->rt_oif = 0; | 1976 | rth->rt_oif = 0; |
2083 | rth->rt_mark = skb->mark; | 1977 | rth->rt_mark = skb->mark; |
1978 | rth->rt_pmtu = 0; | ||
2084 | rth->rt_gateway = daddr; | 1979 | rth->rt_gateway = daddr; |
2085 | rth->rt_peer_genid = 0; | ||
2086 | rt_init_peer(rth, &res->table->tb_peers); | 1980 | rt_init_peer(rth, &res->table->tb_peers); |
2087 | rth->fi = NULL; | 1981 | rth->fi = NULL; |
2088 | 1982 | ||
@@ -2260,8 +2154,8 @@ local_input: | |||
2260 | rth->rt_iif = dev->ifindex; | 2154 | rth->rt_iif = dev->ifindex; |
2261 | rth->rt_oif = 0; | 2155 | rth->rt_oif = 0; |
2262 | rth->rt_mark = skb->mark; | 2156 | rth->rt_mark = skb->mark; |
2157 | rth->rt_pmtu = 0; | ||
2263 | rth->rt_gateway = daddr; | 2158 | rth->rt_gateway = daddr; |
2264 | rth->rt_peer_genid = 0; | ||
2265 | rt_init_peer(rth, net->ipv4.peers); | 2159 | rt_init_peer(rth, net->ipv4.peers); |
2266 | rth->fi = NULL; | 2160 | rth->fi = NULL; |
2267 | if (res.type == RTN_UNREACHABLE) { | 2161 | if (res.type == RTN_UNREACHABLE) { |
@@ -2337,7 +2231,6 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2337 | rth->rt_mark == skb->mark && | 2231 | rth->rt_mark == skb->mark && |
2338 | net_eq(dev_net(rth->dst.dev), net) && | 2232 | net_eq(dev_net(rth->dst.dev), net) && |
2339 | !rt_is_expired(rth)) { | 2233 | !rt_is_expired(rth)) { |
2340 | ipv4_validate_peer(rth); | ||
2341 | if (noref) { | 2234 | if (noref) { |
2342 | dst_use_noref(&rth->dst, jiffies); | 2235 | dst_use_noref(&rth->dst, jiffies); |
2343 | skb_dst_set_noref(skb, &rth->dst); | 2236 | skb_dst_set_noref(skb, &rth->dst); |
@@ -2459,8 +2352,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2459 | rth->rt_iif = orig_oif ? : dev_out->ifindex; | 2352 | rth->rt_iif = orig_oif ? : dev_out->ifindex; |
2460 | rth->rt_oif = orig_oif; | 2353 | rth->rt_oif = orig_oif; |
2461 | rth->rt_mark = fl4->flowi4_mark; | 2354 | rth->rt_mark = fl4->flowi4_mark; |
2355 | rth->rt_pmtu = 0; | ||
2462 | rth->rt_gateway = fl4->daddr; | 2356 | rth->rt_gateway = fl4->daddr; |
2463 | rth->rt_peer_genid = 0; | ||
2464 | rt_init_peer(rth, (res->table ? | 2357 | rt_init_peer(rth, (res->table ? |
2465 | &res->table->tb_peers : | 2358 | &res->table->tb_peers : |
2466 | dev_net(dev_out)->ipv4.peers)); | 2359 | dev_net(dev_out)->ipv4.peers)); |
@@ -2717,7 +2610,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) | |||
2717 | (IPTOS_RT_MASK | RTO_ONLINK)) && | 2610 | (IPTOS_RT_MASK | RTO_ONLINK)) && |
2718 | net_eq(dev_net(rth->dst.dev), net) && | 2611 | net_eq(dev_net(rth->dst.dev), net) && |
2719 | !rt_is_expired(rth)) { | 2612 | !rt_is_expired(rth)) { |
2720 | ipv4_validate_peer(rth); | ||
2721 | dst_use(&rth->dst, jiffies); | 2613 | dst_use(&rth->dst, jiffies); |
2722 | RT_CACHE_STAT_INC(out_hit); | 2614 | RT_CACHE_STAT_INC(out_hit); |
2723 | rcu_read_unlock_bh(); | 2615 | rcu_read_unlock_bh(); |
@@ -2794,6 +2686,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
2794 | rt->rt_iif = ort->rt_iif; | 2686 | rt->rt_iif = ort->rt_iif; |
2795 | rt->rt_oif = ort->rt_oif; | 2687 | rt->rt_oif = ort->rt_oif; |
2796 | rt->rt_mark = ort->rt_mark; | 2688 | rt->rt_mark = ort->rt_mark; |
2689 | rt->rt_pmtu = ort->rt_pmtu; | ||
2797 | 2690 | ||
2798 | rt->rt_genid = rt_genid(net); | 2691 | rt->rt_genid = rt_genid(net); |
2799 | rt->rt_flags = ort->rt_flags; | 2692 | rt->rt_flags = ort->rt_flags; |
@@ -2896,13 +2789,13 @@ static int rt_fill_info(struct net *net, | |||
2896 | const struct inet_peer *peer = rt_peer_ptr(rt); | 2789 | const struct inet_peer *peer = rt_peer_ptr(rt); |
2897 | inet_peer_refcheck(peer); | 2790 | inet_peer_refcheck(peer); |
2898 | id = atomic_read(&peer->ip_id_count) & 0xffff; | 2791 | id = atomic_read(&peer->ip_id_count) & 0xffff; |
2899 | expires = ACCESS_ONCE(peer->pmtu_expires); | 2792 | } |
2900 | if (expires) { | 2793 | expires = rt->dst.expires; |
2901 | if (time_before(jiffies, expires)) | 2794 | if (expires) { |
2902 | expires -= jiffies; | 2795 | if (time_before(jiffies, expires)) |
2903 | else | 2796 | expires -= jiffies; |
2904 | expires = 0; | 2797 | else |
2905 | } | 2798 | expires = 0; |
2906 | } | 2799 | } |
2907 | 2800 | ||
2908 | if (rt_is_input_route(rt)) { | 2801 | if (rt_is_input_route(rt)) { |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 9815ea0bca7f..951bcf35b21c 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -100,6 +100,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
100 | xdst->u.rt.rt_src = rt->rt_src; | 100 | xdst->u.rt.rt_src = rt->rt_src; |
101 | xdst->u.rt.rt_dst = rt->rt_dst; | 101 | xdst->u.rt.rt_dst = rt->rt_dst; |
102 | xdst->u.rt.rt_gateway = rt->rt_gateway; | 102 | xdst->u.rt.rt_gateway = rt->rt_gateway; |
103 | xdst->u.rt.rt_pmtu = rt->rt_pmtu; | ||
103 | 104 | ||
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |