Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit defb3519 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
parent 84b3cdc3
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ struct dst_entry {

	struct  dst_ops	        *ops;

	u32			metrics[RTAX_MAX];
	u32			_metrics[RTAX_MAX];

#ifdef CONFIG_NET_CLS_ROUTE
	__u32			tclassid;
@@ -106,7 +106,27 @@ struct dst_entry {
static inline u32
dst_metric(const struct dst_entry *dst, int metric)
{
	return dst->metrics[metric-1];
	return dst->_metrics[metric-1];
}

static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
{
	dst->_metrics[metric-1] = val;
}

static inline void dst_import_metrics(struct dst_entry *dst, const u32 *src_metrics)
{
	memcpy(dst->_metrics, src_metrics, RTAX_MAX * sizeof(u32));
}

static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src)
{
	dst_import_metrics(dest, src->_metrics);
}

static inline u32 *dst_metrics_ptr(struct dst_entry *dst)
{
	return dst->_metrics;
}

static inline u32
@@ -134,7 +154,7 @@ static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metr
static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric,
				      unsigned long rtt)
{
	dst->metrics[metric-1] = jiffies_to_msecs(rtt);
	dst_metric_set(dst, metric, jiffies_to_msecs(rtt));
}

static inline u32
+1 −1
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)

#ifdef CONFIG_BRIDGE_NETFILTER
	/* remember the MTU in the rtable for PMTU */
	br->fake_rtable.dst.metrics[RTAX_MTU - 1] = new_mtu;
	dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
#endif

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
	atomic_set(&rt->dst.__refcnt, 1);
	rt->dst.dev = br->dev;
	rt->dst.path = &rt->dst;
	rt->dst.metrics[RTAX_MTU - 1] = 1500;
	dst_metric_set(&rt->dst, RTAX_MTU, 1500);
	rt->dst.flags	= DST_NOXFRM;
	rt->dst.ops = &fake_dst_ops;
}
+6 −7
Original line number Diff line number Diff line
@@ -240,13 +240,13 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)

	if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
		if (!(dst_metric_locked(dst, RTAX_MTU))) {
			dst->metrics[RTAX_MTU-1] = mtu;
			dst_metric_set(dst, RTAX_MTU, mtu);
			dst_set_expires(dst, dn_rt_mtu_expires);
		}
		if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
			u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
			if (dst_metric(dst, RTAX_ADVMSS) > mss)
				dst->metrics[RTAX_ADVMSS-1] = mss;
				dst_metric_set(dst, RTAX_ADVMSS, mss);
		}
	}
}
@@ -806,8 +806,7 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
		if (DN_FIB_RES_GW(*res) &&
		    DN_FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
			rt->rt_gateway = DN_FIB_RES_GW(*res);
		memcpy(rt->dst.metrics, fi->fib_metrics,
		       sizeof(rt->dst.metrics));
		dst_import_metrics(&rt->dst, fi->fib_metrics);
	}
	rt->rt_type = res->type;

@@ -820,11 +819,11 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)

	if (dst_metric(&rt->dst, RTAX_MTU) == 0 ||
	    dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
		rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu;
		dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu);
	mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst));
	if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0 ||
	    dst_metric(&rt->dst, RTAX_ADVMSS) > mss)
		rt->dst.metrics[RTAX_ADVMSS-1] = mss;
		dst_metric_set(&rt->dst, RTAX_ADVMSS, mss);
	return 0;
}

@@ -1502,7 +1501,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
	RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_local_src);
	if (rt->rt_daddr != rt->rt_gateway)
		RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
	if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0)
	if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
		goto rtattr_failure;
	expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
	if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires,
+1 −1
Original line number Diff line number Diff line
@@ -818,7 +818,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
			     !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
			    rt6->rt6i_dst.plen == 128) {
				rt6->rt6i_flags |= RTF_MODIFIED;
				skb_dst(skb)->metrics[RTAX_MTU-1] = mtu;
				dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
			}
		}

Loading