dhcpcd-discuss

Re: dhcpcd-hooks/10-mtu modification inquiry

Roy Marples

Tue Jan 26 00:25:30 2016

Hi Chris

On Monday 25 January 2016 22:37:11 Maynard, Chris wrote:
> We have a system currently running dhcpcd 5.6.7.  While we'll look to update
> dhcpcd in the future, we are currently using this version, so this is the
> version relevant to this inquiry.
> 
> The dhcpcd-hooks/10-mtu file in question then is this version:
> http://roy.marples.name/projects/dhcpcd/artifact/b2bdd219284ceddd
> 
> I have found that when a DHCP server responds with an "Interface MTU" option
> such that the MTU specified is different than the currently configured MTU
> for the interface, the Ethernet interface appears to be reset, which causes
> dhcpcd to be notified that the carrier is lost.  Unfortunately, it has
> already updated the MTU, so after carrier is lost, it restores the original
> MTU that had been saved in $mtu_dir/$interface and then this process
> repeats indefinitely.
> 
> For example, if original MTU=1500 and new MTU=576, we end up with:
> start:
>         carrier acquired
>         MTU set to 576, save 1500 to $mtu_dir/$interface
> carrier lost
> Restore MTU to $mtu_dir/$interface
> Delete $mtu_dir/$interface
> Goto start
> 
> I am apparently not the only one to notice this reset condition when
> changing the MTU[1].  I wouldn't know all the affected controllers, but for
> the record, this one is an Intel controller (e1000e) running on Linux
> 3.10.21.

It happens for a few others controllers as well.
I have taken a new approach to MTU recently - emulate IPv6 where the MTU is 
applied to each route rather than to the interface as a whole.
The net result is identical and solves this problem very nicely.
Initial patch here: 
http://roy.marples.name/projects/dhcpcd/ci/2195587ec636ec63?sbs=0
But I doubt it applies to 5.6.7


> 
> I would like to honor the interface MTU, but also be able to restore the
> original MTU if needed, such as if the device is unplugged from the network
> where the MTU was changed into some other network where the DHCP server on
> that new network does not deliver the "Interface MTU" option.  To
> accomplish this, I have modified the 10-mtu file as follows:
> 
>       # Configure the MTU for the interface
> 
>       mtu_dir="$state_dir/mtu"
> 
>       set_mtu()
>       {
>         local mtu=$1

$1 needs quoting

> 
>         if [ -w /sys/class/net/$interface/mtu ]; then
>                 echo "$mtu" >/sys/class/net/$interface/mtu

$interface needs quoting

>         else
>                 ifconfig "$interface" mtu "$mtu"
>         fi
>       }
> 
>       if [ -n "$new_interface_mtu" ] && $if_up; then
>         # The smallest MTU dhcpcd can work with is 576
>         if [[ "$new_interface_mtu" -ge 576 && "$new_interface_mtu" -ne
> "$ifmtu" ]]; then if set_mtu "$new_interface_mtu"; then

You use should [ ] instead of [[ ]] and -a instead of &&, otherwise you rely 
on /bin/sh being bash

>                         syslog info "$interface: MTU set to
> $new_interface_mtu" # Save the original MTU so we can restore it later if [
> ! -e "$mtu_dir/$interface" ]; then
>                                 mkdir -p "$mtu_dir"
>                                 echo "$ifmtu" > "$mtu_dir/$interface"
>                         fi
>                 fi
>         fi
>       elif [ -z "$new_interface_mtu" ] && $if_up; then
>         # No MTU specified, so restore the original MTU
>         if [ -e "$mtu_dir/$interface" ]; then
>                 mtu=$(cat "$mtu_dir/$interface")
>                 if [ $mtu -ne $ifmtu ]; then

$mtu and $ifmtu need quoting

>                         set_mtu "$mtu"
>                         syslog info "$interface: MTU restored to $mtu"
>                 fi
>         fi
>       fi
> 
> Basically, I don't care about what the MTU is set to if the interface is
> down, only when it comes up.  If it's up and a new MTU is specified, set it
> if it's valid and different from the current MTU, and then store the
> original MTU if we haven't already (storing it is only ever done once).  If
> it's up but no MTU is specified, then simply restore the original MTU if it
> had been saved and if it's different from the current one.  Never delete
> $mtu_dir/$interface, as that's the original MTU!
> 
> So, with this change, what ends up happening is:
> 
> start:
>         carrier acquired
>         MTU set to 576, save 1500 to $mtu_dir/$interface
> carrier lost
> carrier acquired
> MTU already set to 576, so no need to change it.
> Happy days!
> 
> The interface is still reset once but recovers quickly.  If I were to unplug
> from this network and plug into a different network with no "Interface MTU"
> option, then this would happen:
> 
> start:
>         carrier acquired
>         Change MTU from 576 to $mtu_dir/$interface (i.e., 1500)
> carrier lost
> carrier acquired
> MTU already set to 1500, so no need to change it.
> Happy days!
> 
> My apologies for the length of this message, but I wanted to provide as much
> information as possible so it would hopefully be clear what the problem. 
> Does this approach make sense?  Is there a better way to accomplish this
> perhaps?  Maybe there's something I missed or haven't thought of?  Any
> feedback is appreciated.  Thanks for reading.

Aside from the issues I noted inline, it looks good!
We can leave this here for the archives for older users of dhcpcd in the same 
boat as yourself :)

But please, upgrade as many issues have been fixed! Hopefully no new ones 
created ;)

Roy

Follow-Ups:
RE: dhcpcd-hooks/10-mtu modification inquiryMaynard, Chris
References:
dhcpcd-hooks/10-mtu modification inquiryMaynard, Chris
Archive administrator: postmaster@marples.name