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

Commit 50d889b1 authored by David Ahern's avatar David Ahern Committed by Daniel Borkmann
Browse files

net/ipv4: Add helper to return path MTU based on fib result



Determine path MTU from a FIB lookup result. Logic is a distillation of
ip_dst_mtu_maybe_forward.

Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent fd0bfa8d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -449,4 +449,6 @@ static inline void fib_proc_exit(struct net *net)
}
#endif

u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr);

#endif  /* _NET_FIB_H */
+31 −0
Original line number Diff line number Diff line
@@ -1352,6 +1352,37 @@ static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr)
	return NULL;
}

/* MTU selection:
 * 1. mtu on route is locked - use it
 * 2. mtu from nexthop exception
 * 3. mtu from egress device
 */

u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr)
{
	struct fib_info *fi = res->fi;
	struct fib_nh *nh = &fi->fib_nh[res->nh_sel];
	struct net_device *dev = nh->nh_dev;
	u32 mtu = 0;

	if (dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu ||
	    fi->fib_metrics->metrics[RTAX_LOCK - 1] & (1 << RTAX_MTU))
		mtu = fi->fib_mtu;

	if (likely(!mtu)) {
		struct fib_nh_exception *fnhe;

		fnhe = find_exception(nh, daddr);
		if (fnhe && !time_after_eq(jiffies, fnhe->fnhe_expires))
			mtu = fnhe->fnhe_pmtu;
	}

	if (likely(!mtu))
		mtu = min(READ_ONCE(dev->mtu), IP_MAX_MTU);

	return mtu - lwtunnel_headroom(nh->nh_lwtstate, mtu);
}

static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
			      __be32 daddr, const bool do_cache)
{