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

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

net: Abstract default ADVMSS behind an accessor.



Make all RTAX_ADVMSS metric accesses go through a new helper function,
dst_metric_advmss().

Leave the actual default metric as "zero" in the real metric slot,
and compute the actual default value dynamically via a new dst_ops
AF specific callback.

For stacked IPSEC routes, we use the advmss of the path which
preserves existing behavior.

Unlike ipv4/ipv6, DecNET ties the advmss to the mtu and thus updates
advmss on pmtu updates.  This inconsistency in advmss handling
results in more raw metric accesses than I wish we ended up with.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cc6f02dd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -825,7 +825,7 @@ unsigned int cxgbi_sock_select_mss(struct cxgbi_sock *csk, unsigned int pmtu)
	unsigned int idx;
	struct dst_entry *dst = csk->dst;

	csk->advmss = dst_metric(dst, RTAX_ADVMSS);
	csk->advmss = dst_metric_advmss(dst);

	if (csk->advmss > pmtu - 40)
		csk->advmss = pmtu - 40;
+13 −1
Original line number Diff line number Diff line
@@ -112,10 +112,22 @@ dst_metric_raw(const struct dst_entry *dst, const int metric)
static inline u32
dst_metric(const struct dst_entry *dst, const int metric)
{
	WARN_ON_ONCE(metric == RTAX_HOPLIMIT);
	WARN_ON_ONCE(metric == RTAX_HOPLIMIT ||
		     metric == RTAX_ADVMSS);
	return dst_metric_raw(dst, metric);
}

static inline u32
dst_metric_advmss(const struct dst_entry *dst)
{
	u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS);

	if (!advmss)
		advmss = dst->ops->default_advmss(dst);

	return advmss;
}

static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
{
	dst->_metrics[metric-1] = val;
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ struct dst_ops {

	int			(*gc)(struct dst_ops *ops);
	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
	unsigned int		(*default_advmss)(const struct dst_entry *);
	void			(*destroy)(struct dst_entry *);
	void			(*ifdown)(struct dst_entry *,
					  struct net_device *dev, int how);
+2 −2
Original line number Diff line number Diff line
@@ -829,7 +829,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
		return -EINVAL;

	scp->state = DN_CC;
	scp->segsize_loc = dst_metric(__sk_dst_get(sk), RTAX_ADVMSS);
	scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk));
	dn_send_conn_conf(sk, allocation);

	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
@@ -958,7 +958,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen,
	sk->sk_route_caps = sk->sk_dst_cache->dev->features;
	sock->state = SS_CONNECTING;
	scp->state = DN_CI;
	scp->segsize_loc = dst_metric(sk->sk_dst_cache, RTAX_ADVMSS);
	scp->segsize_loc = dst_metric_advmss(sk->sk_dst_cache);

	dn_nsp_send_conninit(sk, NSP_CI);
	err = -EINPROGRESS;
+16 −6
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ static unsigned long dn_rt_deadline;

static int dn_dst_gc(struct dst_ops *ops);
static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
static void dn_dst_link_failure(struct sk_buff *);
static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
@@ -129,6 +130,7 @@ static struct dst_ops dn_dst_ops = {
	.gc_thresh =		128,
	.gc =			dn_dst_gc,
	.check =		dn_dst_check,
	.default_advmss =	dn_dst_default_advmss,
	.negative_advice =	dn_dst_negative_advice,
	.link_failure =		dn_dst_link_failure,
	.update_pmtu =		dn_dst_update_pmtu,
@@ -245,7 +247,8 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
		}
		if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
			u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
			if (dst_metric(dst, RTAX_ADVMSS) > mss)
			u32 existing_mss = dst_metric_raw(dst, RTAX_ADVMSS);
			if (!existing_mss || existing_mss > mss)
				dst_metric_set(dst, RTAX_ADVMSS, mss);
		}
	}
@@ -795,12 +798,17 @@ static int dn_rt_bug(struct sk_buff *skb)
	return NET_RX_DROP;
}

static unsigned int dn_dst_default_advmss(const struct dst_entry *dst)
{
	return dn_mss_from_pmtu(dst->dev, dst_mtu(dst));
}

static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
{
	struct dn_fib_info *fi = res->fi;
	struct net_device *dev = rt->dst.dev;
	struct neighbour *n;
	unsigned mss;
	unsigned int metric;

	if (fi) {
		if (DN_FIB_RES_GW(*res) &&
@@ -820,10 +828,12 @@ 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)
		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)
	metric = dst_metric_raw(&rt->dst, RTAX_ADVMSS);
	if (metric) {
		unsigned int mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst));
		if (metric > mss)
			dst_metric_set(&rt->dst, RTAX_ADVMSS, mss);
	}
	return 0;
}

Loading