diff options
author | David S. Miller <davem@davemloft.net> | 2010-12-09 00:16:57 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-09 13:46:36 -0500 |
commit | defb3519a64141608725e2dac5a5aa9a3c644bae (patch) | |
tree | 2f44985e44aef53a0d99991b9f5c2f0eb6dbf4ad /net/ipv4/route.c | |
parent | 84b3cdc38cd2882d7ac3c2ae4b6faf5c199874e3 (diff) |
net: Abstract away all dst_entry metrics accesses.
Use helper functions to hide all direct accesses, especially writes,
to dst_entry metrics values.
This will allow us to:
1) More easily change how the metrics are stored.
2) Implement COW for metrics.
In particular this will help us put metrics into the inetpeer
cache if that is what we end up doing. We can make the _metrics
member a pointer instead of an array, initially have it point
at the read-only metrics in the FIB, and then on the first set
grab an inetpeer entry and point the _metrics member there.
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3843c2dfde82..26ac396eaa5e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1686,11 +1686,14 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, | |||
1686 | if (mtu < dst_mtu(&rth->dst)) { | 1686 | if (mtu < dst_mtu(&rth->dst)) { |
1687 | dst_confirm(&rth->dst); | 1687 | dst_confirm(&rth->dst); |
1688 | if (mtu < ip_rt_min_pmtu) { | 1688 | if (mtu < ip_rt_min_pmtu) { |
1689 | u32 lock = dst_metric(&rth->dst, | ||
1690 | RTAX_LOCK); | ||
1689 | mtu = ip_rt_min_pmtu; | 1691 | mtu = ip_rt_min_pmtu; |
1690 | rth->dst.metrics[RTAX_LOCK-1] |= | 1692 | lock |= (1 << RTAX_MTU); |
1691 | (1 << RTAX_MTU); | 1693 | dst_metric_set(&rth->dst, RTAX_LOCK, |
1694 | lock); | ||
1692 | } | 1695 | } |
1693 | rth->dst.metrics[RTAX_MTU-1] = mtu; | 1696 | dst_metric_set(&rth->dst, RTAX_MTU, mtu); |
1694 | dst_set_expires(&rth->dst, | 1697 | dst_set_expires(&rth->dst, |
1695 | ip_rt_mtu_expires); | 1698 | ip_rt_mtu_expires); |
1696 | } | 1699 | } |
@@ -1708,10 +1711,11 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
1708 | if (dst_mtu(dst) > mtu && mtu >= 68 && | 1711 | if (dst_mtu(dst) > mtu && mtu >= 68 && |
1709 | !(dst_metric_locked(dst, RTAX_MTU))) { | 1712 | !(dst_metric_locked(dst, RTAX_MTU))) { |
1710 | if (mtu < ip_rt_min_pmtu) { | 1713 | if (mtu < ip_rt_min_pmtu) { |
1714 | u32 lock = dst_metric(dst, RTAX_LOCK); | ||
1711 | mtu = ip_rt_min_pmtu; | 1715 | mtu = ip_rt_min_pmtu; |
1712 | dst->metrics[RTAX_LOCK-1] |= (1 << RTAX_MTU); | 1716 | dst_metric_set(dst, RTAX_LOCK, lock | (1 << RTAX_MTU)); |
1713 | } | 1717 | } |
1714 | dst->metrics[RTAX_MTU-1] = mtu; | 1718 | dst_metric_set(dst, RTAX_MTU, mtu); |
1715 | dst_set_expires(dst, ip_rt_mtu_expires); | 1719 | dst_set_expires(dst, ip_rt_mtu_expires); |
1716 | call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); | 1720 | call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); |
1717 | } | 1721 | } |
@@ -1796,36 +1800,37 @@ static void set_class_tag(struct rtable *rt, u32 tag) | |||
1796 | 1800 | ||
1797 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | 1801 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) |
1798 | { | 1802 | { |
1803 | struct dst_entry *dst = &rt->dst; | ||
1799 | struct fib_info *fi = res->fi; | 1804 | struct fib_info *fi = res->fi; |
1800 | 1805 | ||
1801 | if (fi) { | 1806 | if (fi) { |
1802 | if (FIB_RES_GW(*res) && | 1807 | if (FIB_RES_GW(*res) && |
1803 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) | 1808 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) |
1804 | rt->rt_gateway = FIB_RES_GW(*res); | 1809 | rt->rt_gateway = FIB_RES_GW(*res); |
1805 | memcpy(rt->dst.metrics, fi->fib_metrics, | 1810 | dst_import_metrics(dst, fi->fib_metrics); |
1806 | sizeof(rt->dst.metrics)); | ||
1807 | if (fi->fib_mtu == 0) { | 1811 | if (fi->fib_mtu == 0) { |
1808 | rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu; | 1812 | dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); |
1809 | if (dst_metric_locked(&rt->dst, RTAX_MTU) && | 1813 | if (dst_metric_locked(dst, RTAX_MTU) && |
1810 | rt->rt_gateway != rt->rt_dst && | 1814 | rt->rt_gateway != rt->rt_dst && |
1811 | rt->dst.dev->mtu > 576) | 1815 | dst->dev->mtu > 576) |
1812 | rt->dst.metrics[RTAX_MTU-1] = 576; | 1816 | dst_metric_set(dst, RTAX_MTU, 576); |
1813 | } | 1817 | } |
1814 | #ifdef CONFIG_NET_CLS_ROUTE | 1818 | #ifdef CONFIG_NET_CLS_ROUTE |
1815 | rt->dst.tclassid = FIB_RES_NH(*res).nh_tclassid; | 1819 | dst->tclassid = FIB_RES_NH(*res).nh_tclassid; |
1816 | #endif | 1820 | #endif |
1817 | } else | 1821 | } else |
1818 | rt->dst.metrics[RTAX_MTU-1]= rt->dst.dev->mtu; | 1822 | dst_metric_set(dst, RTAX_MTU, dst->dev->mtu); |
1819 | 1823 | ||
1820 | if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0) | 1824 | if (dst_metric(dst, RTAX_HOPLIMIT) == 0) |
1821 | rt->dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl; | 1825 | dst_metric_set(dst, RTAX_HOPLIMIT, sysctl_ip_default_ttl); |
1822 | if (dst_mtu(&rt->dst) > IP_MAX_MTU) | 1826 | if (dst_mtu(dst) > IP_MAX_MTU) |
1823 | rt->dst.metrics[RTAX_MTU-1] = IP_MAX_MTU; | 1827 | dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); |
1824 | if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0) | 1828 | if (dst_metric(dst, RTAX_ADVMSS) == 0) |
1825 | rt->dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->dst.dev->mtu - 40, | 1829 | dst_metric_set(dst, RTAX_ADVMSS, |
1826 | ip_rt_min_advmss); | 1830 | max_t(unsigned int, dst->dev->mtu - 40, |
1827 | if (dst_metric(&rt->dst, RTAX_ADVMSS) > 65535 - 40) | 1831 | ip_rt_min_advmss)); |
1828 | rt->dst.metrics[RTAX_ADVMSS-1] = 65535 - 40; | 1832 | if (dst_metric(dst, RTAX_ADVMSS) > 65535 - 40) |
1833 | dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); | ||
1829 | 1834 | ||
1830 | #ifdef CONFIG_NET_CLS_ROUTE | 1835 | #ifdef CONFIG_NET_CLS_ROUTE |
1831 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1836 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
@@ -2720,7 +2725,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi | |||
2720 | new->__use = 1; | 2725 | new->__use = 1; |
2721 | new->input = dst_discard; | 2726 | new->input = dst_discard; |
2722 | new->output = dst_discard; | 2727 | new->output = dst_discard; |
2723 | memcpy(new->metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32)); | 2728 | dst_copy_metrics(new, &ort->dst); |
2724 | 2729 | ||
2725 | new->dev = ort->dst.dev; | 2730 | new->dev = ort->dst.dev; |
2726 | if (new->dev) | 2731 | if (new->dev) |
@@ -2827,7 +2832,7 @@ static int rt_fill_info(struct net *net, | |||
2827 | if (rt->rt_dst != rt->rt_gateway) | 2832 | if (rt->rt_dst != rt->rt_gateway) |
2828 | NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway); | 2833 | NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway); |
2829 | 2834 | ||
2830 | if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0) | 2835 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) |
2831 | goto nla_put_failure; | 2836 | goto nla_put_failure; |
2832 | 2837 | ||
2833 | if (rt->fl.mark) | 2838 | if (rt->fl.mark) |