From 7d9bdfa31b85978dc30b099229d888c5e0804202 Mon Sep 17 00:00:00 2001 From: Abdul Karim Date: Sat, 17 Feb 2024 18:48:18 +0000 Subject: [PATCH] ncm-network: nmstate - default gateway fix. nmstate requires next-hop-interface for every route to be added. Create default route entry only on the interface if default_gateway falls within subnet boundary. fixes #1655 --- ncm-network/src/main/perl/nmstate.pm | 21 ++++++++++++++----- ncm-network/src/test/perl/nmstate_advance.t | 12 +++++++++++ ncm-network/src/test/perl/nmstate_simple.t | 3 +++ .../src/test/resources/nmstate_advance.pan | 1 + 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ncm-network/src/main/perl/nmstate.pm b/ncm-network/src/main/perl/nmstate.pm index e13f3a1388..18f67052b2 100644 --- a/ncm-network/src/main/perl/nmstate.pm +++ b/ncm-network/src/main/perl/nmstate.pm @@ -320,6 +320,13 @@ sub find_vlan_id { } return $vlanid; } +# Check if given ip belongs to a network +sub ip_in_network { + my ($self, $check_ip, $ip, $netmask) = @_; + # is the given ip in his ip/netmask. + my $subnet = NetAddr::IP->new("$ip", "$netmask"); + return NetAddr::IP->new("$check_ip")->within($subnet); +} # generates the hashrefs for interface in yaml file format needed by nmstate. # bulk of the config settings needed by the nmstate yml is done here. @@ -414,12 +421,16 @@ sub generate_nmstate_config # create default route entry. my %default_rt; if ($default_gw) { - # create only default gw entry if gw entry match interface gateway defined + # create default gw entry on this interface only if it falls within the subnet boundary. # otherwise this interface is not the default gw interface. - if ((defined($iface->{gateway})) and ($iface->{gateway} eq $default_gw)) { - $default_rt{destination} = '0.0.0.0/0'; - $default_rt{'next-hop-address'} = $default_gw; - $default_rt{'next-hop-interface'} = $device; + # next-hop-interface is mandatory in nmstate therefore we need interface to create default route entry. + if ((defined($iface->{ip})) and (defined($iface->{netmask}))) { + my $is_dgw_iface = $self->ip_in_network($default_gw, $iface->{ip}, $iface->{netmask}); + if ($is_dgw_iface) { + $default_rt{destination} = '0.0.0.0/0'; + $default_rt{'next-hop-address'} = $default_gw; + $default_rt{'next-hop-interface'} = $device; + } } } # combined default route with any policy routing/rule, if any diff --git a/ncm-network/src/test/perl/nmstate_advance.t b/ncm-network/src/test/perl/nmstate_advance.t index e4dc8a6e6a..af1eddcfd2 100644 --- a/ncm-network/src/test/perl/nmstate_advance.t +++ b/ncm-network/src/test/perl/nmstate_advance.t @@ -45,6 +45,9 @@ routes: config: - next-hop-interface: eth0 state: absent + - destination: 0.0.0.0/0 + next-hop-address: 4.3.2.254 + next-hop-interface: eth0 - destination: 1.2.3.4/32 next-hop-interface: eth0 - destination: 1.2.3.5/24 @@ -82,6 +85,9 @@ routes: config: - next-hop-interface: eth0.123 state: absent + - destination: 0.0.0.0/0 + next-hop-address: 4.3.2.254 + next-hop-interface: eth0.123 - destination: 1.2.3.4/32 next-hop-interface: eth0.123 EOF @@ -107,6 +113,9 @@ routes: config: - next-hop-interface: vlan0 state: absent + - destination: 0.0.0.0/0 + next-hop-address: 4.3.2.254 + next-hop-interface: eth0.123 - destination: 1.2.3.4/32 next-hop-interface: vlan0 EOF @@ -152,6 +161,9 @@ routes: config: - next-hop-interface: bond0 state: absent + - destination: 0.0.0.0/0 + next-hop-address: 4.3.2.254 + next-hop-interface: bond0 EOF diff --git a/ncm-network/src/test/perl/nmstate_simple.t b/ncm-network/src/test/perl/nmstate_simple.t index e313938c4c..5ca004519c 100644 --- a/ncm-network/src/test/perl/nmstate_simple.t +++ b/ncm-network/src/test/perl/nmstate_simple.t @@ -61,6 +61,9 @@ routes: config: - next-hop-interface: eth0 state: absent + - destination: 0.0.0.0/0 + next-hop-address: 4.3.2.254 + next-hop-interface: eth0 EOF Readonly my $NOTTOREMOVE => <