Project

General

Profile

Actions

Bug #4515

closed

Unable To Set MTU on LAGG Interface If No VLANs Assigned

Added by James S almost 10 years ago. Updated almost 9 years ago.

Status:
Resolved
Priority:
Normal
Category:
Interfaces
Target version:
-
Start date:
03/12/2015
Due date:
% Done:

0%

Estimated time:
Plus Target Version:
Release Notes:
Affected Version:
2.2
Affected Architecture:
All

Description

We've spent some time troubleshooting our inability to set an MTU value on a LAGG interface and have found what we believe to be a bug. The LAGG we're using is very basic, just a LACP bond of two NIC ports to access mode ports on a pair of switches. We tracked the problem to the /etc/inc/interfaces.inc file, the relevant sections of which I've included, with some comments below:

function interface_lagg_configure($lagg) {
...
    $lagg_mtu = interface_find_child_cfgmtu($laggif);
...
}

...

function interface_find_child_cfgmtu($realiface) {
...
    // Get the friendly name of the lagg, e.g. lagg0 becomes opt1
    $interface = convert_real_interface_to_friendly_interface_name($realiface);
    // Get VLANs attached to the adapter or empty if none
    $vlans = link_interface_to_vlans($realiface);
    // Get the Bridge config attached to the adapter or empty if none
    $bridge = link_interface_to_bridge($realiface);
...
    // Skipping GIF/GRE config for bevity
...
    $mtu = 0;
    // If one or more of the VLANs have an MTU, get the biggest one
    if (is_array($vlans)) {
        foreach ($vlans as $vlan) {
            $ifass = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
            if (empty($ifass))
                continue;
            if (!empty($config['interfaces'][$ifass]['mtu'])) {
                if (intval($config['interfaces'][$ifass]['mtu']) > $mtu)
                    $mtu = intval($config['interfaces'][$ifass]['mtu']);
            }
        }
    }
...
    // Repeat for GIF/GRE, resetting the MTU to the largest found value
...
    // Get the bridge (if there is one) and find the MTU for it, replacing the current MTU value if this one is larger
    $ifass = convert_real_interface_to_friendly_interface_name($bridge);
    if (!empty($ifass) && !empty($config['interfaces'][$ifass]['mtu'])) {
        if (intval($config['interfaces'][$ifass]['mtu']) > $mtu)
            $mtu = intval($config['interfaces'][$ifass]['mtu']);
    }
    unset($vlans, $bridge, $gifs, $gres, $ifass, $vlan);

    // Return the largest MTU value of any attached VLAN, Bridge, GIF, or GRE configs attached to this interface
    return $mtu;
}

The way we read this is that the MTU value for your LAGG interface will only be set if you have a sub-interface (VLAN, Bridge, GIF, or GRE) attached to it. In our case, we just want the MTU value we set on the interface backed by the LAGG to be used. We resolved this by modifying the 'interface_find_child_cfgmtu' method include the actual interface in the search for an MTU. A sample is below:

--- interfaces.inc.a    2015-03-11 08:07:32.061604415 -0400
+++ interfaces.inc.b    2015-03-12 06:46:05.822575326 -0400
@@ -4548,11 +4548,18 @@
             }
         }
     }
-    $ifass = convert_real_interface_to_friendly_interface_name($bridge);
-    if (!empty($ifass) && !empty($config['interfaces'][$ifass]['mtu'])) {
-        if (intval($config['interfaces'][$ifass]['mtu']) > $mtu)
-            $mtu = intval($config['interfaces'][$ifass]['mtu']);
+    if (is_empty($bridge)) {
+        $ifass = convert_real_interface_to_friendly_interface_name($bridge);
+        if (!empty($ifass) && !empty($config['interfaces'][$ifass]['mtu'])) {
+            if (intval($config['interfaces'][$ifass]['mtu']) > $mtu)
+                $mtu = intval($config['interfaces'][$ifass]['mtu']);
+        }
+    }
+    if (!empty($config['interfaces'][$interface]['mtu'])) {
+        if (intval($config['interfaces'][$interface]['mtu']) > $mtu)
+            $mtu = intval($config['interfaces'][$interface]['mtu']);
     }
+
     unset($vlans, $bridge, $gifs, $gres, $ifass, $vlan);

     return $mtu;

We're not submitting a pull request for this because we're not entirely sure if there are ramifications to making this change that are not obvious. We understand trying to find the largest MTU used by a VLAN trunked to an interface as that is likely to be the actual interface MTU, but it seems like this should only be a fall back if the interface MTU is not specified. The only other reference to this 'interface_find_child_cfgmtu' that we see in the interface code is for bridge interface setup. If it seems better to keep the MTU checking code specific to the LAGG interfaces, a modification of 'interface_lagg_configure' might be better:

--- interfaces.inc.a    2015-03-11 08:07:32.061604415 -0400
+++ interfaces.inc.c    2015-03-12 06:59:20.090545811 -0400
@@ -671,7 +671,17 @@
         $laggif = pfSense_interface_create("lagg");

     /* Check if MTU was defined for this lagg interface */
-    $lagg_mtu = interface_find_child_cfgmtu($laggif);
+    $lagg_mtu = 0;
+    $friendly_iface = convert_real_interface_to_friendly_interface_name($laggif);
+    if (!empty($friendly_iface) && !empty($config['interfaces'][$friendly_iface]['mtu'])) {
+        /* Use the actual interface MTU if we have it */
+        if (intval($config['interfaces'][$friendly_iface]['mtu']) > $lagg_mtu)
+            $lagg_mtu = intval($config['interfaces'][$friendly_iface]['mtu']);
+    }
+    if ($lagg_mtu == 0) {
+        /* If the actual interface doesn't have an MTU, check any child interfaces and find the biggest MTU */
+        $lagg_mtu = interface_find_child_cfgmtu($laggif);
+    }
     if ($lagg_mtu == 0) {
         /* Calculate smaller mtu and enforce it */
         $smallermtu = 0;

My PHP is rather rusty, so please pardon the code. I will say that we're using something like the first patch successfully now. We did not test whether MTU changes worked on a running system. The change does correctly set MTU value on both the LAGG interface and the underlying adapters when the system boots.

Actions #1

Updated by Steve Wheeler over 9 years ago

I hit this issue this morning.
There seems to be no way to set the MTU of a LAGG interface without adding a VLAN, or presumably some other type, to it.
Running 2.2.2 64bit.

Actions #2

Updated by Chris Buechler over 9 years ago

  • Assignee set to Chris Buechler
  • Affected Architecture All added
  • Affected Architecture deleted (amd64)
Actions #3

Updated by Chris Buechler almost 9 years ago

  • Status changed from New to Resolved

I believe this was fixed in a later 2.2.x version, but it definitely works in 2.3.

Actions #4

Updated by Steve Wheeler almost 9 years ago

This still seems to be present in 2.2.6. I have to set the MTU on a VLAN on the LAGG.

Actions

Also available in: Atom PDF