Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152991145
D1125.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D1125.diff
View Options
Index: sbin/route/route.c
===================================================================
--- sbin/route/route.c
+++ sbin/route/route.c
@@ -1590,7 +1590,7 @@
"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE"
"\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE"
"\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3"
- "\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY";
+ "\024FIXEDMTU\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY";
static const char ifnetflags[] =
"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
"\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
Index: sys/net/if.c
===================================================================
--- sys/net/if.c
+++ sys/net/if.c
@@ -2526,6 +2526,7 @@
#ifdef INET6
nd6_setmtu(ifp);
#endif
+ rt_updatemtu(ifp);
}
break;
}
Index: sys/net/route.h
===================================================================
--- sys/net/route.h
+++ sys/net/route.h
@@ -151,7 +151,7 @@
/* 0x10000 unused, was RTF_PRCLONING */
/* 0x20000 unused, was RTF_WASCLONED */
#define RTF_PROTO3 0x40000 /* protocol specific routing flag */
-/* 0x80000 unused */
+#define RTF_FIXEDMTU 0x80000 /* MTU was explicitly specified */
#define RTF_PINNED 0x100000 /* route is immutable */
#define RTF_LOCAL 0x200000 /* route represents a local address */
#define RTF_BROADCAST 0x400000 /* route represents a bcast address */
@@ -378,6 +378,7 @@
int rt_expunge(struct radix_node_head *, struct rtentry *);
void rtfree(struct rtentry *);
int rt_check(struct rtentry **, struct rtentry **, struct sockaddr *);
+void rt_updatemtu(struct ifnet *);
/* XXX MRT COMPAT VERSIONS THAT SET UNIVERSE to 0 */
/* Thes are used by old code not yet converted to use multiple FIBS */
Index: sys/net/route.c
===================================================================
--- sys/net/route.c
+++ sys/net/route.c
@@ -141,6 +141,14 @@
struct rtentry **, u_int);
static void rt_setmetrics(const struct rt_addrinfo *, struct rtentry *);
+struct if_mtuinfo
+{
+ struct ifnet *ifp;
+ int mtu;
+};
+
+static int if_updatemtu_cb(struct radix_node *, void *);
+
/*
* handler for net.my_fibnum
*/
@@ -947,6 +955,55 @@
return (error);
}
+static int
+if_updatemtu_cb(struct radix_node *rn, void *arg)
+{
+ struct rtentry *rt;
+ struct if_mtuinfo *ifmtu;
+
+ rt = (struct rtentry *)rn;
+ ifmtu = (struct if_mtuinfo *)arg;
+
+
+ if (rt->rt_ifp != ifmtu->ifp)
+ return (0);
+
+ if (rt->rt_mtu != ifmtu->mtu && (rt->rt_flags & RTF_FIXEDMTU) == 0) {
+ /* We are safe to update route MTU */
+ rt->rt_mtu = ifmtu->mtu;
+ }
+
+ return (0);
+}
+
+void
+rt_updatemtu(struct ifnet *ifp)
+{
+ struct if_mtuinfo ifmtu;
+ struct radix_node_head *rnh;
+ int i, j;
+
+ ifmtu.ifp = ifp;
+
+ /*
+ * Try to update rt_mtu for all routes using this interface
+ * Unfortunately the only way to do this is to traverse all
+ * routing tables in all fibs/domains.
+ */
+ for (i = 1; i <= AF_MAX; i++) {
+ ifmtu.mtu = if_getmtu_family(ifp, i);
+ for (j = 0; j < rt_numfibs; j++) {
+ rnh = rt_tables_get_rnh(j, i);
+ if (rnh == NULL)
+ continue;
+ RADIX_NODE_HEAD_LOCK(rnh);
+ rnh->rnh_walktree(rnh, if_updatemtu_cb, &ifmtu);
+ RADIX_NODE_HEAD_UNLOCK(rnh);
+ }
+ }
+}
+
+
#if 0
int p_sockaddr(char *buf, int buflen, struct sockaddr *s);
int rt_print(char *buf, int buflen, struct rtentry *rt);
@@ -1482,7 +1539,7 @@
if (rt->rt_ifp != NULL) {
family = info->rti_info[RTAX_DST]->sa_family;
mtu = if_getmtu_family(rt->rt_ifp, family);
- if (rt->rt_mtu > mtu)
+ if (rt->rt_mtu == 0 || rt->rt_mtu > mtu)
rt->rt_mtu = mtu;
}
@@ -1501,8 +1558,24 @@
rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt)
{
- if (info->rti_mflags & RTV_MTU)
- rt->rt_mtu = info->rti_rmx->rmx_mtu;
+ if (info->rti_mflags & RTV_MTU) {
+ if (info->rti_rmx->rmx_mtu != 0) {
+
+ /*
+ * MTU was explicitly provided by user.
+ * Keep it.
+ */
+ rt->rt_flags |= RTF_FIXEDMTU;
+ rt->rt_mtu = info->rti_rmx->rmx_mtu;
+ } else {
+
+ /*
+ * User explicitly sets MTU to 0.
+ * Assume rollback to default.
+ */
+ rt->rt_flags &= ~RTF_FIXEDMTU;
+ }
+ }
if (info->rti_mflags & RTV_WEIGHT)
rt->rt_weight = info->rti_rmx->rmx_weight;
/* Kernel -> userland timebase conversion. */
Index: sys/netinet/ip_output.c
===================================================================
--- sys/netinet/ip_output.c
+++ sys/netinet/ip_output.c
@@ -322,20 +322,10 @@
* Calculate MTU. If we have a route that is up, use that,
* otherwise use the interface's MTU.
*/
- if (rte != NULL && (rte->rt_flags & (RTF_UP|RTF_HOST))) {
- /*
- * This case can happen if the user changed the MTU
- * of an interface after enabling IP on it. Because
- * most netifs don't keep track of routes pointing to
- * them, there is no way for one to update all its
- * routes when the MTU is changed.
- */
- if (rte->rt_mtu > ifp->if_mtu)
- rte->rt_mtu = ifp->if_mtu;
+ if (rte != NULL && (rte->rt_flags & (RTF_UP|RTF_HOST)))
mtu = rte->rt_mtu;
- } else {
+ else
mtu = ifp->if_mtu;
- }
/* Catch a possible divide by zero later. */
KASSERT(mtu > 0, ("%s: mtu %d <= 0, rte=%p (rt_flags=0x%08x) ifp=%p",
__func__, mtu, rte, (rte != NULL) ? rte->rt_flags : 0, ifp));
Index: sys/netinet6/ip6_output.c
===================================================================
--- sys/netinet6/ip6_output.c
+++ sys/netinet6/ip6_output.c
@@ -1275,17 +1275,6 @@
*/
alwaysfrag = 1;
mtu = IPV6_MMTU;
- } else if (mtu > ifmtu) {
- /*
- * The MTU on the route is larger than the MTU on
- * the interface! This shouldn't happen, unless the
- * MTU of the interface has been changed after the
- * interface was brought up. Change the MTU in the
- * route to match the interface MTU (as long as the
- * field isn't locked).
- */
- mtu = ifmtu;
- ro_pmtu->ro_rt->rt_mtu = mtu;
}
} else if (ifp) {
mtu = IN6_LINKMTU(ifp);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 19, 12:31 PM (10 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31766866
Default Alt Text
D1125.diff (5 KB)
Attached To
Mode
D1125: Do control-plane route mtu tracking instead of runtime-driven one.
Attached
Detach File
Event Timeline
Log In to Comment