resolved: be more careful with weird links with low MTUs
authorLennart Poettering <lennart@poettering.net>
Tue, 11 May 2021 20:21:52 +0000 (22:21 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 15 May 2021 18:30:52 +0000 (20:30 +0200)
Apparently CAN links will show up in rtnetlink with very low MTUs. We
shouldn't consider them relevant if no IP is spoken over them, since
these MTUs are irrelevant for us then.

Hence, let's check if there's an address assigned to the link before
considering its MTU.

As additional safety net filter out MTUs smaller than the minimum DNS
packet size, too.

Finally, in case we don't find any suitable interface MTU, let's default
to 1500 as the generic Ethernet MTU.

Fixes: #19396
(cherry picked from commit 5a0d0b8f9cdfcbb82c4a89b28f0ebce414c9ecfe)
(cherry picked from commit 3fd268d20979850a70453ed5f8891a0f03344bf2)
(cherry picked from commit ad9277d6834b5496004c98c80d5a7856afbd2861)

src/resolve/resolved-manager.c

index b7e24dc975abe0425a6623419464cb5f3cb880e4..358893274d9847b5e4578ef5f7f99a63aa2f839d 100644 (file)
@@ -1068,18 +1068,27 @@ uint32_t manager_find_mtu(Manager *m) {
         Link *l;
         Iterator i;
 
-        /* If we don't know on which link a DNS packet would be
-         * delivered, let's find the largest MTU that works on all
-         * interfaces we know of */
+        /* If we don't know on which link a DNS packet would be delivered, let's find the largest MTU that
+         * works on all interfaces we know of that have an IP address asociated */
 
         HASHMAP_FOREACH(l, m->links, i) {
-                if (l->mtu <= 0)
+                /* Let's filter out links without IP addresses (e.g. AF_CAN links and suchlike) */
+                if (!l->addresses)
+                        continue;
+
+                /* Safety check: MTU shorter than what we need for the absolutely shortest DNS request? Then
+                 * let's ignore this link. */
+                if (l->mtu < MIN(UDP4_PACKET_HEADER_SIZE + DNS_PACKET_HEADER_SIZE,
+                                 UDP6_PACKET_HEADER_SIZE + DNS_PACKET_HEADER_SIZE))
                         continue;
 
                 if (mtu <= 0 || l->mtu < mtu)
                         mtu = l->mtu;
         }
 
+        if (mtu == 0) /* found nothing? then let's assume the typical Ethernet MTU for lack of anything more precise */
+                return 1500;
+
         return mtu;
 }