Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: David Ahern <dsahern@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>

authored by

David Ahern and committed by
Daniel Borkmann
50d889b1 fd0bfa8d

+33
+2
include/net/ip_fib.h
··· 449 449 } 450 450 #endif 451 451 452 + u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr); 453 + 452 454 #endif /* _NET_FIB_H */
+31
net/ipv4/route.c
··· 1352 1352 return NULL; 1353 1353 } 1354 1354 1355 + /* MTU selection: 1356 + * 1. mtu on route is locked - use it 1357 + * 2. mtu from nexthop exception 1358 + * 3. mtu from egress device 1359 + */ 1360 + 1361 + u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr) 1362 + { 1363 + struct fib_info *fi = res->fi; 1364 + struct fib_nh *nh = &fi->fib_nh[res->nh_sel]; 1365 + struct net_device *dev = nh->nh_dev; 1366 + u32 mtu = 0; 1367 + 1368 + if (dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu || 1369 + fi->fib_metrics->metrics[RTAX_LOCK - 1] & (1 << RTAX_MTU)) 1370 + mtu = fi->fib_mtu; 1371 + 1372 + if (likely(!mtu)) { 1373 + struct fib_nh_exception *fnhe; 1374 + 1375 + fnhe = find_exception(nh, daddr); 1376 + if (fnhe && !time_after_eq(jiffies, fnhe->fnhe_expires)) 1377 + mtu = fnhe->fnhe_pmtu; 1378 + } 1379 + 1380 + if (likely(!mtu)) 1381 + mtu = min(READ_ONCE(dev->mtu), IP_MAX_MTU); 1382 + 1383 + return mtu - lwtunnel_headroom(nh->nh_lwtstate, mtu); 1384 + } 1385 + 1355 1386 static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, 1356 1387 __be32 daddr, const bool do_cache) 1357 1388 {