aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-09 00:16:57 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-09 13:46:36 -0500
commitdefb3519a64141608725e2dac5a5aa9a3c644bae (patch)
tree2f44985e44aef53a0d99991b9f5c2f0eb6dbf4ad /net/ipv4/route.c
parent84b3cdc38cd2882d7ac3c2ae4b6faf5c199874e3 (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.c55
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
1797static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) 1801static 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)