Steps to reproduce:
- Add a vxlan interface without source-address or source-interface options set:
set interfaces vxlan vxlan999 vni 999 set interfaces vxlan vxlan999 remote 192.168.100.100 commit
- Then set source-address or source-interface:
set interfaces vxlan vxlan999 source-interface eth0 commit
Actual result:
Source address or source-interface are not set:
ip -d link show dev vxlan999 76: vxlan999: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/ether 56:08:ba:4d:4e:a8 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535 vxlan id 999 remote 192.168.100.100 srcport 0 0 dstport 8472 tos inherit ttl 16 ageing 300 udpcsum noudp6zerocsumtx noudp6zerocsumrx addr genmode none numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
Expected result:
77: vxlan999: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/ether 9e:05:d9:58:1a:af brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535 vxlan id 999 remote 192.168.100.100 dev eth0 srcport 0 0 dstport 8472 tos inherit ttl 16 ageing 300 udpcsum noudp6zerocsumtx noudp6zerocs umrx addrgenmode none numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
Analysis
- Updating certain configurations (including source-address and source-interface) for an existing vxlan interface requires rebuild of the interface. This script uses leaf_node_changed to detect if those options are changed to request a rebuild of the vxlan interface: https://github.com/vyos/vyos-1x/blob/319102b7f9ea384127b685de7cfbef2a6ade52df/src/conf_mode/interfaces-vxlan.py#L57
- By looking at the implementation of leaf_node_changed, it will return an empty list [] when adding a new a new leaf node: https://github.com/vyos/vyos-1x/blob/05df2a5f021f0c7aab7c06db645d210858b6e98d/python/vyos/configdict.py#L131
- However [] is interpreted as False in the caller script https://github.com/vyos/vyos-1x/blob/319102b7f9ea384127b685de7cfbef2a6ade52df/src/conf_mode/interfaces-vxlan.py#L57.
- Fix **
A simple fix could be updating https://github.com/vyos/vyos-1x/blob/319102b7f9ea384127b685de7cfbef2a6ade52df/src/conf_mode/interfaces-vxlan.py#L57 to explicitly check if the return value is None:
- if leaf_node_changed(conf, base + [ifname, cli_option]): + if leaf_node_changed(conf, base + [ifname, cli_option]) is not None:
Note
leaf_node_changed appears to be a function that returns a boolean but it is not. I saw leaf_node_changed is called elsewhere in vyos-1x without explicitly checking if the return value is None. This seems to be error-prone. I would like to recommend the community to review all usages of leaf_node_changed and maybe deprecate leaf_node_changed in the future to prevent this issue from happening again.