Page MenuHomeVyOS Platform

Modification of any interface setting sets MTU back to default when MTU has been inherited from a bond
Closed, ResolvedPublicBUG

Description

TL;DR:

If you set an MTU on bond the slave ports inherit this if you don't specify otherwise.
If you update any field of the interface of the slave port, including description, it will overwrite this inherited one with the default of 1500.

Tested on vyos-1.4-rolling-202306020317-amd64

Steps:

vyos@vyos# set interfaces bonding bond0 member interface eth1
vyos@vyos# set interfaces bonding bond0 member interface eth2
vyos@vyos# set interfaces bonding bond0 mtu 9000
vyos@vyos# commit

vyos@vyos# ip link
... 
3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast master bond0 state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:b7:af:92 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast master bond0 state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:b7:af:92 brd ff:ff:ff:ff:ff:ff permaddr 08:00:27:fb:d7:e0
5: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:b7:af:92 brd ff:ff:ff:ff:ff:ff

We can see that eth1 and eth2 have inherited the mtu from the bond

vyos@vyos# set interfaces ethernet eth2 description moo
vyos@vyos# commit
vyos@vyos# ip link
...
3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast master bond0 state UP mode DEFAULT group default qlen 1000

link/ether 08:00:27:b7:af:92 brd ff:ff:ff:ff:ff:ff

4: eth2: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP mode DEFAULT group default qlen 1000

link/ether 08:00:27:b7:af:92 brd ff:ff:ff:ff:ff:ff permaddr 08:00:27:fb:d7:e0
alias moo

5: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default qlen 1000

link/ether 08:00:27:b7:af:92 brd ff:ff:ff:ff:ff:ff

Repeating on eth1 with ifconfig debug we see:

DEBUG/IFCONFIG cmd 'ip -json -detail link list dev eth1'
DEBUG/IFCONFIG returned (out):
[{"ifindex":3,"ifname":"eth1","flags":["BROADCAST","MULTICAST","SLAVE","UP","LOWER_UP"],"mtu":9000,"qdisc":"pfifo_fast","master":"bond0","operstate":"UP","linkmode":"DEFAULT","group":"default","txqlen":1000,"link_type":"ether","address":"08:00:27:b7:af:92","broadcast":"ff:ff:ff:ff:ff:ff","promiscuity":0,"allmulti":0,"min_mtu":46,"max_mtu":16110,"linkinfo":{"info_slave_kind":"bond","info_slave_data":{"state":"ACTIVE","mii_status":"UP","link_failure_count":0,"perm_hwaddr":"08:00:27:b7:af:92","queue_id":0,"prio":0,"ad_aggregator_id":1,"ad_actor_oper_port_state":77,"ad_actor_oper_port_state_str":["active","aggregating","in_sync","defaulted"],"ad_partner_oper_port_state":1,"ad_partner_oper_port_state_str":["active"]}},"inet6_addr_gen_mode":"none","num_tx_queues":1,"num_rx_queues":1,"gso_max_size":65536,"gso_max_segs":65535,"tso_max_size":65536,"tso_max_segs":65535,"gro_max_size":65536,"parentbus":"pci","parentdev":"0000:00:08.0","ifalias":"moo"}]
DEBUG/IFCONFIG cmd 'ip link set dev eth1 mtu 1500'
DEBUG/IFCONFIG cmd 'nft -a list chain ip6 raw VYOS_TCP_MSS'
DEBUG/IFCONFIG returned (out):
table ip6 raw {
        chain VYOS_TCP_MSS { # handle 1
                type filter hook forward priority raw; policy accept;
        }
}

I believe this is done in python/vyos/ifconfig/interface.py update()

# MTU - Maximum Transfer Unit has a default value. It must ALWAYS be set
# before mangling any IPv6 option. If MTU is less then 1280 IPv6 will be
# automatically disabled by the kernel. Also MTU must be increased before
# configuring any IPv6 address on the interface.
if 'mtu' in config and dict_search('dhcp_options.mtu', config) == None:
    self.set_mtu(config.get('mtu'))

Ideally we'd need some check to see if its not the default or its that set of the bond and avoid updating the MTU in this scenario

At the time of the set the MTU from the interface configuration is a default of 1500 as there is no explicit MTU set

> /usr/lib/python3/dist-packages/vyos/ifconfig/interface.py(434)set_mtu()
-> tmp = self.get_interface('mtu')
(Pdb) bt
  /usr/libexec/vyos/conf_mode/interfaces-ethernet.py(213)<module>()
-> apply(c)
  /usr/libexec/vyos/conf_mode/interfaces-ethernet.py(202)apply()
-> e.update(ethernet)
  /usr/lib/python3/dist-packages/vyos/ifconfig/ethernet.py(363)update()
-> super().update(config)
  /usr/lib/python3/dist-packages/vyos/ifconfig/interface.py(1512)update()
-> self.set_mtu(config.get('mtu'))
> /usr/lib/python3/dist-packages/vyos/ifconfig/interface.py(434)set_mtu()
-> tmp = self.get_interface('mtu')
(Pdb) p config
*** NameError: name 'config' is not defined
(Pdb) up
> /usr/lib/python3/dist-packages/vyos/ifconfig/interface.py(1512)update()
-> self.set_mtu(config.get('mtu'))
(Pdb) p config
{'description': 'moo2', 'firewall': {'local': {'ipv6_name': 'IPV6_drop'}}, 'hw_id': '44:38:39:00:00:33', 'ring_buffer': {'rx': '4096', 'tx': '4096'}, 'ifname': 'eth3', 'ip': {'arp_cache_timeout': '30'}, 'duplex': 'auto', 'mtu': '1500', 'speed': 'auto', 'is_bond_member': {'bond0': {}}}
(Pdb)

Workaround

Set fixed MTU on slave interfaces as well as bond interfaces to avoid any discrepancy when unrelated changes are made

Details

Difficulty level
Unknown (require assessment)
Version
1.4-rolling
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Bug (incorrect behavior)

Revisions and Commits