Page MenuHomeVyOS Platform

[1.3->1.4 Migration] An empty interface configuration drops all interfaces configuration
Closed, ResolvedPublicBUG

Description

1. Migration from 1.3.5 to 1.4.0-epa2
An empty vif interface drops all vif's configuration during migration from 1.3.5 to 1.4.0-epa2
Configuration 1.3.5

interfaces {
    ethernet eth0 {
        address 192.168.0.1/24
        vif 2
        vif 800 {
            address 192.168.1.1/24
        }
        vif 801 {
            address 192.168.2.1/24
        }
    }
    loopback lo
}

After migration all vifs configs under this interface are empty.
If we change from vif 2 to vif 2 {} in the configuration manually then migration passes.

2. Migration from 1.3.5 to 1.5 (1.5-rolling-202405010020)

The same config from 1.3.5
After migration, there is only a loopback interface in the configuration. Interface eth0 is absent.
If we change from loopback lo to loopback lo {} in the configuration manually then interfaces appear but vifs not.
After
If we change from vif 2 to vif 2 {} in the configuration manually then migration passes.

Details

Version
VyOS 1.5-rolling-202405010020, VyOS 1.4.0-epa2
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Bug (incorrect behavior)

Event Timeline

a.apostoliuk triaged this task as High priority.
c-po changed the task status from Open to In progress.May 3 2024, 4:07 PM
c-po claimed this task.

How was this configuration achieved? Or is it manually crafted?

c-po changed the task status from In progress to Needs reporter action.May 8 2024, 4:05 PM

Migration requires the config file to be in the standard syntax, such as produced by the system itself (set/del; commit; save) --- in this case, a configuration that can be loaded and saved on VyOS 1.3.5 would not be missing braces as above. If one needs to hand edit a config file, at the very least one needs to load/save on the source system before migration. The only weird corner case, linked above, is when a change of mac address triggers a rewrite by the ealry-legacy parser (only used in <= 1.3.x, and only in one remaining place in 1.3.x: vyatta_interface_rescan) --- that does produce incorrect syntax and is a known problem as described in the comment in T5611; that case is also restored by saving the config on the source image before system update and the resulting migration on reboot.

Checking a recent 1.5 build (1.5-rolling-202405090225), I do not see the discrepancy mentioned in the description: the result for 1.5 is also (just) missing vif entries, and one can observe that the syntax error in vif 2 causes cascading syntax errors in the other vif sections.
The following script recreates the effect of the XorpConfigParser:

#! /usr/bin/perl

use strict;
use lib "/opt/vyatta/share/perl5/";
use Sys::Syslog qw(:standard :macros);
use XorpConfigParser;

sub xorp_write {
    my ($INFILE, $OUTFILE) = @_;

    # parse config input file
    my $xcp = new XorpConfigParser();
    $xcp->parse($INFILE);

    # write config output file
    open (my $out, '>', $OUTFILE)
    or die "Can't open $OUTFILE : $!";

    select $out;
    $xcp->output(0);
    select STDOUT;
    close $out;
}

die "xorp-write needs two args: input_file output_file"
    unless ($#ARGV == 1);

xorp_write(@ARGV);
exit 0;

The result on the lines in question (example.config is syntactically sound; xorped.config is not):

└──> diff -C 2 example.config xorped.config
*** example.config      2024-05-12 19:26:59.377107781 -0500
--- xorped.config       2024-05-12 19:36:30.562143990 -0500
***************
*** 7,12 ****
          address 192.168.0.1/24
          hw-id 52:54:00:c1:df:f9
!         vif 2 {
!         }
          vif 800 {
              address 192.168.1.1/24
--- 7,11 ----
          address 192.168.0.1/24
          hw-id 52:54:00:c1:df:f9
!         vif 2
          vif 800 {
              address 192.168.1.1/24
***************
*** 16,21 ****
          }
      }
!     loopback lo {
!     }
  }
  service {
--- 15,19 ----
          }
      }
!     loopback lo
  }
  service {
***************

This leads to failed parsing for the whole vif subsection:

In [1]: from vyos.configtree import ConfigTree

In [2]: with open('./example.config') as f:
   ...:     example_config_str = f.read()
   ...: 

In [3]: example_ct = ConfigTree(example_config_str)

In [4]: example_vif = example_ct.get_subtree(['interfaces', 'ethernet', 'eth1', 'vif'], with_node=True)

In [5]: print(example_vif.to_string())
vif 2 {
}
vif 800 {
    address "192.168.1.1/24"
}
vif 801 {
    address "192.168.2.1/24"
}

In [6]: with open('./xorped.config') as f:
   ...:     xorped_config_str = f.read()
   ...: 

In [7]: xorped_ct = ConfigTree(xorped_config_str)

In [8]: xorped_vif = xorped_ct.get_subtree(['interfaces', 'ethernet', 'eth1', 'vif'], with_node=True)

In [9]: print(xorped_vif.to_string())
vif {
    800 {
        address "192.168.1.1/24"
    }
    801 {
        address "192.168.2.1/24"
    }
}

The second format is incorrect for tag nodes.

Added parent task T5611; the issue is explained in the above comment and in that task. As has been discussed, the easiest workaround is to save the config on the source image before migrating --- backporting the rewrite of vyatta_net_name/vyatta_interface_rescan to 1.3.x, as mentioned in T5611, will not resolve the issue for earlier images, so a workaround is needed in those cases.

@a.apostoliuk if you accept the explanation above and the workaround suffices (as recently discussed), we will close this task.

jestabro moved this task from Backlog to Finished on the VyOS 1.4 Sagitta (1.4.1) board.

As discussed a workaround is available, and preferable to the danger over usefulness of backporting to 1.3.x.