Page MenuHomeVyOS Platform

Cannot change MTU
Closed, ResolvedPublicBUG

Description

vyos@vyosDC1# set interfaces ethernet eth0 mtu 1350
[edit]
vyos@vyosDC1# commi
commit commit-confirm
[edit]
vyos@vyosDC1# commit
[ interfaces ethernet eth0 ]
VyOS had an issue completing a command.

We are sorry that you encountered a problem while using VyOS.
There are a few things you can do to help us (and yourself):

When reporting problems, please include as much information as possible:

  • do not obfuscate any data (feel free to contact us privately if your business policy requires it)
  • and include all the information presented below

Report Time: 2020-04-30 13:56:29
Image Version: VyOS 1.3-rolling-202004300117
Release Train: equuleus

Built by: autobuild@vyos.net
Built on: Thu 30 Apr 2020 01:17 UTC
Build UUID: 5e3d3c7c-8adf-4a56-b70b-0419e4f223d2
Build Commit ID: 31acba87d1b416

Architecture: x86_64
Boot via: installed image
System type: VMware guest

Hardware vendor: VMware, Inc.
Hardware model: VMware Virtual Platform
Hardware S/N: VMware-56 4d f9 76 53 88 13 c7-cf af 38 d0 00 e3 40 56
Hardware UUID: 564df976-5388-13c7-cfaf-38d000e34056

OSError: [Errno 34] Numerical result out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 462, in <module>
  apply(c)
File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 453, in apply
  apply_vlan_config(vlan, vif)
File "/usr/lib/python3/dist-packages/vyos/ifconfig_vlan.py", line 64, in apply_vlan_config
  vlan.set_mtu(config['mtu'])
File "/usr/lib/python3/dist-packages/vyos/ifconfig/interface.py", line 291, in set_mtu
  return self.set_interface('mtu', mtu)
File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 152, in set_interface
  return self._set_sysfs(self.config, name, value)
File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 136, in _set_sysfs
  self._sysfs_set[name]['location'].format(**config), value)
File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 105, in _write_sysfs
  f.write(str(value))

OSError: [Errno 34] Numerical result out of range

noteworthy:
cmd '/sbin/ethtool -K eth0 ufo off'
returned (out):

returned (err):
Cannot change udp-fragmentation-offload

interfaces ethernet eth0 failed
Commit failed
[edit]

Details

Version
VyOS 1.3-rolling-202004300117
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Bug (incorrect behavior)

Event Timeline

same here
root@vyos:~# ls -la /tmp/vyos.log.debug
-rw-r--r-- 1 vyos users 0 May 1 18:03 /tmp/vyos.log.debug
root@vyos:~# /sbin/ethtool -K eth0 ufo off
Cannot change udp-fragmentation-offload

root@vyos:~# show version
Version: VyOS 1.3-rolling-202004230117
Release Train: equuleus

Built by: autobuild@vyos.net
Built on: Thu 23 Apr 2020 01:17 UTC
Build UUID: 30db2c70-3eb8-4009-81f7-012337f8289d
Build Commit ID: 1f0cad00cf26b7

Architecture: x86_64
Boot via: installed image
System type: KVM guest

Hardware vendor: Red Hat
Hardware model: OpenStack Compute
Hardware S/N: 00000000-0000-0000-0000-0cc47af88ada
Hardware UUID: d9c8f859-4d07-4019-9a10-fe80d8dc0764

Copyright: VyOS maintainers and contributors
root@vyos:~#
.

vyos@vyos# set interfaces ethernet eth0 firewall in name allow-all
[edit]
vyos@vyos# commit
[ interfaces ethernet eth0 ]
Cannot change udp-fragmentation-offload

Failed to generate committed config
[edit]

Unknown Object (User) assigned this task to thomas-mangin.May 2 2020, 2:27 PM

@robertoberto issue (cannot change udp fragmentation-offload) is not the same as the original post (changing MTU out of range) so please create a separate task for it.

In T2404#62515, @jjakob wrote:

@robertoberto issue (cannot change udp fragmentation-offload) is not the same as the original post (changing MTU out of range) so please create a separate task for it.

ok created https://phabricator.vyos.net/T2419

The reason seems to be that when the kernel can not change the MTU when writing to the sysfs, it will raise a OSError with the reason why.

Sure it can (was in the initial ifconfig.py rewrite IIRC)

$ echo 1400 > /sys/class/net/eth1/mtu
$ cat /sys/class/net/eth1/mtu
1400

$ echo 1500 > /sys/class/net/eth1/mtu
$ cat /sys/class/net/eth1/mtu
1500

But you can also use sudo ip link set eth1 mtu 1500 (that's how it was done in VyOS 1.2)

Here:

root@vyos:~# cat /sys/class/net/eth0/mtu
1450
root@vyos:~# echo 1500 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1460 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1440 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1441 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1442 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1443 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1449 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1450 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1460 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1455 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1453 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1452 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1451 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~#

Here:

root@vyos:~# cat /sys/class/net/eth0/mtu
1450
root@vyos:~# echo 1500 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1460 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1440 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1441 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1442 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1443 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1449 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1450 > /sys/class/net/eth0/mtu
root@vyos:~# echo 1460 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1455 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1453 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1452 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~# echo 1451 > /sys/class/net/eth0/mtu
-bash: echo: write error: Invalid argument
root@vyos:~#

to add an interface I need to set 1450 Max
vyos@vyos# show interfaces
ethernet eth0 {

address dhcp
mtu 1450

}
loopback lo {
}
[edit]

vyos@vyos:~$ show version
Version: VyOS 1.3-rolling-202004230117
Release Train: equuleus

Built by: autobuild@vyos.net
Built on: Thu 23 Apr 2020 01:17 UTC
Build UUID: 30db2c70-3eb8-4009-81f7-012337f8289d
Build Commit ID: 1f0cad00cf26b7

Architecture: x86_64
Boot via: installed image
System type: KVM guest

Hardware vendor: Red Hat
Hardware model: OpenStack Compute
Hardware S/N: 00000000-0000-0000-0000-0cc47af88ada
Hardware UUID: d9c8f859-4d07-4019-9a10-fe80d8dc0764

Copyright: VyOS maintainers and contributors

An issue to change the MTU should not fail the whole interface change but just this one but the code does not not allow this easily. I will try to work on this.

An issue to change the MTU should not fail the whole interface change but just this one but the code does not not allow this easily. I will try to work on this.

Main issue is that without MTU set it fail:

vyos@vyos# show interfaces 
 ethernet eth0 {
     address dhcp
     mtu 1450
 }
 loopback lo {
 }
[edit]
vyos@vyos# delete interfaces ethernet eth0 mtu 1450
[edit]
vyos@vyos# commit
[ interfaces ethernet eth0 ]
VyOS had an issue completing a command.

We are sorry that you encountered a problem while using VyOS.
There are a few things you can do to help us (and yourself):
- Make sure you are running the latest version of the code available at
  https://downloads.vyos.io/rolling/current/amd64/vyos-rolling-latest.iso
- Consult the forum to see how to handle this issue
  https://forum.vyos.io
- Join our community on slack where our users exchange help and advice
  https://vyos.slack.com

When reporting problems, please include as much information as possible:
- do not obfuscate any data (feel free to contact us privately if your 
  business policy requires it)
- and include all the information presented below

Report Time:      2020-05-03 19:46:38
Image Version:    VyOS 1.3-rolling-202004230117
Release Train:    equuleus

Built by:         autobuild@vyos.net
Built on:         Thu 23 Apr 2020 01:17 UTC
Build UUID:       30db2c70-3eb8-4009-81f7-012337f8289d
Build Commit ID:  1f0cad00cf26b7

Architecture:     x86_64
Boot via:         installed image
System type:      KVM guest

Hardware vendor:  Red Hat
Hardware model:   OpenStack Compute
Hardware S/N:     00000000-0000-0000-0000-0cc47af88ada
Hardware UUID:    d9c8f859-4d07-4019-9a10-fe80d8dc0764

OSError: [Errno 22] Invalid argument

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 437, in <module>
    apply(c)
  File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 354, in apply
    e.set_mtu(eth['mtu'])
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/interface.py", line 291, in set_mtu
    return self.set_interface('mtu', mtu)
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 152, in set_interface
    return self._set_sysfs(self.config, name, value)
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 136, in _set_sysfs
    self._sysfs_set[name]['location'].format(**config), value)
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 105, in _write_sysfs
    f.write(str(value))
OSError: [Errno 22] Invalid argument


[[interfaces ethernet eth0]] failed
Commit failed
Failed to generate committed config
[edit]

This should probably be:

if eth['mtu']:
    e.set_mtu(eth['mtu'])

Then if the user doesn't set a mtu, we don't try to change it. If the config set mtu is wrong the commit should fail, but it should get verified in the verify section by a max mtu read from the interface (if that's possible), or leaving it as it is now. It shouldn't silently (or even loudly) continue as that would make the failure undetectable at boot.

That would only hide the problem. The MTU bug would still be here.

The mtu provided are reasonable and should not fail IMHO. I need to understand why Linux does not want to honour it.. hw limitation or other. If it is a limitation then we should detect it and report it to the user

I tried to google to find out how to discover max mtu an interface accept but not found.

I guess limitation is because we are using OpenStack KVM or the other guy is using VMware and they use some bytes to their SDN

I tried to google to find out how to discover max mtu an interface accept but not found.

I guess limitation is because we are using OpenStack KVM or the other guy is using VMware and they use some bytes to their SDN

Maybe leave the default OS MTU and add to docs these limitations

Other ubuntu servers inside same openstack max mtu OS leave at 1450 too

Some code should also be added to detect the parent MTU size and make sure a clan MTU is smaller than the parent

My suggestion:

  • if someone set a higher MTU than OS support, commit fail will be ok and that's OK, each vyos admin should know his OS limitations
  • If interface don't have MTU set don't try to set a default MTU
  • OR you can hardcode 1450 MTU to KVM and VMWare max MTU

I think not setting the MTU at all if the user doesn't configure it is the right way to do it. It would be nice if we could detect an interface's max MTU but I couldn't find a way to do it either (I didn't really search that hard other than looking under /sys/net/{ifname} and /proc/sys/net).
@thomas-mangin Which other dependent interfaces do you mean? All other interfaces that depend on the ethernet interface should leave the MTU untouched too, let the OS choose the defaults.

sever@vyos-roll# set interfaces ethernet eth1 description testeth
[edit]
sever@vyos-roll# commit
[edit]
sever@vyos-roll# set interfaces ethernet eth1 mtu 1200
[edit]
sever@vyos-roll# commit
[ interfaces ethernet eth1 ]

Report Time:      2020-05-04 08:29:52
Image Version:    VyOS 1.3-rolling-202005040117
Release Train:    equuleus

Built by:         autobuild@vyos.net
Built on:         Mon 04 May 2020 01:17 UTC
Build UUID:       ff77b444-8f2a-4170-9917-0874460ea6fd
Build Commit ID:  2cb6f390d7bdaa

Architecture:     x86_64
Boot via:         installed image
System type:      KVM guest

Hardware vendor:  QEMU
Hardware model:   Standard PC (i440FX + PIIX, 1996)
Hardware S/N:     
Hardware UUID:    2e8de2ab-a5a2-4e2c-8c2a-b9cb3e2166fb

Traceback (most recent call last):
  File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 333, in <module>
    apply(c)
  File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 282, in apply
    e.add_addr(addr)
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/interface.py", line 659, in add_addr
    self._cmd(f'ip addr add "{addr}" dev "{self.ifname}"')
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 48, in _cmd
    return cmd(command, self.debug)
  File "/usr/lib/python3/dist-packages/vyos/util.py", line 155, in cmd
    raise OSError(code, feedback)
FileNotFoundError: [Errno 2] failed to run command: ip addr add "fe80::/64" dev "eth1"
returned: 
exit code: 2

noteworthy:
cmd '/sbin/ethtool --show-pause eth1'
returned (out):
Pause parameters for eth1:
returned (err):
Cannot get device pause settings: Operation not supported
cmd '/sbin/ethtool -K eth1 ufo off'
returned (out):

returned (err):
Cannot change udp-fragmentation-offload
cmd 'ip addr add "fe80::/64" dev "eth1"'
returned (out):

returned (err):
RTNETLINK answers: No buffer space available

[[interfaces ethernet eth1]] failed
Commit failed
[edit]

Change mtu againe

sever@vyos-roll# set interfaces ethernet eth1 mtu 1350 
[edit]
sever@vyos-roll# commit
[ interfaces ethernet eth1 ]
VyOS had an issue completing a command.

Traceback (most recent call last):
  File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 333, in <module>
    apply(c)
  File "/usr/libexec/vyos/conf_mode/interfaces-ethernet.py", line 247, in apply
    e.add_ipv6_eui64_address(addr)
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/interface.py", line 429, in add_ipv6_eui64_address
    self.add_addr(f'{eui64}/{prefixlen}')
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/interface.py", line 659, in add_addr
    self._cmd(f'ip addr add "{addr}" dev "{self.ifname}"')
  File "/usr/lib/python3/dist-packages/vyos/ifconfig/control.py", line 48, in _cmd
    return cmd(command, self.debug)
  File "/usr/lib/python3/dist-packages/vyos/util.py", line 155, in cmd
    raise OSError(code, feedback)
FileNotFoundError: [Errno 2] failed to run command: ip addr add "fe80::5054:ff:fe47:61e6/64" dev "eth1"
returned: 
exit code: 2

noteworthy:
cmd '/sbin/ethtool --show-pause eth1'
returned (out):
Pause parameters for eth1:
returned (err):
Cannot get device pause settings: Operation not supported
cmd 'ip addr add "fe80::5054:ff:fe47:61e6/64" dev "eth1"'
returned (out):

returned (err):
RTNETLINK answers: No buffer space available

[[interfaces ethernet eth1]] failed
Commit failed
[edit]

I don't use ipv6

@Viacheslav do you have IPv6 disabled per chance? What's the output of ip addr dev eth1 after the failed commits? What's the full eth1 config?
The odd thing to me here is that it shouldn't ever be adding just fe80::/64, it should get the mac (using self.get_mac()) and create a single EUI64 address. The longer fe80:: address looks as it should be.

You can try set interfaces ethernet eth1 ipv6 address no-default-link-local, then it won't add the fe80::/64 EUI-64 address.

@jjakob I don't set any ip address on eth1

sever@vyos-roll# show interfaces ethernet eth1
 description testeth
[edit]
sever@vyos-roll# 


root@vyos-roll:/home/sever# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1200 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:47:61:e6 brd ff:ff:ff:ff:ff:ff
root@vyos-roll:/home/sever#

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=867113

So the minimum MTU for IPv6 is 1280. Setting ipv6 address no-default-link-local will probably fix this.

The reason for this is that we went from kernel-assigned default IPv6 link-locals to adding them through the interface scripts. We probably need some check if the MTU is less than 1280, don't add the default link-local and raise a ConfigError on adding IPv6 addresses.

I suggest adding a "validate" function to vyos.validate. We should determine the hypervisor used and if a setting is allowed on that hypervisor or not. Thus we can throw an appropriate erorr message by raise ConfigError() in the Python file changing the interface setting. This would be the cleanest way then the "false" setting never reaches the configuration backend at all.

We already have such checks for e.g. ethernet speed/duplex on KVM hypervisor.

@c-po is it possible to detect the exact networking setup used on the host? If not, I don't think that'll do any good, because the hypervisor is just that - a hypervisor. There can be many different types of networking. Like in this case, Openstack's SDN supports a lower MTU than a bridged or NATed connection with the same hypervisor would. The only reliable way is to detect the max MTU in some way (the kernel/device driver must know this, the question how can we read it) - the first step is to not touch the default MTU if the user doesn't set it.

In T2404#62721, @jjakob wrote:

@c-po is it possible to detect the exact networking setup used on the host? If not, I don't think that'll do any good, because the hypervisor is just that - a hypervisor. There can be many different types of networking. Like in this case, Openstack's SDN supports a lower MTU than a bridged or NATed connection with the same hypervisor would. The only reliable way is to detect the max MTU in some way (the kernel/device driver must know this, the question how can we read it) - the first step is to not touch the default MTU if the user doesn't set it.

$ sudo yum install virt-what

@Viacheslav I confirmed the bug you have with assigning 'fe80::/64' when it shouldn't. It appered after https://github.com/vyos/vyos-1x/pull/383 - I'll investigate once my other PR gets merged and open a task for it. (note that it should add the fe80::(eui-64)/64 based on mac address by default and no-default-link-local did disable it before PR#383)

Hardware vendor: Red Hat
Hardware model: OpenStack Compute
MTU should be max 1450

@thomas-mangin seems mostly fine via quick glance. Only the max_mtu is imo wrong - the device may support jumbo frames. If we limit upper MTU to 1500 we'll prevent the user from using jumbo frames if he chooses to. I can't think of a good way to solve this whole issue within the confines of the current get_config/verify/apply separation. We simply can't verify if the MTU is allowed for the hardware without trying to apply it. Some network cards don't support jumbo frames, some do, with various upper limits: baby giant, super jumbo,... (https://en.wikipedia.org/wiki/Jumbo_frame)

IMO we should make an exception for hardware (ethernet) interfaces and allow them to raise ConfigError even in apply(). Then change the ordering or commit logic so they are always applied first (in essence join the verify and apply functions) and if the apply() fails, run the script again with old values to revert the running config to the old state.
Due to this limitation, they simply can't be part of the same commit behavior as the project developer docs mandate. Commit staging isn't implemented yet anyway so all scripts still just run verify() and apply() sequentially.
The only difference is that we need to either:
a) apply MTU first in the apply() function, as it may raise a ConfigError, thus bailing out early
or
b) if the script raises ConfigError in apply(), re-run it with the "effective" config values to revert the changes it made. This would require either the config of that node to be reverted, or rewrite the interface script so we can tell it which config we want it to apply - session or effective.

for example: an error in apply() raises ApplyError. in main, we catch the ApplyError and re-run the whole get_config, verify, apply chain but with effective config instead of session config (for example by get_config_dict, then comparing the old and new config dicts, we can kill two birds with one stone: get a revert function, and have a granular apply logic that only applies changed settings - though I'm not sure that can work with the way the effective config is obtained right now, AFAIK on boot both are identical so it wouldn't work: see T2409)

After main is done reverting, it re-raises the ApplyError. The calling script catches the ApplyError and treats it the same as as a ConfigError.

I was also wondering if we should attempt an auto-detection of MTU on boot and save the result? This is why I was asking if this was the right approach.

If we want to convert the OSError to a ConfigError, I think the way forward is deal wit it in the get_interface code, as an option to convert all exception raised to anothre Error (ApplyError or ConfigError).

There was some discussion on how to make sure all the configuration is applied or none of it. I believe unknown hardware reaction/handling such as changing MTU should be part of the discussion.

How would the auto-detection work? Go through all the possible MTUs one by one? (a binary search would be way better) I'm not sure how long that would take for systems with lots of interfaces. We also need to then save this limitation somewhere permanent, and read it from the interface code, possibly a custom validator script (the shell completion can't be made dynamic). I guess this would be okay, depending on how much time it would take. The speed would depend on the interface driver. There could be drivers that are very slow, we couldn't test them and people would complain.

My suggestion: if you do a MTU suggestor/validation should be a tool optional outsite configure

Hmm, another thing - how about hot-pluggable ethernet cards? They could be USB, or in the enterprise world servers that support PCIe hot-plug could have ethernet cards swapped on-the-fly. I'm thinking the MTU detector script would need to be executed via udev rules on 'add' events.

@robertoberto why would you want it optional? It shouldn't impact functionality, if the detection is correctly written. It's not like an ethernet card's maximum supported MTU is going to change, it's fixed in the hardware/driver, or isn't it? The whole point is to get rid of the exception when committing, which isn't user-friendly, the way the scripts should behave is to catch the wrong option before trying to apply it. Unless my suggestion from above is implemented, where we would rreorganize and rewrite the scripts in such a way that we could detect the failure to apply the setting in apply() and revert all the other settings. Or (much more simply) just move applying MTU to the beginning of apply(), so no other settings are applied if it fails - but this wouldn't catch any other possible exceptions like the other method would, and isn't compliant with the structure dictated for interface scripts - separate verify() and apply() functions. The problem is we can't leave all the other settings on the interface applied when setting some of them fails, that leaves the state of the config system and the OS inconsistent and can cause all kinds of bugs.

I raised this with the team and the idea of auto-detection does not get much support, which is fine, I just wanted to make sure I was doing the right thing. So I will finish this patch which will prevent some failure case and try to make the error message friendlier. Also, can look at where in the chain of change the MTU is performed to see if it can be rolled back.

I don't see any problem on user receive message telling him MTU is not accepted by OS when his commit
On Juniper it is very common case

erkin renamed this task from change mtu to Cannot change MTU.Aug 30 2021, 6:28 AM
erkin set Issue type to Bug (incorrect behavior).
erkin removed a subscriber: Global Notifications.

Fixed

vyos@r1# set interfaces ethernet eth2 description foo
[edit]
vyos@r1# set interfaces ethernet eth2 mtu 1200
[edit]
vyos@r1# commit
[ interfaces ethernet eth2 ]
link-local IPv6 address will be configured on interface "eth2", the
required minimum MTU is 1280!

[[interfaces ethernet eth2]] failed
Commit failed
[edit]
vyos@r1# run show ver

Version:          VyOS 1.3.5
Release train:    equuleus