Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cloud-netconfig for openSUSE:Factory checked in at 2023-01-09 17:24:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cloud-netconfig (Old) and /work/SRC/openSUSE:Factory/.cloud-netconfig.new.32243 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cloud-netconfig" Mon Jan 9 17:24:14 2023 rev:14 rq:1057067 version:1.7 Changes: -------- --- /work/SRC/openSUSE:Factory/cloud-netconfig/cloud-netconfig.changes 2022-10-06 07:42:38.276745257 +0200 +++ /work/SRC/openSUSE:Factory/.cloud-netconfig.new.32243/cloud-netconfig.changes 2023-01-09 17:24:17.951327063 +0100 @@ -1,0 +2,13 @@ +Fri Dec 16 14:32:31 UTC 2022 - Joachim Gleissner <jgleiss...@suse.com> + +- Update to version 1.7: + + Overhaul policy routing setup (issue #19) + + Support alias IPv4 ranges (issue #14) + + Add support for NetworkManager (bsc#1204549) + + Remove dependency on netconfig + + Install into libexec directory + + Clear stale ifcfg files for accelerated NICs (bsc#1199853) + + More debug messages + + Documentation update + +------------------------------------------------------------------- Old: ---- cloud-netconfig-1.6.tar.bz2 New: ---- cloud-netconfig-1.7.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cloud-netconfig.spec ++++++ --- /var/tmp/diff_new_pack.W2Kt76/_old 2023-01-09 17:24:18.623330866 +0100 +++ /var/tmp/diff_new_pack.W2Kt76/_new 2023-01-09 17:24:18.627330889 +0100 @@ -1,7 +1,7 @@ # # spec file # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -36,13 +36,18 @@ %define csp_string Google Compute Engine %endif +%if ! %{defined _distconfdir} +%define _distconfdir %{_sysconfdir} +%define no_dist_conf 1 +%endif + Name: %{base_name}%{flavor_suffix} -Version: 1.6 +Version: 1.7 Release: 0 -Summary: Network configuration scripts for %{csp_string} License: GPL-3.0-or-later -Group: System/Management +Summary: Network configuration scripts for %{csp_string} URL: https://github.com/SUSE-Enceladus/cloud-netconfig +Group: System/Management Source0: %{base_name}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch @@ -55,6 +60,9 @@ Requires: sysconfig-netconfig %endif BuildRequires: pkgconfig(udev) +%if 0%{?sle_version} > 150100 +BuildRequires: NetworkManager +%endif Requires: curl Requires: udev %if 0%{?sles_version} == 11 @@ -67,11 +75,28 @@ Conflicts: cloud-netconfig %endif %{?systemd_requires} +%define _scriptdir %{_libexecdir}/cloud-netconfig +%if 0%{?suse_version} > 1550 +%define _netconfigdir %{_libexecdir}/netconfig.d +%else +%define _netconfigdir %{_sysconfdir}/netconfig.d +%endif %description -n %{base_name}%{flavor_suffix} This package contains scripts for automatically configuring network interfaces in %{csp_string} with full support for hotplug. +%if 0%{?sle_version} > 150100 +%package -n %{base_name}-nm +Summary: Network configuration scripts for %{csp_string} +Group: System/Management +Requires: NetworkManager +Requires: cloud-netconfig + +%description -n %{base_name}-nm +Dispatch script for NetworkManager that automatically runs cloud-netconfig. +%endif + %prep %setup -q -n %{base_name}-%{version} @@ -82,11 +107,11 @@ DESTDIR=%{buildroot} \ PREFIX=%{_usr} \ SYSCONFDIR=%{_sysconfdir} \ + DISTCONFDIR=%{_distconfdir} \ + SCRIPTDIR=%{_scriptdir} \ UDEVRULESDIR=%{_udevrulesdir} \ - %if 0%{?suse_version} > 1550 - NETCONFDIR=%{_libexecdir}/netconfig/netconfig.d \ - %endif - UNITDIR=%{_unitdir} + UNITDIR=%{_unitdir} \ + NETCONFIGDIR=%{_netconfigdir} # Disable persistent net generator from udev-persistent-ifnames as # it does not work for xen interfaces. This will likely produce a warning. @@ -95,15 +120,19 @@ ln -s /dev/null %{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules %endif +%if 0%{?sle_version} <= 150100 +rm -r %{buildroot}/usr/lib/NetworkManager +%endif + %files -n %{base_name}%{flavor_suffix} %defattr(-,root,root) -%config(noreplace) %{_sysconfdir}/default/cloud-netconfig -%if 0%{?suse_version} > 1550 -%{_libexecdir}/netconfig/netconfig.d/cloud-netconfig +%{_scriptdir} +%if %{defined no_config} +%config(noreplace) %{_distconfdir}/default/cloud-netconfig %else -%{_sysconfdir}/netconfig.d/cloud-netconfig +%{_distconfdir}/default/cloud-netconfig %endif -%{_sysconfdir}/sysconfig/network/scripts/* +%{_netconfigdir} %if 0%{?suse_version} >= 1315 %{_sysconfdir}/udev/rules.d %endif @@ -112,6 +141,11 @@ %doc README.md %license LICENSE +%if 0%{?sle_version} > 150100 +%files -n %{base_name}-nm +/usr/lib/NetworkManager/dispatcher.d +%endif + %pre %service_add_pre %{base_name}.service %{base_name}.timer ++++++ cloud-netconfig-1.6.tar.bz2 -> cloud-netconfig-1.7.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/Makefile new/cloud-netconfig-1.7/Makefile --- old/cloud-netconfig-1.6/Makefile 2020-11-04 17:34:18.857419551 +0100 +++ new/cloud-netconfig-1.7/Makefile 2022-12-16 15:29:58.365590361 +0100 @@ -1,21 +1,26 @@ .PHONY: common help install-azure install-ec2 PREFIX?=/usr SYSCONFDIR?=/etc +DISTCONFDIR?=/usr/etc +LIBEXECDIR?=/usr/libexec UDEVRULESDIR?=$(PREFIX)/lib/udev/rules.d -NETCONFDIR?=$(SYSCONFDIR)/netconfig.d -SCRIPTDIR?=$(SYSCONFDIR)/sysconfig/network/scripts +SCRIPTDIR?=$(LIBEXECDIR)/cloud-netconfig UNITDIR?=$(PREFIX)/lib/systemd/system -DEFAULTDIR?=$(SYSCONFDIR)/default +DEFAULTDIR?=$(DISTCONFDIR)/default +NETCONFIGDIR?=$(SYSCONFDIR)/netconfig.d +NMDISPATCHDIR?=/usr/lib/NetworkManager/dispatcher.d DESTDIR?= -DEST_NETCONFDIR=$(DESTDIR)$(NETCONFDIR) DEST_UDEVRULESDIR=$(DESTDIR)$(UDEVRULESDIR) DEST_SCRIPTDIR=$(DESTDIR)$(SCRIPTDIR) DEST_UNITDIR=$(DESTDIR)$(UNITDIR) DEST_DEFAULTDIR=$(DESTDIR)$(DEFAULTDIR) +DEST_NETCONFIGDIR=$(DESTDIR)$(NETCONFIGDIR) +DEST_NMDISPATCHDIR=$(DESTDIR)$(NMDISPATCHDIR) +NM_DISPATCH_SCRIPT=90-cloud-netconfig verSrc = $(shell cat VERSION) -verSpec = $(shell rpm -q --specfile --qf '%{VERSION}' cloud-netconfig.spec 2>/dev/null) +verSpec = $(shell sed -n -r -e '/^Version:/ s/(Version: *)([^ ]+)/\2/p' cloud-netconfig.spec) ifneq "$(verSrc)" "$(verSpec)" $(error "Version mismatch source and spec, aborting") @@ -24,34 +29,48 @@ help: @echo "Type 'make install-ec2' for installation on EC2" @echo "Type 'make install-azure' for installation on Azure" + @echo "Type 'make install-gce' for installation on GCE" @echo "Use var DESTDIR for installing into a different root." common: - mkdir -p $(DEST_NETCONFDIR) - mkdir -p $(DEST_UDEVRULESDIR) - mkdir -p $(DEST_SCRIPTDIR) - mkdir -p $(DEST_UNITDIR) - mkdir -p $(DEST_DEFAULTDIR) - install -m 755 common/cloud-netconfig $(DEST_NETCONFDIR) - install -m 755 common/cloud-netconfig-cleanup $(DEST_SCRIPTDIR) - install -m 644 common/cloud-netconfig-default $(DEST_DEFAULTDIR)/cloud-netconfig - install -m 755 common/cloud-netconfig-hotplug $(DEST_SCRIPTDIR) - install -m 644 systemd/cloud-netconfig.service $(DEST_UNITDIR) - install -m 644 systemd/cloud-netconfig.timer $(DEST_UNITDIR) + mkdir -p $(DESTDIR)$(UDEVRULESDIR) + mkdir -p $(DESTDIR)$(SCRIPTDIR) + mkdir -p $(DESTDIR)$(UNITDIR) + mkdir -p $(DESTDIR)$(DEFAULTDIR) + mkdir -p $(DESTDIR)$(NETCONFIGDIR) + mkdir -p $(DESTDIR)$(NMDISPATCHDIR) + install -m 755 common/cloud-netconfig $(DESTDIR)$(SCRIPTDIR) + install -m 755 common/cloud-netconfig-cleanup $(DESTDIR)$(SCRIPTDIR) + install -m 644 common/cloud-netconfig-default $(DESTDIR)$(DEFAULTDIR)/cloud-netconfig + install -m 755 common/cloud-netconfig-hotplug $(DESTDIR)$(SCRIPTDIR) + install -m 755 common/cloud-netconfig-wrapper $(DESTDIR)$(NETCONFIGDIR)/cloud-netconfig + install -m 755 common/cloud-netconfig-nm $(DESTDIR)$(NMDISPATCHDIR)/$(NM_DISPATCH_SCRIPT) + install -m 644 systemd/cloud-netconfig.service $(DESTDIR)$(UNITDIR) + install -m 644 systemd/cloud-netconfig.timer $(DESTDIR)$(UNITDIR) + sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g" $(DESTDIR)$(SCRIPTDIR)/cloud-netconfig + sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g" $(DESTDIR)$(SCRIPTDIR)/cloud-netconfig-hotplug + sed -i -r -e "s;DISTCONFDIR=.*;DISTCONFDIR=${DISTCONFDIR};g" $(DESTDIR)$(SCRIPTDIR)/cloud-netconfig-hotplug + sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g" $(DESTDIR)$(NETCONFIGDIR)/cloud-netconfig + sed -i -r -e "s;SCRIPTDIR=.*;SCRIPTDIR=${SCRIPTDIR};g" $(DESTDIR)$(NMDISPATCHDIR)/$(NM_DISPATCH_SCRIPT) + sed -i -r -e "s;%SCRIPTDIR%;${SCRIPTDIR};g" $(DESTDIR)$(UNITDIR)/cloud-netconfig.service install-azure: common - install -m 644 azure/61-cloud-netconfig-hotplug.rules $(DEST_UDEVRULESDIR) - install -m 755 azure/functions.cloud-netconfig $(DEST_SCRIPTDIR) + install -m 644 azure/61-cloud-netconfig-hotplug.rules $(DESTDIR)$(UDEVRULESDIR) + install -m 755 azure/functions.cloud-netconfig $(DESTDIR)$(SCRIPTDIR) + install -m 755 azure/cleanup-stale-ifcfg $(DESTDIR)$(SCRIPTDIR) + sed -i -e "s;%SCRIPTDIR%;${SCRIPTDIR};g" $(DESTDIR)$(UDEVRULESDIR)/*hotplug.rules install-ec2: common - install -m 644 common/75-cloud-persistent-net-generator.rules $(DEST_UDEVRULESDIR) - install -m 644 ec2/51-cloud-netconfig-hotplug.rules $(DEST_UDEVRULESDIR) - install -m 755 ec2/functions.cloud-netconfig $(DEST_SCRIPTDIR) + install -m 644 common/75-cloud-persistent-net-generator.rules $(DESTDIR)$(UDEVRULESDIR) + install -m 644 ec2/51-cloud-netconfig-hotplug.rules $(DESTDIR)$(UDEVRULESDIR) + install -m 755 ec2/functions.cloud-netconfig $(DESTDIR)$(SCRIPTDIR) + sed -i -e "s;%SCRIPTDIR%;${SCRIPTDIR};g" $(DESTDIR)$(UDEVRULESDIR)/*hotplug.rules install-gce: common - install -m 644 common/75-cloud-persistent-net-generator.rules $(DEST_UDEVRULESDIR) - install -m 644 gce/51-cloud-netconfig-hotplug.rules $(DEST_UDEVRULESDIR) - install -m 755 gce/functions.cloud-netconfig $(DEST_SCRIPTDIR) + install -m 644 common/75-cloud-persistent-net-generator.rules $(DESTDIR)$(UDEVRULESDIR) + install -m 644 gce/51-cloud-netconfig-hotplug.rules $(DESTDIR)$(UDEVRULESDIR) + install -m 755 gce/functions.cloud-netconfig $(DESTDIR)$(SCRIPTDIR) + sed -i -e "s;%SCRIPTDIR%;${SCRIPTDIR};g" $(DESTDIR)$(UDEVRULESDIR)/*hotplug.rules tarball: @test -n "$(verSrc)" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/README.html new/cloud-netconfig-1.7/README.html --- old/cloud-netconfig-1.6/README.html 2021-04-20 15:03:26.582059289 +0200 +++ new/cloud-netconfig-1.7/README.html 1970-01-01 01:00:00.000000000 +0100 @@ -1,65 +0,0 @@ -<h1>cloud-netconfig</h1> -<p><strong>cloud-netconfig</strong> is a collection of scripts for automatically configuring -network interfaces in cloud frameworks. Currently supported are Amazon EC2, -Microsoft Azure, and Google Compute Engine. It requires netconfig (package -<strong>sysconfig-netconfig</strong> on openSUSE and SUSE Linux Enterprise distributions).</p> -<h3>Installation</h3> -<p>If you are installing from source, run as root <code>make install-ec2</code>, <code>make -install-azure</code>, or <code>make install-gce</code> depending on your platform. Then reload -the udev rules by running <code>udevadm control -R</code>. Afterwards add -<strong>cloud-netconfig</strong> to the variable <strong>NETCONFIG__MODULES__ORDER</strong> in -<code>/etc/sysconfig/network/config</code> and restart networking (<code>systemctl restart -wicked.serice</code> on SUSE Linux Enterprise Server or openSUSE distributions). On -EC2 and Azure you may want to enable the systemd timer too (see below for -details on its purpose). To do that, run <code>systemctl enable --now -cloud-netconfig.timer</code>.</p> -<h3>Mode of Operation</h3> -<p><strong>cloud-netconfig</strong> handles three different tasks:</p> -<ul> -<li>Set up unconfigured interfaces</li> -</ul> -<p>For any network interface that does not have an associated configuration file -in <code>/etc/sysconfig/network</code>, a DHCP based configuration will be generated and -<code>ifup</code> will be called, which triggers interface configuration through <code>wicked</code>.</p> -<ul> -<li>Apply secondary IPv4 addresses</li> -</ul> -<p>For all interfaces managed by <strong>cloud-netconfig</strong>, it will look up secondary -IPv4 addresses from the framework's metadta server and configure them on the -interface. This does not apply to Google Compute Engine, as secondary IPv4 -addresses are not assigned directly through the framework.</p> -<ul> -<li>Create routing policies</li> -</ul> -<p>In case the system has more than one network interface, <strong>cloud-netconfig</strong> -sets up routing in a way that packets are routed through the interface -associated with the source address of the packet. To do that, it creates a -separate routing table for each interface with a default route according to the -interface configration. It also creates a routing policy to use that table for -packets using any of the interface's source addresses. This ensures that -packets are routed via the correct interface.</p> -<p>Note: DHCP servers of cloud frameworks (this applies to Microsoft Azure at the -time of writing) may not include a gateway address in DHCP leases for secondary -IPv4 addresses. This is presumably to avoid default routes to clash. To enable -full connectivity in this case, <strong>cloud-netconfig</strong> assumes the gateway host to -be the first host of the sub-network assigned to the interface.</p> -<p>Interface configurations will be checked periodically on each DHCP lease -renewal and additionally, if the systemd timer is enabled (default on Amazon -EC2 and Microsoft Azure SUSE Linux Enterprise Server images), every 60 seconds. -<strong>cloud-netconfig</strong> detects changes in the metadata configuration and updates -interface configuration and routing policies accordingly. This means that IP -addresses that were removed from the virtual interface configuration will be -removed from the interface, but only addresses that were automatically added by -<strong>cloud-netconfig</strong> will be removed. Addresses added manually by the -administrator or by another tool (e.g. high-availability software) will not be -touched.</p> -<h3>Configuration</h3> -<p><strong>cloud-netconfig</strong> does not require any configuration, but it should be noted -that it will not overwrite existing interface configurations. This allows to -use specific interface configurations. <strong>cloud-netconfig</strong> will still set up -secondary IP addresses and routing policies. If you do not want that, set the -variable <strong>CLOUD__NETCONFIG__MANAGE</strong> to <strong>no</strong> in the <code>ifcfg</code> file in -<code>/etc/sysconfig/network</code> to disable it for the associated interface. You can -also change the default value of <strong>CLOUD__NETCONFIG__MANAGE</strong> for in -<code>/etc/default/cloud-netconfig</code>. The default applies to newly created <code>ifcfg</code> -files, not for existing ones.</p> \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/README.md new/cloud-netconfig-1.7/README.md --- old/cloud-netconfig-1.6/README.md 2021-08-11 14:01:06.647719396 +0200 +++ new/cloud-netconfig-1.7/README.md 2022-12-16 15:29:58.369590436 +0100 @@ -20,7 +20,7 @@ ### Mode of Operation -**cloud-netconfig** handles three different tasks: +**cloud-netconfig** handles the following tasks: - Set up unconfigured interfaces @@ -35,32 +35,46 @@ interface. This does not apply to Google Compute Engine, as secondary IPv4 addresses are not assigned directly through the framework. +- Configure alias IPv4 ranges + +When running in Google Compute Engine or Amazon AWS, **cloud-netconfig** can +additionally set up alias IPv4 ranges on managed interfaces. For that purpose, +it will look up those ranges from the metedata server and add them to the +`local` routing table, which will cause the kernel to consider addresses +falling into those ranges as local ones. + - Create routing policies In case the system has more than one network interface, **cloud-netconfig** sets up routing in a way that packets are routed through the interface associated with the source address of the packet. To do that, it creates a -separate routing table for each interface with a default route according to the -interface configration. It also creates a routing policy to use that table for -packets using any of the interface's source addresses. This ensures that -packets are routed via the correct interface. - -Note: DHCP servers of cloud frameworks (this applies to Microsoft Azure at the -time of writing) may not include a gateway address in DHCP leases for secondary -IPv4 addresses. This is presumably to avoid default routes to clash. To enable -full connectivity in this case, **cloud-netconfig** assumes the gateway host to -be the first host of the sub-network assigned to the interface. +separate routing table for each interface with a default route according to +the interface configration. It also creates routing policies to use that table +for packets using any of the interface's source addresses. This ensures that +packets are routed via the correct interface. In case alias IPv4 ranges are +associated with the interface, routing policies will be created for those as +well. + +Note: DHCP servers of cloud frameworks may not include a gateway address in +DHCP leases for secondary IPv4 addresses. This is presumably to avoid default +routes to clash and potentially render the instance without functioning +external connectivity. With routing policies in place, multiple default routes +are feasible and **cloud-netconfig** will try to configure them where +applicable. In Google Compute Engine, the gateway address is available from +the metadata and **cloud-netconfig** will look it up and apply accordingly. If +no gateway information is available (which is the case in Microsoft Azure at +the time of writing), **cloud-netconfig** assumes the gateway host to be the +first host of the sub-network assigned to the interface. Interface configurations will be checked periodically on each DHCP lease -renewal and additionally, if the systemd timer is enabled (default on Amazon -EC2 and Microsoft Azure SUSE Linux Enterprise Server images), every 60 seconds. -**cloud-netconfig** detects changes in the metadata configuration and updates -interface configurations and routing policies accordingly. This means that IP -addresses that were removed from the virtual interface configuration will be -removed from the interface, but only addresses that were automatically added by -**cloud-netconfig** will be removed. Addresses added manually by the -administrator or by another tool (e.g. high-availability software) will not be -touched. +renewal and additionally, if the systemd timer is enabled, every 60 +seconds. **cloud-netconfig** detects changes in the metadata configuration and +updates interface configurations and routing policies accordingly. This means +that IP addresses and ranges that were removed from the virtual interface +configuration will be removed from the interface, but only addresses and +ranges that were automatically added by **cloud-netconfig** will be +removed. Addresses added manually by the administrator or by another tool +(e.g. high-availability software) will not be touched. ### Configuration diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/VERSION new/cloud-netconfig-1.7/VERSION --- old/cloud-netconfig-1.6/VERSION 2021-08-27 12:26:02.523795379 +0200 +++ new/cloud-netconfig-1.7/VERSION 2022-12-16 15:29:58.369590436 +0100 @@ -1 +1 @@ -1.6 +1.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/azure/61-cloud-netconfig-hotplug.rules new/cloud-netconfig-1.7/azure/61-cloud-netconfig-hotplug.rules --- old/cloud-netconfig-1.6/azure/61-cloud-netconfig-hotplug.rules 2018-07-10 18:22:11.173301719 +0200 +++ new/cloud-netconfig-1.7/azure/61-cloud-netconfig-hotplug.rules 2022-12-16 15:29:58.369590436 +0100 @@ -1 +1,2 @@ -SUBSYSTEM=="net", KERNEL=="eth*", DRIVERS=="hv_netvsc", RUN+="/etc/sysconfig/network/scripts/cloud-netconfig-hotplug" +SUBSYSTEM=="net", KERNEL=="eth*", DRIVERS=="hv_netvsc", RUN+="%SCRIPTDIR%/cloud-netconfig-hotplug" +SUBSYSTEM=="net", KERNEL=="eth*", DRIVERS=="mlx5_core", RUN+="%SCRIPTDIR%/cleanup-stale-ifcfg" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/azure/cleanup-stale-ifcfg new/cloud-netconfig-1.7/azure/cleanup-stale-ifcfg --- old/cloud-netconfig-1.6/azure/cleanup-stale-ifcfg 1970-01-01 01:00:00.000000000 +0100 +++ new/cloud-netconfig-1.7/azure/cleanup-stale-ifcfg 2022-12-16 15:29:58.369590436 +0100 @@ -0,0 +1,29 @@ +#!/bin/sh + +# Copyright (c) 2022 SUSE Software Solutions ltd +# +# This file is part of cloud-netconfig. +# +# cloud-netconfig is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cloud-netconfig is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cloud-netconfig. If not, see <http://www.gnu.org/licenses/>. + + +test -z "$INTERFACE" && exit 1 +ifcfg="/etc/sysconfig/network/ifcfg-${INTERFACE}" + +if [[ -f $ifcfg ]]; then + if grep -q -E "^CLOUD_NETCONFIG_MANAGE=[\'\"]?yes" $ifcfg ; then + logger -t cloud-netconfig "ifcfg file for $INTERFACE seems stale, deleting" + rm "/etc/sysconfig/network/ifcfg-${INTERFACE}" + fi +fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/azure/functions.cloud-netconfig new/cloud-netconfig-1.7/azure/functions.cloud-netconfig --- old/cloud-netconfig-1.6/azure/functions.cloud-netconfig 2021-08-27 16:55:30.278959254 +0200 +++ new/cloud-netconfig-1.7/azure/functions.cloud-netconfig 2022-12-16 15:29:58.369590436 +0100 @@ -37,7 +37,7 @@ return fi sleep 0.5 - result=$($CURL $url 2>/dev/null) + result=$($CURL $url | tr -d ' \n' 2>/dev/null) done echo -n $result @@ -47,7 +47,7 @@ # ------------------------------------------------------------------- # get the MAC address from the metadata server # format is uppercase without semicolons -# +# get_iface_mac() { local if_idx="$1" @@ -59,7 +59,7 @@ # ------------------------------------------------------------------- # gets all IPv4 address from the Azure metadata server for given # interface index -# +# get_ipv4_addresses_by_index() { local if_idx="$1" count=0 prefixlen="$2" @@ -75,8 +75,8 @@ } # ------------------------------------------------------------------- -# get IPv4 address from the Azure metadata server and return them -# +# get IPv4 addresses from the Azure metadata server and return them +# get_ipv4_addresses_from_metadata() { local idx hwaddr="$1" @@ -93,6 +93,22 @@ } # ------------------------------------------------------------------- +# dummy, no IP ranges in Azure +# +get_ipv4_ranges_from_metadata() +{ + return 0 +} + +# ------------------------------------------------------------------- +# dummy, no gateway information in metadata +# +get_gateway_from_metadata() +{ + return 0 +} + +# ------------------------------------------------------------------- # check whether metadata server is available # metadata_available() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/cloud-netconfig.spec new/cloud-netconfig-1.7/cloud-netconfig.spec --- old/cloud-netconfig-1.6/cloud-netconfig.spec 2021-08-27 12:26:02.523795379 +0200 +++ new/cloud-netconfig-1.7/cloud-netconfig.spec 2022-12-16 15:29:58.373590508 +0100 @@ -35,8 +35,13 @@ %define csp_string Google Compute Engine %endif +%if ! %{defined _distconfdir} +%define _distconfdir %{_sysconfdir} +%define no_dist_conf 1 +%endif + Name: %{base_name}%{flavor_suffix} -Version: 1.6 +Version: 1.7 Release: 0 License: GPL-3.0-or-later Summary: Network configuration scripts for %{csp_string} @@ -54,6 +59,7 @@ Requires: sysconfig-netconfig %endif BuildRequires: pkgconfig(udev) +BuildRequires: NetworkManager Requires: udev Requires: curl %if 0%{?sles_version} == 11 @@ -66,11 +72,27 @@ Conflicts: cloud-netconfig %endif %{?systemd_requires} +%define _scriptdir %{_libexecdir}/cloud-netconfig +%if 0%{?suse_version} > 1550 +%define _netconfigdir %{_libexecdir}/netconfig.d +%else +%define _netconfigdir %{_sysconfdir}/netconfig.d +%endif + %description -n %{base_name}%{flavor_suffix} This package contains scripts for automatically configuring network interfaces in %{csp_string} with full support for hotplug. +%package -n %{base_name}-nm +Summary: Network configuration scripts for %{csp_string} +Group: System/Management +Requires: cloud-netconfig +Requires: NetworkManager + +%description -n %{base_name}-nm +Dispatch script for NetworkManager that automatically runs cloud-netconfig. + %prep %setup -q -n %{base_name}-%{version} @@ -81,8 +103,11 @@ DESTDIR=%{buildroot} \ PREFIX=%{_usr} \ SYSCONFDIR=%{_sysconfdir} \ + DISTCONFDIR=%{_distconfdir} \ + SCRIPTDIR=%{_scriptdir} \ UDEVRULESDIR=%{_udevrulesdir} \ - UNITDIR=%{_unitdir} + UNITDIR=%{_unitdir} \ + NETCONFIGDIR=%{_netconfigdir} # Disable persistent net generator from udev-persistent-ifnames as # it does not work for xen interfaces. This will likely produce a warning. @@ -91,11 +116,16 @@ ln -s /dev/null %{buildroot}/%{_sysconfdir}/udev/rules.d/75-persistent-net-generator.rules %endif + %files -n %{base_name}%{flavor_suffix} %defattr(-,root,root) -%config(noreplace) %{_sysconfdir}/default/cloud-netconfig -%{_sysconfdir}/netconfig.d/cloud-netconfig -%{_sysconfdir}/sysconfig/network/scripts/* +%{_scriptdir} +%if %{defined no_config} +%config(noreplace) %{_distconfdir}/default/cloud-netconfig +%else +%{_distconfdir}/default/cloud-netconfig +%endif +%{_netconfigdir} %if 0%{?suse_version} >= 1315 %{_sysconfdir}/udev/rules.d %endif @@ -104,6 +134,9 @@ %doc README.md %license LICENSE +%files -n %{base_name}-nm +/usr/lib/NetworkManager/dispatcher.d + %pre %service_add_pre %{base_name}.service %{base_name}.timer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig new/cloud-netconfig-1.7/common/cloud-netconfig --- old/cloud-netconfig-1.6/common/cloud-netconfig 2021-08-27 15:23:21.154649724 +0200 +++ new/cloud-netconfig-1.7/common/cloud-netconfig 2022-12-16 15:29:58.373590508 +0100 @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (c) 2017 SUSE Linux GmbH +# Copyright (c) 2022 SUSE LLC # # This file is part of cloud-netconfig. # @@ -18,20 +18,135 @@ # along with cloud-netconfig. If not, see <http://www.gnu.org/licenses/ PROGNAME="cloud-netconfig" -# The environment variable ROOT indicates the root of the system to be -# managed by SuSEconfig when that root is not '/' -r="$ROOT" - -. "$r/etc/sysconfig/network/scripts/functions.netconfig" -# for get_ipv4_addresses_from_metadata() -. "$r/etc/sysconfig/network/scripts/functions.cloud-netconfig" +SCRIPTDIR=/usr/libexec/cloud-netconfig +STATEDIR=/run/wicked +ADDRDIR=/run/cloud-netconfig +LOCKFILE=/run/cloud-netconfig/lock + +. ${SCRIPTDIR}/functions.cloud-netconfig + +LOGGER_OPTS="-t $PROGNAME" +tty -s && LOGGER_OPTS="$LOGGER_OPTS -s" + +# ------------------------------------------------------------------- +# log debug message +# +debug () { + test "$QUIET" = "yes" && return + test "$DEBUG" = "yes" || return + logger $LOGGER_OPTS -p debug "$*" +} + +# ------------------------------------------------------------------- +# log warning message +# +warn () { + test "$QUIET" = "yes" && return + logger $LOGGER_OPTS -p warn -t "$*" +} + +# ------------------------------------------------------------------- +# log info message +# +log () { + test "$QUIET" = "yes" && return + logger $LOGGER_OPTS "$*" +} + +# ------------------------------------------------------------------- +# get variable from file +# +function get_variable() +{ + local line + while read line; do + eval $line + done < <(grep "^[[:space:]]*$1=" $2 2>/dev/null) +} + +# ------------------------------------------------------------------- +# print network service in use +# +get_network_service() +{ + IFS="=." + NET_SERVICE=(`systemctl --no-pager -p Id show network.service`) + echo "${NET_SERVICE[1]}" +} + +# ------------------------------------------------------------------- +# print relevant information from wicked lease info +# +get_wicked_lease_info() +{ + local iface="$1" cfg="${STATEDIR}/leaseinfo.${iface}.dhcp.ipv4" + if [ -e "$cfg" ]; then + grep -E '^IPADDR|^NETWORK|^NETMASK|^BROADCAST|^GATEWAYS|^ROUTES' $cfg + else + return 1 + fi +} + +# ------------------------------------------------------------------- +# print network info from given IPv4 address and netmask +# +calculate_network() +{ + local addr=$1 netmask=$2 + test -z "$addr" -o -z "$netmask" && return 1 + IFS=. read -r i1 i2 i3 i4 <<< "$addr" + IFS=. read -r m1 m2 m3 m4 <<< "$netmask" + printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))" +} + + +# ------------------------------------------------------------------- +# get relevant information from NetworkManager, map to expected +# variable names and print them +# +get_nm_lease_info() +{ + local iface="$1" + test -z `type -p nmcli` && { warn "nmcli not found, cannot configure interface" ; return 1 ; } + local ipaddr network netmask broadcast gateways prefixlen + ipaddr=`nmcli -f DHCP4 -t d show $iface | grep ':ip_address' | cut -d= -f2 | tr -d ' '` + netmask=`nmcli -f DHCP4 -t d show $iface | grep ':subnet_mask' | cut -d= -f2 | tr -d ' '` + broadcast=`nmcli -f DHCP4 -t d show $iface | grep ':broadcast_address' | cut -d= -f2 | tr -d ' '` + gateways=`nmcli -f DHCP4 -t d show $iface | grep ':routers' | cut -d= -f2 | tr ',' ' '` + echo "IPADDR=$ipaddr" + echo -n "NETWORK=" + calculate_network $ipaddr $netmask + echo "NETMASK=$netmask" + echo "BROADCAST=$broadcast" + echo "GATEWAYS=($gateways)" +} + + +# ------------------------------------------------------------------- +# print relevant lease information from used network system +# +get_lease_info() +{ + local iface="$1" + test -z "$iface" && return 1 + netsys=`get_network_service` + case "$netsys" in + "wicked") + get_wicked_lease_info "$iface" + ;; + "NetworkManager") + get_nm_lease_info "$iface" + ;; + "*") + return 1 + ;; + esac +} -STATEDIR=/var/run/netconfig -ADDRDIR=/var/run/netconfig/cloud # ------------------------------------------------------------------- # return all IPv4 addresses currently configured on given interface -# +# get_ipv4_addresses_from_interface() { local idx type addr iface="$1" @@ -43,7 +158,7 @@ # ------------------------------------------------------------------- # return all IPv6 addresses currently configured on given interface -# +# get_ipv6_addresses_from_interface() { local idx iface_r scope_lit scope type addr rest iface="$1" @@ -60,7 +175,7 @@ # ------------------------------------------------------------------- # compare arrays and return the ones that are in the first but not # the second -# +# get_extra_elements() { local actual=(${!1}) target=(${!2}) @@ -93,46 +208,16 @@ } # ------------------------------------------------------------------- -# look up a free priority with a given prefix from the rule table -# -get_free_priority() -{ - local prefix="$1" - test -z "$prefix" && return 1 - - local IPV - [[ -n "$2" ]] && IPV="-${2}" - - local prio=$((prefix*100)) - local taken - while [[ $prio -lt $((prefix*100+100)) ]]; do - taken=0 - while read -r no rest ; do - if [[ "${prio}" == "${no%%:}" ]]; then - taken=1 - break - fi - done < <(ip $IPV rule show) - if [[ $taken == 0 ]]; then - echo -n "${prio}" - return - fi - prio=$((prio+1)) - done - warn "No free priority for prefix $prefix" - echo -n "29999" -} - -# ------------------------------------------------------------------- # get IPv4 addresses from log dir # get_cn_assigned_addrs() { local iface="$1" + local addr_type="$2" test -z "$iface" && return 1 - if [[ -e ${ADDRDIR}/${iface} ]]; then - echo $(cat ${ADDRDIR}/${iface}) + if [[ -e ${ADDRDIR}/${addr_type}${iface} ]]; then + echo $(cat ${ADDRDIR}/${addr_type}${iface}) fi } @@ -154,9 +239,10 @@ { local iface="$1" local addr="$2" + local addr_type="$3" test -z "$iface" -o -z "$addr" && return 1 - addr_log_file="${ADDRDIR}/${iface}" + addr_log_file="${ADDRDIR}/${addr_type}${iface}" if [[ -e ${addr_log_file} ]]; then grep -q -x "${addr}" "${addr_log_file}" || echo "${addr}" >> "${addr_log_file}" else @@ -172,9 +258,10 @@ { local iface="$1" local addr="$2" + local addr_type="$3" test -z "$iface" -o -z "$addr" && return 1 - addr_log_file="${ADDRDIR}/${iface}" + addr_log_file="${ADDRDIR}/${addr_type}${iface}" if [[ -e ${addr_log_file} ]]; then addr_log_file_tmp=$(mktemp ${ADDRDIR}/${iface}.XXXXXXXX) if [ $? -ne 0 ]; then @@ -190,34 +277,75 @@ # copy routes from default table to given table and remove routes # that do not exist in default table (if any) # -update_routing_table() +update_routing_tables() { - local rtable="$1" + local ipv="$1" local iface="$2" + local dest_table="$3" + local gw_table="$4" - test -z "$rtable" && return 1 + test -z "$gw_table" && return 1 - # copy routes from default table - for ipv in "-4" "-6" ; do - ip $ipv route show | grep -v "^default" | while read route ; do - ip $ipv route replace $route table $rtable - done + # copy destination specific routes from default table + ip $ipv route show dev $iface | grep -v "^default" | while read route ; do + # expires arg can't be used as is, drop it + route=$(echo $route | sed -e 's/expires [^ ]*//') + debug "creating/replacing route $route dev $iface table $dest_table" + ip $ipv route replace $route dev $iface table $dest_table + done + + # copy gateway route(s) from default table + ip $ipv route show default dev $iface | while read route ; do + route=$(echo $route | sed -e 's/expires [^ ]*//') + debug "creating/replacing route $route dev $iface table $gw_table" + ip $ipv route replace $route dev $iface table $gw_table + done + + # check if there are any leftover routes and delete them + ip $ipv route show all table $dest_table | grep -v "^default" | while read route; do + ip_out="$(ip $ipv route show $route)" + if [[ -z "$ip_out" ]]; then + debug "deleting obsolete route $route from table $dest_table" + ip $ipv route del $route table $dest_table + fi + done +} - # Do a second run with routes specific to the interface being configured. - # This makes sure that in case there are competing routes (same destination - # but different device), the one matching the right interface is selected. - # This situation can happen in case there are multiple interfaces that are - # connected to the same subnet. - ip $ipv route show dev "$iface" | grep -v "^default" | while read route ; do - ip $ipv route replace $route dev "$iface" table $rtable - done +# ------------------------------------------------------------------- +# copy routes from default table to given table and remove routes +# that do not exist in default table (if any) +# +update_routing_policies() +{ + local ipv="$1" + local iface="$2" + local dest_table="$3" + local gw_table="$4" + local -n addrs=$5 - # check if there are any leftover routes and delete them - ip $ipv route show all table $rtable | grep -v "^default" | while read route ; do - ip_out="$(ip $ipv route show $route)" - test -z "$ip_out" && ip $ipv route del $route table $rtable - done + # update routing policies so connections from addresses on + # secondary interfaces are routed via those + # also include IP rangers + local found prio from ip rest + for addr in ${addrs[@]} ; do + found=0 + while read -r prio from ip rest ; do + if [[ "${addr%/32}" == "$ip" ]]; then + found=1 + break + fi + done < <(ip $ipv rule show) + if [[ $found == 0 ]]; then + debug "creating policy rule for src address ${addr%/32}" + ip $ipv rule add from ${addr%/32} priority $dest_table lookup $dest_table + ip $ipv rule add from ${addr%/32} priority $gw_table lookup $gw_table + fi done + + # create main (w/o default) lookup rule, if necessary + if [[ -z "$(ip $ipv rule show prio 30399)" ]]; then + ip $ipv rule add from all table main prio 30399 suppress_prefixlength 0 + fi } # ------------------------------------------------------------------- @@ -226,23 +354,38 @@ # configure_interface_ipv4() { - local cfg="$1" - test -z "$cfg" -o ! -f "$cfg" && return 1 - local INTERFACE IPADDR NETWORK NETMASK BROADCAST GATEWAYS - get_variable "INTERFACE" "$cfg" - get_variable "IPADDR" "$cfg" - get_variable "NETWORK" "$cfg" - get_variable "NETMASK" "$cfg" - get_variable "BROADCAST" "$cfg" - get_variable "GATEWAYS" "$cfg" - get_variable "PREFIXLEN" "$cfg" - get_variable "ROUTES" "$cfg" + local INTERFACE="$1" + test -z "$INTERFACE" && return 1 + local IPADDR NETWORK NETMASK BROADCAST GATEWAYS + eval `get_lease_info $INTERFACE` + if [ -z "$IPADDR" ]; then + warn "Could not determine address from DHCP4 lease info" + return 1 + fi local HWADDR="$(cat /sys/class/net/${INTERFACE}/address)" - local RTABLE="10${INTERFACE: -1}" + if [ -z "$HWADDR" ]; then + warn "Could not determine MAC address for $INTERFACE" + return 1 + fi + local ifindex="$(cat /sys/class/net/${INTERFACE}/ifindex)" + if [ -z "$ifindex" ]; then + warn "Could not determine interface index for $INTERFACE" + return 1 + fi + local dest_table="$((ifindex+30000))" + local gw_table="$((ifindex+30400))" # get active and configured addresses local laddrs=($(get_ipv4_addresses_from_interface $INTERFACE)) - local raddrs=($(get_ipv4_addresses_from_metadata $HWADDR)) + local raddrs addr + for addr in $(get_ipv4_addresses_from_metadata $HWADDR) ; do + # validate whether element looks like an IPv4 address + if [[ $addr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then + raddrs+=($addr) + else + warn "IPv4 address \"${addr}\" from instance metadata does not look valid, skipping" + fi + done # get differences local addr_to_remove=($(get_extra_elements laddrs[@] raddrs[@])) @@ -256,7 +399,6 @@ debug "excess addresses on $INTERFACE: ${addr_to_remove[@]}" debug "addresses to configure on $INTERFACE: ${addr_to_add[@]}" - local addr priority for addr in ${addr_to_remove[@]} ; do # as a safety measure, check against the address received via DHCP and # refuse to remove it even if it is not in the meta data @@ -286,6 +428,28 @@ add_addr_to_log $INTERFACE $addr done + local ip_ranges=$(get_ipv4_ranges_from_metadata $HWADDR) + local local_route + for ipr in $ip_ranges; do + local_route=$(ip r show $ipr type local table local) + if [[ -z $local_route ]]; then + debug "No local route for IP range $ipr, creating one" + ip -4 r add local $ipr dev $INTERFACE table local + add_addr_to_log $INTERFACE $ipr aliases_ + fi + done + # check if cloud-netconfig configured IP aliases were removed + local cn_ip_ranges=$(get_cn_assigned_addrs $INTERFACE ranges_) + if [[ -n $cn_ip_ranges ]]; then + for ipr in $cn_ip_ranges ; do + if [[ " $ip_ranges " == *" $ipr "* ]]; then + debug "IP range $ipr was removed, dropping local route" + ip -4 r del local $ipr dev $INTERFACE table local + remove_addr_from_log $INTERFACE $ipr ranges_ + fi + done + fi + # If we have a single NIC configuration, skip routing policies if [[ $SINGLE_NIC = yes ]]; then return @@ -295,26 +459,18 @@ # need a separate route table so we can send packets there # using routing policy. Check whether the table is there and # create it if not. - if [ -z "$(ip -4 route show default dev $INTERFACE table $RTABLE)" ]; then + if [ -z "$(ip -4 route show default dev $INTERFACE)" ]; then local GW GWS=() # we simply take the first gateway in case there is more than one eval GWS=\(${GATEWAYS}\) if [[ -n "${GWS[0]}" ]]; then GW="${GWS[0]}" else - debug "No gateway from DHCP4, guessing" - # no default route, guess one - if [[ $PREFIXLEN = 32 ]]; then - # peer-to-peer setup but no gateway. At the time of writing - # that is the setup in GCE. Subnet routes and gateway get - # delivered by DHCP as addtional routes. - for r in $ROUTES ; do - if [[ ${r##*,} = 0.0.0.0 ]]; then - GW="${r%%,*}" - break - fi - done - else + # GCE does not provide a gateway for secondary NICs in the + # lease info but is available via meta data. + GW=$(get_gateway_from_metadata $HWADDR) + if [ -z $GW ]; then + debug "No gateway info available for $INTERFACE, guessing" # we assume the gateway is the first host of the network local netstart=${NETWORK##*.} local gw_host_part=$((netstart+1)) @@ -322,32 +478,47 @@ fi fi if [[ -n $GW ]]; then - debug "adding default route via $GW for $INTERFACE table $RTABLE" - ip -4 route add default via $GW dev "$INTERFACE" table "$RTABLE" + debug "adding default route via $GW for $INTERFACE table $GW_TABLE" + ip -4 route add default via $GW dev "$INTERFACE" metric $((ifindex+20000)) else warn "No default route for $INTERFACE" fi fi # copy specific routes from the default routing table - update_routing_table $RTABLE $INTERFACE + update_routing_tables -4 $INTERFACE $dest_table $gw_table # update routing policies so connections from addresses on # secondary interfaces are routed via those - local found prio from ip rest + # also include IP rangers + #local found prio from ip rest + #for addr in ${raddrs[@]} $ip_ranges ; do + # found=0 + # while read -r prio from ip rest ; do + # if [[ "${addr%/32}" == "$ip" ]]; then + # found=1 + # break + # fi + # done < <(ip -4 rule show) + # if [[ $found == 0 ]]; then + # debug "creating policy rule for src address ${addr%/32}" + # #priority=$(get_free_priority $LOCAL_TABLE 4) + # ip -4 rule add from ${addr%/32} priority $dest_table lookup $dest_table + # #priority=$(get_free_priority $GW_TABLE 4) + # ip -4 rule add from ${addr%/32} priority $gw_table lookup $gw_table + # fi + #done + local all_addrs=() for addr in ${raddrs[@]} ; do - found=0 - while read -r prio from ip rest ; do - if [[ "${addr%/*}" == "$ip" ]]; then - found=1 - break - fi - done < <(ip -4 rule show) - if [[ $found == 0 ]]; then - priority=$(get_free_priority $RTABLE 4) - ip -4 rule add from ${addr%/*} priority $priority table $RTABLE - fi + all_addrs+=("${addr%/*}") done + all_addrs+=($ip_ranges) + update_routing_policies -4 $INTERFACE $dest_table $gw_table all_addrs + + # create main (w/o default) lookup rule, if necessary + if [[ -z "$(ip -4 rule show prio 30399)" ]]; then + ip -4 rule add from all table main prio 30399 suppress_prefixlength 0 + fi } # ------------------------------------------------------------------- @@ -355,23 +526,20 @@ # configure_interface_ipv6() { - local cfg="$1" - test -z "$cfg" -o ! -f "$cfg" && return 1 - get_variable "INTERFACE" "$cfg" - - # NOTE: unlike with IPv4, we set up routing policies even for the primary - # interface. Default routes for IPv6 will likely have the same metric, so - # unlike with the IPv4 routes, where we use higher metrics for the non - # primary interfaces, we may run into the situation where the kernel picks - # the default route of a non primary interface as the main default. Using - # routing policies prevents that, but it means there will be a routing - # policy even if you do not have a secondary interface at all (not a - # problem, just not as nice as it could be). + local INTERFACE="$1" + test -z "$INTERFACE" && return 1 + + local ifindex="$(cat /sys/class/net/${INTERFACE}/ifindex)" + if [ -z "$ifindex" ]; then + warn "Could not determine interface index for $INTERFACE" + return 1 + fi - local RTABLE="10${INTERFACE: -1}" + local dest_table="$((ifindex+30000))" + local gw_table="$((ifindex+30400))" # if necessary, create route table with default route for interface - if [ -z "$(ip -6 route show default dev $INTERFACE table $RTABLE)" ]; then + if [ -z "$(ip -6 route show default dev $INTERFACE table $RTABLE 2>/dev/null)" ]; then # it is possible that we received the DHCP response before the # the router advertisement; in that case, we wait up to 10 secs local route via GW rest counter=0 @@ -384,28 +552,54 @@ sleep 1 fi done - if [[ -z "$GW" ]]; then - warn "no IPv6 default route available for $INTERFACE" - return - fi - ip -6 route add default via $GW dev $INTERFACE table $RTABLE fi - local addr laddrs=($(get_ipv6_addresses_from_interface $INTERFACE)) - local found prio from ip rest - for addr in ${laddrs[@]} ; do - found=0 - while read -r prio from ip rest ; do - if [[ "${addr%/*}" == "$ip" ]]; then - found=1 - break - fi - done < <(ip -6 rule show) - if [[ $found == 0 ]]; then - priority=$(get_free_priority $RTABLE 6) - ip -6 rule add from ${addr%/*} priority $priority table $RTABLE - fi - done + update_routing_tables -6 $INTERFACE $dest_table $gw_table + local laddrs=($(get_ipv6_addresses_from_interface $INTERFACE)) + update_routing_policies -6 $INTERFACE $dest_table $gw_table laddrs + + #local addr laddrs=($(get_ipv6_addresses_from_interface $INTERFACE)) + #local found prio from ip rest + #for addr in ${laddrs[@]} ; do + # found=0 + # while read -r prio from ip rest ; do + # if [[ "${addr%/*}" == "$ip" ]]; then + # found=1 + # break + # fi + # done < <(ip -6 rule show) + # if [[ $found == 0 ]]; then + # priority=$(get_free_priority $RTABLE 6) + # debug "creating policy rule for address ${addr%/*}" + # ip -6 rule add from ${addr%/*} priority $priority table $RTABLE + # fi + #done + + ## create main (w/o default) lookup rule, if necessary + #if [[ -z "$(ip -6 rule show prio 30399)" ]]; then + # ip -6 rule add from all table main prio 30399 suppress_prefixlength 0 + #fi +} + +# ------------------------------------------------------------------- +# Check if interface has a DHCP lease. Takes interface name +# and IP version. +# +iface_has_lease() +{ + local iface="$1" ipv="$2" + test -z "$iface" && return 1 + test "$ipv" != "4" -a "$ipv" != "6" && return 1 + + local netsys=`get_network_service` + if [ "$netsys" == "wicked" ]; then + test -e /run/wicked/leaseinfo.${iface}.dhcp.ipv${ipv} + return $? + elif [ "$netsys" == "NetworkManager" ]; then + nmcli -f DHCP${ipv} -t d show $iface | grep -q -E ':ip6?_address' + return $? + fi + return 1 } # ------------------------------------------------------------------- @@ -415,55 +609,68 @@ # manage_interfaceconfig() { - local cfg="$1" - test -z "$cfg" -o ! -d "$cfg" && return 1 - local ifcfg="/etc/sysconfig/network/ifcfg-${cfg##*/}" + local iface="$1" + test -z "$iface" && return 1 + local netsys=`get_network_service` local CLOUD_NETCONFIG_MANAGE - if [[ -f "${ifcfg}" ]]; then - get_variable "CLOUD_NETCONFIG_MANAGE" "${ifcfg}" + if [ "$netsys" == "wicked" ]; then + local ifcfg="/etc/sysconfig/network/ifcfg-${iface}" + if [[ -f "${ifcfg}" ]]; then + get_variable "CLOUD_NETCONFIG_MANAGE" "${ifcfg}" + fi + elif [ "$netsys" == "NetworkManager" ]; then + get_variable "CLOUD_NETCONFIG_MANAGE" /etc/default/cloud-netconfig + else + debug "Unknown network service $netsys. Not handling interface configuration." + return fi if [[ "$CLOUD_NETCONFIG_MANAGE" != "yes" ]]; then # do not touch interface - debug "Not managing interface ${cfg##*/}" + debug "Not managing interface ${iface}" return fi - linkstatus=$(get_link_status ${cfg##*/}) + linkstatus=$(get_link_status ${iface}) if [[ $linkstatus != UP ]]; then - debug "interface ${cfg##*/} is down" + debug "interface ${iface} is down" return fi if ! metadata_available ; then - warn "Cannot access instance metadata, skipping interface configuration for ${cfg##*/}" + warn "Cannot access instance metadata, skipping interface configuration for ${iface}" return fi - for cfg in ${1}/* ; do - test -f $cfg || continue - get_variable "SERVICE" "$cfg" - case "$SERVICE" in - "wicked-dhcp-ipv4"|"dhcpcd") - configure_interface_ipv4 "$cfg" - ;; - "wicked-dhcp-ipv6"|"dhcp6c") - configure_interface_ipv6 "$cfg" - ;; - esac - done + iface_has_lease $iface 4 && configure_interface_ipv4 $iface + iface_has_lease $iface 6 && configure_interface_ipv6 $iface } -if_dirs=() -for IFDIR in $STATEDIR/* ; do - test -d $IFDIR -a -d "/sys/class/net/${IFDIR##*/}" || continue - test ${IFDIR##*/} = "lo" && continue - if_dirs+=($IFDIR) +if [ ! -d $ADDRDIR ]; then + rm -f $ADDRDIR + mkdir $ADDRDIR +fi + +test -e "$LOCKFILE" && exit 0 + +trap "rm -f $LOCKFILE" EXIT +touch $LOCKFILE + +get_variable DEBUG /etc/sysconfig/network/config + +nics=() +for IFDIR in /sys/class/net/* ; do + # skip virtual and bonded interfaces + test -e $IFDIR/device || continue + test -e $IFDIR/master && continue + nics+=(${IFDIR##*/}) done # set single NIC flag if appropriate -if [[ ${#if_dirs[@]} -eq 1 ]]; then +if [[ ${#nics[@]} -eq 1 ]]; then SINGLE_NIC=yes else SINGLE_NIC=no fi -for IFDIR in ${if_dirs[@]} ; do - manage_interfaceconfig $IFDIR +for nic in ${nics[@]} ; do + manage_interfaceconfig $nic done + +exit 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-default new/cloud-netconfig-1.7/common/cloud-netconfig-default --- old/cloud-netconfig-1.6/common/cloud-netconfig-default 2020-02-04 18:31:10.628357312 +0100 +++ new/cloud-netconfig-1.7/common/cloud-netconfig-default 2022-12-16 15:29:58.373590508 +0100 @@ -1,2 +1,4 @@ -# Default value cloud-netconfig should use when creating new ifcfg files +# Default value cloud-netconfig should use when creating new ifcfg files. +# On systems that use NetworkManager systems, this globally enables or +# disables cloud-netconfig. CLOUD_NETCONFIG_MANAGE="yes" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-hotplug new/cloud-netconfig-1.7/common/cloud-netconfig-hotplug --- old/cloud-netconfig-1.6/common/cloud-netconfig-hotplug 2020-02-04 18:31:10.628357312 +0100 +++ new/cloud-netconfig-1.7/common/cloud-netconfig-hotplug 2022-12-16 15:29:58.373590508 +0100 @@ -1,6 +1,6 @@ -#!/bin/sh +#!/bin/bash -# Copyright (c) 2017 SUSE Linux GmbH +# Copyright (c) 2022 SUSE LLC # # This file is part of cloud-netconfig. # @@ -17,10 +17,13 @@ # You should have received a copy of the GNU General Public License # along with cloud-netconfig. If not, see <http://www.gnu.org/licenses/>. +SCRIPTDIR=/usr/libexec/cloud-netconfig +DISTCONFDIR=/usr/etc test -z "$INTERFACE" && exit 1 test "$INTERFACE" == "eth0" && exit 0 +test -f ${DISTCONFDIR}/default/cloud-netconfig && . ${DISTCONFDIR}/default/cloud-netconfig test -f /etc/default/cloud-netconfig && . /etc/default/cloud-netconfig test -z "$CLOUD_NETCONFIG_MANAGE" && CLOUD_NETCONFIG_MANAGE=yes @@ -100,7 +103,7 @@ ;; remove) - /etc/sysconfig/network/scripts/cloud-netconfig-cleanup + ${SCRIPTDIR}/cloud-netconfig-cleanup ;; esac diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-nm new/cloud-netconfig-1.7/common/cloud-netconfig-nm --- old/cloud-netconfig-1.6/common/cloud-netconfig-nm 1970-01-01 01:00:00.000000000 +0100 +++ new/cloud-netconfig-1.7/common/cloud-netconfig-nm 2022-12-16 15:29:58.373590508 +0100 @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright (c) 2022 SUSE LLC +# +# This file is part of cloud-netconfig. +# +# cloud-netconfig is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cloud-netconfig is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cloud-netconfig. If not, see <http://www.gnu.org/licenses/ + +# This is a NetworkManager dispatcher script. It runs cloud-netconfig setup on +# interface up and cloud-netconfig cleanup on interface down. + +SCRIPTDIR=/usr/libexec/cloud-netconfig + +if [ "$2" == "up" ]; then + ${SCRIPTDIR}/cloud-netconfig +elif [ "$2" == "down" ]; then + ${SCRIPTDIR}/cloud-netconfig-cleanup +fi + +echo $? diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/common/cloud-netconfig-wrapper new/cloud-netconfig-1.7/common/cloud-netconfig-wrapper --- old/cloud-netconfig-1.6/common/cloud-netconfig-wrapper 1970-01-01 01:00:00.000000000 +0100 +++ new/cloud-netconfig-1.7/common/cloud-netconfig-wrapper 2022-12-16 15:29:58.373590508 +0100 @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright (c) 2022 SUSE LLC +# +# This file is part of cloud-netconfig. +# +# cloud-netconfig is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cloud-netconfig is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cloud-netconfig. If not, see <http://www.gnu.org/licenses/ + +# Netconfig wrapper script for cloud-netconfig + +SCRIPTDIR=/usr/libexec/cloud-netconfig +IFS="=." +NET_SERVICE=(`systemctl --no-pager -p Id show network.service`) + +if [ "${NET_SERVICE[1]}" == "NetworkManager" ]; then + # handled via NetworkManager dispatch script + exit 0 +fi + +exec $SCRIPTDIR/cloud-netconfig diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/ec2/51-cloud-netconfig-hotplug.rules new/cloud-netconfig-1.7/ec2/51-cloud-netconfig-hotplug.rules --- old/cloud-netconfig-1.6/ec2/51-cloud-netconfig-hotplug.rules 2018-07-10 18:22:11.177301751 +0200 +++ new/cloud-netconfig-1.7/ec2/51-cloud-netconfig-hotplug.rules 2022-12-16 15:29:58.377590583 +0100 @@ -1,2 +1,2 @@ ACTION=="add", SUBSYSTEM=="net", KERNEL=="eth*", IMPORT{program}="/bin/sleep 1" -SUBSYSTEM=="net", KERNEL=="eth*", RUN+="/etc/sysconfig/network/scripts/cloud-netconfig-hotplug" +SUBSYSTEM=="net", KERNEL=="eth*", RUN+="%SCRIPTDIR%/cloud-netconfig-hotplug" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/ec2/functions.cloud-netconfig new/cloud-netconfig-1.7/ec2/functions.cloud-netconfig --- old/cloud-netconfig-1.6/ec2/functions.cloud-netconfig 2021-08-27 16:55:30.278959254 +0200 +++ new/cloud-netconfig-1.7/ec2/functions.cloud-netconfig 2022-12-16 15:29:58.377590583 +0100 @@ -16,7 +16,7 @@ # # You should have received a copy of the GNU General Public License -API_VERSION="2018-09-24" +API_VERSION="latest" METADATA_URL_BASE="http://169.254.169.254/${API_VERSION}" METADATA_URL_IFACE="${METADATA_URL_BASE}/meta-data/network/interfaces/macs" CURL="curl -m 3 --noproxy 169.254.169.254" @@ -65,7 +65,7 @@ # ------------------------------------------------------------------- # get IPv4 address from the EC2 meta data server and return them -# +# get_ipv4_addresses_from_metadata() { local addr count=0 hwaddr="$1" prefixlen @@ -93,11 +93,34 @@ } # ------------------------------------------------------------------- +# get IPv4 range (prefix in EC2 term) for interface +# +get_ipv4_ranges_from_metadata() +{ + local hwaddr="$1" prefixes + test -z "$hwaddr" && return + set_from_metadata prefixes "${METADATA_URL_IFACE}/${hwaddr}/ipv4-prefix" || return 1 + echo $prefixes +} + +# ------------------------------------------------------------------- +# dummy, EC2 provides gateway information in DHCP4 offer +# +get_gateway_from_metadata() +{ + return 0 +} + +# ------------------------------------------------------------------- # check if metadata server is available -# +# metadata_available() { check_url "${METADATA_URL_BASE}/meta-data/" return $? } +# if eth0 and eth1 are on the same subnet, packets may be disrouted and +# since policy rules may not be in place yet render IMDS inaccessible; +# force eth0 as work-around +metadata_available || test -e /sys/class/net/eth0 && CURL="$CURL --interface eth0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/gce/51-cloud-netconfig-hotplug.rules new/cloud-netconfig-1.7/gce/51-cloud-netconfig-hotplug.rules --- old/cloud-netconfig-1.6/gce/51-cloud-netconfig-hotplug.rules 2020-11-04 17:33:04.668500917 +0100 +++ new/cloud-netconfig-1.7/gce/51-cloud-netconfig-hotplug.rules 2022-12-16 15:29:58.377590583 +0100 @@ -1,2 +1,2 @@ ACTION=="add", SUBSYSTEM=="net", KERNEL=="eth*", IMPORT{program}="/bin/sleep 1" -SUBSYSTEM=="net", KERNEL=="eth*", RUN+="/etc/sysconfig/network/scripts/cloud-netconfig-hotplug" +SUBSYSTEM=="net", KERNEL=="eth*", RUN+="%SCRIPTDIR%/cloud-netconfig-hotplug" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/gce/functions.cloud-netconfig new/cloud-netconfig-1.7/gce/functions.cloud-netconfig --- old/cloud-netconfig-1.6/gce/functions.cloud-netconfig 2020-11-04 17:33:04.668500917 +0100 +++ new/cloud-netconfig-1.7/gce/functions.cloud-netconfig 2022-12-16 15:29:58.377590583 +0100 @@ -16,30 +16,95 @@ # # You should have received a copy of the GNU General Public License +METADATA_BASE_URL="http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/" +URL_HDR="Metadata-Flavor:Google" +CURL="curl -m 3 --noproxy 169.254.169.254 -H $URL_HDR" + +# ------------------------------------------------------------------- +# look up a meta data item +# +get_from_metadata() +{ + local url="${METADATA_BASE_URL}${1}" + local result=$($CURL $url 2>/dev/null) + echo -n $result +} + # ------------------------------------------------------------------- # no metadata lookup in GCE required due to no secondary IP addresses # simply look up local addresses # get_ipv4_addresses_from_metadata() { - local iface status mac if_match addr hwaddr="$1" + local hwaddr="$1" test -z "$hwaddr" && return 1 - while read -r iface status mac rest ; do + + local nics=$(get_from_metadata) + for idx in $nics ; do + local mac=$(get_from_metadata "${idx}mac") + if [[ $mac == $hwaddr ]]; then + local addr=$(get_from_metadata ${idx}ip) + if [[ ${addr} == ${addr%/*} ]]; then + addr="${addr}/32" + fi + echo $addr + return 0 + fi + done + return 1 +} + +# ------------------------------------------------------------------- +# look up gateway information in metadata +# +get_gateway_from_metadata() +{ + local hwaddr="$1" + test -z "$hwaddr" && return 1 + + local nics=$(get_from_metadata) + for idx in $nics ; do + local mac=$(get_from_metadata "${idx}mac") + if [[ $mac == $hwaddr ]]; then + get_from_metadata ${idx}gateway + return 0 + fi + done + return 1 +} + +# ------------------------------------------------------------------- +# look up IP range information for interface +# +get_ipv4_ranges_from_metadata() +{ + local hwaddr="$1" mac ipalias ipaliases aliases_str + test -z "$hwaddr" && return 1 + + local nics=$(get_from_metadata) + for idx in $nics ; do + mac=$(get_from_metadata "${idx}mac") if [[ $mac == $hwaddr ]]; then - if_match=$iface - break + ipaliases=$(get_from_metadata ${idx}ip-aliases/) + if [[ -n $ipaliases ]]; then + for ipalias in $ipaliases ; do + aliases_str="$aliases_str `get_from_metadata "${idx}ip-aliases/${ipalias}" | tr -d '\n'`" + done + echo $aliases_str + fi + return 0 fi - done < <(ip -br -o -4 link show) - if [[ -n $if_match ]]; then - ip -br -4 -o addr show dev $if_match | awk '{ print $3 }' - fi + done + return 1 } # ------------------------------------------------------------------- -# dummy function, metadata not used +# check whether metadata is available # metadata_available() { - return 0 + local resp=$($CURL "http://metadata.google.internal/computeMetadata/v1/instance/id" 2>/dev/null) + [[ -n "$resp" ]] + return $? } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloud-netconfig-1.6/systemd/cloud-netconfig.service new/cloud-netconfig-1.7/systemd/cloud-netconfig.service --- old/cloud-netconfig-1.6/systemd/cloud-netconfig.service 2019-01-31 14:11:27.891295667 +0100 +++ new/cloud-netconfig-1.7/systemd/cloud-netconfig.service 2022-12-16 15:29:58.377590583 +0100 @@ -3,4 +3,4 @@ [Service] Type=oneshot -ExecStart=-/bin/bash -c '/sbin/netconfig -m cloud-netconfig update' +ExecStart=-/bin/bash -c '%SCRIPTDIR%/cloud-netconfig'