1
0
mirror of https://github.com/systemd/systemd synced 2026-04-10 09:04:50 +02:00

Compare commits

..

No commits in common. "f333ed27fac2472ef5ab0d6fb980eea8353ced8d" and "8b0bc54cdb35a5353e09a49e0732bf5601c749ad" have entirely different histories.

77 changed files with 625 additions and 1798 deletions

View File

@ -1,9 +0,0 @@
---
# vi: ts=2 sw=2 et:
# SPDX-License-Identifier: LGPL-2.1-or-later
blank_issues_enabled: true
contact_links:
- name: systemd-devel mailing list
url: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
about: Please ask (and answer) questions here, use the issue tracker only for issues.

View File

@ -1,12 +0,0 @@
---
# vi: ts=2 sw=2 et:
# SPDX-License-Identifier: LGPL-2.1-or-later
name: "CodeQL config"
disable-default-queries: false
queries:
- name: Enable possibly useful queries which are disabled by default
uses: ./.github/codeql-custom.qls
- name: systemd-specific CodeQL queries
uses: ./.lgtm/cpp-queries/

View File

@ -1,33 +0,0 @@
---
# vi: ts=2 sw=2 et syntax=yaml:
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Note: it is not recommended to directly reference the respective queries from
# the github/codeql repository, so we have to "dance" around it using
# a custom QL suite
# See:
# - https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#running-additional-queries
# - https://github.com/github/codeql-action/issues/430#issuecomment-806092120
# - https://codeql.github.com/docs/codeql-cli/creating-codeql-query-suites/
- import: codeql-suites/cpp-lgtm.qls
from: codeql/cpp-queries
- include:
id:
- cpp/bad-strncpy-size
- cpp/declaration-hides-variable
- cpp/inconsistent-null-check
- cpp/mistyped-function-arguments
- cpp/nested-loops-with-same-variable
- cpp/sizeof-side-effect
- cpp/suspicious-pointer-scaling
- cpp/suspicious-pointer-scaling-void
- cpp/suspicious-sizeof
- cpp/unsafe-strcat
- cpp/unsafe-strncat
- cpp/unsigned-difference-expression-compared-zero
- cpp/unused-local-variable
tags:
- "security"
- "correctness"
severity: "error"

View File

@ -7,10 +7,6 @@ name: "CodeQL"
on: on:
pull_request: pull_request:
branches: [main] branches: [main]
paths:
- .github/codeql-config.yml
- .github/codeql-custom.qls
- .github/workflows/codeql-analysis.yml
# It takes the workflow approximately 30 minutes to analyze the code base # It takes the workflow approximately 30 minutes to analyze the code base
# so it doesn't seem to make much sense to trigger it on every PR or commit. # so it doesn't seem to make much sense to trigger it on every PR or commit.
# It runs daily at 01:00 to avoid colliding with the Coverity workflow. # It runs daily at 01:00 to avoid colliding with the Coverity workflow.
@ -24,6 +20,7 @@ jobs:
analyze: analyze:
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name == 'schedule' || github.event.pull_request.user.login == 'dependabot[bot]'
concurrency: concurrency:
group: ${{ github.workflow }}-${{ matrix.language }}-${{ github.ref }} group: ${{ github.workflow }}-${{ matrix.language }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
@ -44,7 +41,6 @@ jobs:
uses: github/codeql-action/init@546b30f35ae5a3db0e0be1843008c2224f71c3b0 uses: github/codeql-action/init@546b30f35ae5a3db0e0be1843008c2224f71c3b0
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
config-file: ./.github/codeql-config.yml
- run: sudo -E .github/workflows/unit_tests.sh SETUP - run: sudo -E .github/workflows/unit_tests.sh SETUP

View File

@ -1,6 +1,5 @@
--- ---
# vi: ts=2 sw=2 et: # vi: ts=2 sw=2 et:
# SPDX-License-Identifier: LGPL-2.1-or-later
# Explicitly enable certain checks which are hidden by default # Explicitly enable certain checks which are hidden by default
queries: queries:

View File

@ -1,11 +0,0 @@
---
# vi: ts=2 sw=2 et syntax=yaml:
# SPDX-License-Identifier: LGPL-2.1-or-later
library: false
name: systemd/cpp-queries
version: 0.0.1
dependencies:
codeql/cpp-all: "*"
codeql/suite-helpers: "*"
extractor: cpp

View File

@ -74,10 +74,6 @@ node /org/freedesktop/systemd1 {
StartUnit(in s name, StartUnit(in s name,
in s mode, in s mode,
out o job); out o job);
StartUnitWithFlags(in s name,
in s mode,
in t flags,
out o job);
StartUnitReplace(in s old_unit, StartUnitReplace(in s old_unit,
in s new_unit, in s new_unit,
in s mode, in s mode,
@ -334,10 +330,6 @@ node /org/freedesktop/systemd1 {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadFinishTimestampMonotonic = ...; readonly t UnitsLoadFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDSecurityStartTimestamp = ...; readonly t InitRDSecurityStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDSecurityStartTimestampMonotonic = ...; readonly t InitRDSecurityStartTimestampMonotonic = ...;
@ -767,8 +759,6 @@ node /org/freedesktop/systemd1 {
<variablelist class="dbus-method" generated="True" extra-ref="StartUnit()"/> <variablelist class="dbus-method" generated="True" extra-ref="StartUnit()"/>
<variablelist class="dbus-method" generated="True" extra-ref="StartUnitWithFlags()"/>
<variablelist class="dbus-method" generated="True" extra-ref="StartUnitReplace()"/> <variablelist class="dbus-method" generated="True" extra-ref="StartUnitReplace()"/>
<variablelist class="dbus-method" generated="True" extra-ref="StopUnit()"/> <variablelist class="dbus-method" generated="True" extra-ref="StopUnit()"/>
@ -987,10 +977,6 @@ node /org/freedesktop/systemd1 {
<variablelist class="dbus-property" generated="True" extra-ref="UnitsLoadFinishTimestampMonotonic"/> <variablelist class="dbus-property" generated="True" extra-ref="UnitsLoadFinishTimestampMonotonic"/>
<variablelist class="dbus-property" generated="True" extra-ref="UnitsLoadTimestamp"/>
<variablelist class="dbus-property" generated="True" extra-ref="UnitsLoadTimestampMonotonic"/>
<variablelist class="dbus-property" generated="True" extra-ref="InitRDSecurityStartTimestamp"/> <variablelist class="dbus-property" generated="True" extra-ref="InitRDSecurityStartTimestamp"/>
<variablelist class="dbus-property" generated="True" extra-ref="InitRDSecurityStartTimestampMonotonic"/> <variablelist class="dbus-property" generated="True" extra-ref="InitRDSecurityStartTimestampMonotonic"/>
@ -1188,13 +1174,6 @@ node /org/freedesktop/systemd1 {
<para><function>StartUnitReplace()</function> is similar to <function>StartUnit()</function> but <para><function>StartUnitReplace()</function> is similar to <function>StartUnit()</function> but
replaces a job that is queued for one unit by a job for another unit.</para> replaces a job that is queued for one unit by a job for another unit.</para>
<para><function>StartUnitWithFlags()</function> is similar to <function>StartUnit()</function> but
allows the caller to pass an extra <varname>flags</varname> parameter, which does not support any
flags for now, and is reserved for future extensions. The new method also changes the behaviour
of the <varname>JobRemoved</varname> signal and make it return <literal>skipped</literal> in case
the unit activation job is skipped because a <varname>Condition*=</varname> is not satisfied.
With the <varname>StartUnit</varname> method, <literal>done</literal> would be returned instead.</para>
<para><function>StopUnit()</function> is similar to <function>StartUnit()</function> but stops the <para><function>StopUnit()</function> is similar to <function>StartUnit()</function> but stops the
specified unit rather than starting it. Note that the <literal>isolate</literal> mode is invalid for this specified unit rather than starting it. Note that the <literal>isolate</literal> mode is invalid for this
method.</para> method.</para>
@ -1513,11 +1492,6 @@ node /org/freedesktop/systemd1 {
boot loader or initrd implementation. In these cases the respective pairs of timestamps are both 0, boot loader or initrd implementation. In these cases the respective pairs of timestamps are both 0,
indicating that no data is available.</para> indicating that no data is available.</para>
<para><varname>UnitsLoadTimestamp</varname> and <varname>UnitsLoadTimestampMonotonic</varname> encode
<constant>CLOCK_REALTIME</constant> and <constant>CLOCK_MONOTONIC</constant> microseconds timestamps
(as described above). The timestamps are taken every time when the manager starts loading unit files.
</para>
<para>Similarly, the <varname>SecurityStartTimestamp</varname>, <para>Similarly, the <varname>SecurityStartTimestamp</varname>,
<varname>GeneratorsStartTimestamp</varname> and <varname>LoadUnitTimestamp</varname> (as well as their <varname>GeneratorsStartTimestamp</varname> and <varname>LoadUnitTimestamp</varname> (as well as their
monotonic and stop counterparts) expose performance data for uploading the security policies to the monotonic and stop counterparts) expose performance data for uploading the security policies to the

View File

@ -854,19 +854,18 @@ Table=1234</programlisting></para>
<listitem><para>Whether to enable or disable Router Advertisement sending on a link. Takes a <listitem><para>Whether to enable or disable Router Advertisement sending on a link. Takes a
boolean value. When enabled, prefixes configured in [IPv6Prefix] sections and routes boolean value. When enabled, prefixes configured in [IPv6Prefix] sections and routes
configured in [IPv6RoutePrefix] sections are distributed as defined in the [IPv6SendRA] configured in [IPv6RoutePrefix] sections are distributed as defined in the [IPv6SendRA]
section. If <varname>DHCPPrefixDelegation=</varname> is enabled, then the delegated prefixes section. If <varname>DHCPv6PrefixDelegation=</varname> is enabled, then the delegated
are also distributed. See <varname>DCHPPrefixDelegation=</varname> setting and the prefixes are also distributed. See <varname>DHCPv6PrefixDelegation=</varname> setting and the
[IPv6SendRA], [IPv6Prefix], [IPv6RoutePrefix], and [DHCPPrefixDelegation] sections for more [IPv6SendRA], [IPv6Prefix], [IPv6RoutePrefix], and [DHCPv6PrefixDelegation] sections for more
configuration options.</para></listitem> configuration options.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>DHCPPrefixDelegation=</varname></term> <term><varname>DHCPv6PrefixDelegation=</varname></term>
<listitem><para>Takes a boolean value. When enabled, requests subnet prefixes acquired by a <listitem><para>Takes a boolean value. When enabled, requests prefixes using a DHCPv6 client
DHCPv6 client, or by a DHCPv4 client through the 6RD option configured on another link. By configured on another link. By default, an address within each delegated prefix will be
default, an address within each delegated prefix will be assigned, and the prefixes will be assigned, and the prefixes will be announced through IPv6 Router Advertisement when
announced through IPv6 Router Advertisement when <varname>IPv6SendRA=</varname> is enabled. <varname>IPv6SendRA=</varname> is enabled. Such default settings can be configured in
Such default settings can be configured in [DHCPPrefixDelegation] section. Defaults to [DHCPv6PrefixDelegation] section. Defaults to disabled.</para></listitem>
disabled.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>IPv6MTUBytes=</varname></term> <term><varname>IPv6MTUBytes=</varname></term>
@ -1901,15 +1900,6 @@ Table=1234</programlisting></para>
the local system. Defaults to false.</para></listitem> the local system. Defaults to false.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>Use6RD=</varname></term>
<listitem><para>When true, subnets of the received IPv6 prefix are assigned to downstream
interfaces which enables <varname>DHCPPrefixDelegation=</varname>. See also
<varname>DHCPPrefixDelegation=</varname> in the [Network] section, the [DHCPPrefixDelegation]
section, and <ulink url="https://tools.ietf.org/html/rfc5969">RFC 5969</ulink>. Defaults to
false.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>FallbackLeaseLifetimeSec=</varname></term> <term><varname>FallbackLeaseLifetimeSec=</varname></term>
<listitem> <listitem>
@ -2086,15 +2076,16 @@ Table=1234</programlisting></para>
<listitem> <listitem>
<para>When true (the default), the client will request the DHCPv6 server to delegate <para>When true (the default), the client will request the DHCPv6 server to delegate
prefixes. If the server provides prefixes to be delegated, then subnets of the prefixes are prefixes. If the server provides prefixes to be delegated, then subnets of the prefixes are
assigned to the interfaces which enables <varname>DHCPPrefixDelegation=</varname>. assigned to the interfaces which enables <varname>DHCPv6PrefixDelegation=</varname>.
See also <varname>DHCPPrefixDelegation=</varname> in [Network] section, See also <varname>DHCPv6PrefixDelegation=</varname> in [Network] section,
[DHCPPrefixDelegation] section, and [DHCPv6PrefixDelegation] section, and
<ulink url="https://www.rfc-editor.org/rfc/rfc8415.html#section-6.3">RFC 8415</ulink>. <ulink url="https://www.rfc-editor.org/rfc/rfc8415.html#section-6.3">RFC 8415</ulink>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>RouteMetric=</varname></term>
<term><varname>UseDNS=</varname></term> <term><varname>UseDNS=</varname></term>
<term><varname>UseNTP=</varname></term> <term><varname>UseNTP=</varname></term>
<term><varname>UseHostname=</varname></term> <term><varname>UseHostname=</varname></term>
@ -2112,9 +2103,9 @@ Table=1234</programlisting></para>
<para>Allows DHCPv6 client to start without router advertisements's managed or other <para>Allows DHCPv6 client to start without router advertisements's managed or other
address configuration flag. Takes one of <literal>no</literal>, <literal>solicit</literal> address configuration flag. Takes one of <literal>no</literal>, <literal>solicit</literal>
or <literal>information-request</literal>. If this is not specified, or <literal>information-request</literal>. If this is not specified,
<literal>solicit</literal> is used when <varname>DHCPPrefixDelegation=</varname> is <literal>solicit</literal> is used when <varname>DHCPv6PrefixDelegation=</varname> is
enabled and <varname>UplinkInterface=:self</varname> is specified in the enabled and <varname>UplinkInterface=:self</varname> is specified in the
[DHCPPrefixDelegation] section. Otherwise, defaults to <literal>no</literal>, and the [DHCPv6PrefixDelegation] section. Otherwise, defaults to <literal>no</literal>, and the
DHCPv6 client will be started when an RA is received. See also DHCPv6 client will be started when an RA is received. See also
<varname>DHCPv6Client=</varname> setting in the [IPv6AcceptRA] section.</para> <varname>DHCPv6Client=</varname> setting in the [IPv6AcceptRA] section.</para>
</listitem> </listitem>
@ -2123,11 +2114,10 @@ Table=1234</programlisting></para>
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>[DHCPPrefixDelegation] Section Options</title> <title>[DHCPv6PrefixDelegation] Section Options</title>
<para>The [DHCPPrefixDelegation] section configures subnet prefixes of the delegated prefixes <para>The [DHCPv6PrefixDelegation] section configures delegated prefixes assigned by DHCPv6 server.
acquired by a DHCPv6 client, or by a DHCPv4 client through the 6RD option on another interface. The settings in this section are used only when <varname>DHCPv6PrefixDelegation=</varname> setting
The settings in this section are used only when the <varname>DHCPPrefixDelegation=</varname> is enabled.</para>
setting in the [Network] section is enabled.</para>
<variablelist class='network-directives'> <variablelist class='network-directives'>
<varlistentry> <varlistentry>
@ -2138,7 +2128,7 @@ Table=1234</programlisting></para>
interface itself is considered the uplink interface, and interface itself is considered the uplink interface, and
<varname>WithoutRA=solicit</varname> is implied if the setting is not explicitly specified. <varname>WithoutRA=solicit</varname> is implied if the setting is not explicitly specified.
When <literal>:auto</literal>, the first link which acquired prefixes to be delegated from When <literal>:auto</literal>, the first link which acquired prefixes to be delegated from
the DHCPv6 or DHCPv4 server is selected. Defaults to <literal>:auto</literal>.</para> the DHCPv6 server is selected. Defaults to <literal>:auto</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2158,8 +2148,7 @@ Table=1234</programlisting></para>
<listitem> <listitem>
<para>Takes a boolean. When enabled, and <varname>IPv6SendRA=</varname> in [Network] section <para>Takes a boolean. When enabled, and <varname>IPv6SendRA=</varname> in [Network] section
is enabled, the delegated prefixes are distributed through the IPv6 Router Advertisement. is enabled, the delegated prefixes are distributed through the IPv6 Router Advertisement.
This setting will be ignored when the <varname>DHCPPrefixDelegation=</varname> setting is Defaults to yes.</para>
enabled on the upstream interface. Defaults to yes.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2448,7 +2437,7 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
to <literal>always</literal>, the DHCPv6 client will be started in managed mode when an RA to <literal>always</literal>, the DHCPv6 client will be started in managed mode when an RA
is received, even if neither managed nor other information flag is set in the RA. This will is received, even if neither managed nor other information flag is set in the RA. This will
be ignored when <varname>WithoutRA=</varname> in the [DHCPv6] section is enabled, or be ignored when <varname>WithoutRA=</varname> in the [DHCPv6] section is enabled, or
<varname>UplinkInterface=:self</varname> in the [DHCPPrefixDelegation] section is <varname>UplinkInterface=:self</varname> in the [DHCPv6PrefixDelegation] section is
specified. Defaults to true.</para> specified. Defaults to true.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2722,8 +2711,8 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
values <literal>:none</literal> and <literal>:auto</literal>. When emitting DNS servers or values <literal>:none</literal> and <literal>:auto</literal>. When emitting DNS servers or
search domains is enabled but no servers are specified, the servers configured in the uplink search domains is enabled but no servers are specified, the servers configured in the uplink
interface will be emitted. When <literal>:auto</literal>, the value specified to the same interface will be emitted. When <literal>:auto</literal>, the value specified to the same
setting in the [DHCPPrefixDelegation] section will be used if setting in the [DHCPv6PrefixDelegation] section will be used if
<varname>DHCPPrefixDelegation=</varname> is enabled, otherwise the link which has a default <varname>DHCPv6PrefixDelegation=</varname> is enabled, otherwise the link which has a default
gateway with the highest priority will be automatically selected. When <literal>:none</literal>, gateway with the highest priority will be automatically selected. When <literal>:none</literal>,
no uplink interface will be selected. Defaults to <literal>:auto</literal>.</para></listitem> no uplink interface will be selected. Defaults to <literal>:auto</literal>.</para></listitem>
</varlistentry> </varlistentry>
@ -4387,7 +4376,7 @@ Name=enp2s0
[Network] [Network]
IPv6SendRA=yes IPv6SendRA=yes
DHCPPrefixDelegation=yes</programlisting> DHCPv6PrefixDelegation=yes</programlisting>
<para>This will enable DHCPv6-PD on the interface enp1s0 as an upstream interface where the <para>This will enable DHCPv6-PD on the interface enp1s0 as an upstream interface where the
DHCPv6 client is running and enp2s0 as a downstream interface where the prefix is delegated to. DHCPv6 client is running and enp2s0 as a downstream interface where the prefix is delegated to.

View File

@ -1008,9 +1008,11 @@ else
# We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian. # We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
bpftool = find_program('bpftool', '/usr/sbin/bpftool', required : bpf_framework_required) bpftool = find_program('bpftool', '/usr/sbin/bpftool', required : bpf_framework_required)
bpf_arches = ['x86_64']
deps_found = libbpf.found() and clang.found() and llvm_strip.found() and bpftool.found() deps_found = libbpf.found() and clang.found() and llvm_strip.found() and bpftool.found()
# Can build BPF program from source code in restricted C # Can build BPF program from source code in restricted C
conf.set10('BPF_FRAMEWORK', deps_found) conf.set10('BPF_FRAMEWORK',
bpf_arches.contains(host_machine.cpu_family()) and deps_found)
endif endif
libmount = dependency('mount', libmount = dependency('mount',
@ -1683,6 +1685,7 @@ subdir('src/boot/efi')
############################################################ ############################################################
build_bpf_skel_py = find_program('tools/build-bpf-skel.py')
generate_gperfs = find_program('tools/generate-gperfs.py') generate_gperfs = find_program('tools/generate-gperfs.py')
make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py') make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py')
make_directive_index_py = find_program('tools/make-directive-index.py') make_directive_index_py = find_program('tools/make-directive-index.py')

View File

@ -413,9 +413,7 @@ option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'gnu-efi support for sd-boot') description : 'gnu-efi support for sd-boot')
option('efi-cc', type : 'array', option('efi-cc', type : 'array',
description : 'the compiler to use for EFI modules') description : 'the compiler to use for EFI modules')
# Note that LLD does not support PE/COFF relocations option('efi-ld', type : 'string', value : 'ld',
# https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html
option('efi-ld', type : 'combo', choices : ['bfd', 'gold'],
description : 'the linker to use for EFI modules') description : 'the linker to use for EFI modules')
option('efi-libdir', type : 'string', option('efi-libdir', type : 'string',
description : 'path to the EFI lib directory') description : 'path to the EFI lib directory')

View File

@ -1,18 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This network file matches 6rd-* SIT devices which is automatically created by
# systemd-networkd when DHCPv4 6RD option is received.
[Match]
Name=6rd-*
Type=sit
[Network]
DHCPPrefixDelegation=yes

View File

@ -1,8 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_NETWORKD') == 1 if conf.get('ENABLE_NETWORKD') == 1
install_data('80-6rd-tunnel.network', install_data('80-container-host0.network',
'80-container-host0.network',
'80-container-ve.network', '80-container-ve.network',
'80-container-vz.network', '80-container-vz.network',
'80-vm-vt.network', '80-vm-vt.network',

View File

@ -52,12 +52,12 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
/* If WaitForKeyEx fails here, the firmware pretends it talks this /* If WaitForKeyEx fails here, the firmware pretends it talks this
* protocol, but it really doesn't. */ * protocol, but it really doesn't. */
TextInputEx = NULL; TextInputEx = NULL;
else
events[n_events++] = TextInputEx->WaitForKeyEx;
checked = TRUE; checked = TRUE;
} }
if (TextInputEx)
events[n_events++] = TextInputEx->WaitForKeyEx;
err = BS->CreateEvent(EVT_TIMER, 0, NULL, NULL, &timer); err = BS->CreateEvent(EVT_TIMER, 0, NULL, NULL, &timer);
if (EFI_ERROR(err)) if (EFI_ERROR(err))
return log_error_status_stall(err, L"Error creating timer event: %r", err); return log_error_status_stall(err, L"Error creating timer event: %r", err);

View File

@ -48,6 +48,14 @@ if efi_cc.length() == 0
efi_cc = cc.cmd_array() efi_cc = cc.cmd_array()
endif endif
efi_ld = find_program(get_option('efi-ld'))
efi_ld_name = efi_ld.path().split('/')[-1]
if efi_ld_name == 'lld' or efi_ld_name == 'ld.lld'
# LLVM/LLD does not support PE/COFF relocations
# https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html
error('LLVM/lld does not support PE/COFF relocations. Use different linker for EFI image.')
endif
efi_libdir = '' efi_libdir = ''
foreach dir : [get_option('efi-libdir'), foreach dir : [get_option('efi-libdir'),
'/usr/lib/gnuefi' / efi_arch[0], '/usr/lib/gnuefi' / efi_arch[0],
@ -244,67 +252,34 @@ if get_option('b_ndebug') == 'true' or (
get_option('b_ndebug') == 'if-release' and get_option('buildtype') in ['plain', 'release']) get_option('b_ndebug') == 'if-release' and get_option('buildtype') in ['plain', 'release'])
efi_cflags += ['-DNDEBUG'] efi_cflags += ['-DNDEBUG']
endif endif
if get_option('b_lto')
efi_cflags += ['-flto']
endif
foreach arg : get_option('c_args') foreach arg : get_option('c_args')
if arg in ['-Werror', '-g', '-ggdb', '-O1', '-O2', '-O3', '-Og', '-Os', '-DNDEBUG', '-flto', '-fno-lto'] if arg in ['-Werror', '-g', '-ggdb', '-O1', '-O2', '-O3', '-Og', '-Os', '-DNDEBUG']
message('Using "@0@" from c_args for EFI compiler'.format(arg)) message('Using "@0@" from c_args for EFI compiler'.format(arg))
efi_cflags += arg efi_cflags += arg
endif endif
endforeach endforeach
efi_ldflags = [ efi_ldflags = ['-T', efi_lds,
'-fuse-ld=' + get_option('efi-ld'), '-shared',
'-L', efi_libdir, '-Bsymbolic',
'-nostdlib', '-nostdlib',
'-T', efi_lds, '--no-undefined',
'-Wl,--build-id=sha1', '--warn-common',
'-Wl,--fatal-warnings', '--fatal-warnings',
'-Wl,--no-undefined', '-znocombreloc',
'-Wl,--warn-common', '--build-id=sha1',
'-Wl,-Bsymbolic', '-L', efi_libdir,
'-z', 'nocombreloc', efi_crt0]
efi_crt0,
]
if efi_arch[1] in ['aarch64', 'arm', 'riscv64'] if efi_arch[1] in ['aarch64', 'arm', 'riscv64']
efi_ldflags += ['-shared', '-fwhole-program']
# Aarch64, ARM32 and 64bit RISC-V don't have an EFI capable objcopy. # Aarch64, ARM32 and 64bit RISC-V don't have an EFI capable objcopy.
# Use 'binary' instead, and add required symbols manually. # Use 'binary' instead, and add required symbols manually.
efi_ldflags += ['-Wl,--defsym=EFI_SUBSYSTEM=0xa'] efi_ldflags += ['--defsym=EFI_SUBSYSTEM=0xa']
efi_format = ['-O', 'binary'] efi_format = ['-O', 'binary']
else else
efi_ldflags += ['-pie']
if get_option('efi-ld') == 'bfd'
efi_ldflags += '-Wl,--no-dynamic-linker'
endif
efi_format = ['--target=efi-app-@0@'.format(efi_arch[1])] efi_format = ['--target=efi-app-@0@'.format(efi_arch[1])]
endif endif
if run_command('grep', '-q', '__CTOR_LIST__', efi_lds).returncode() == 0
# fedora has a patched gnu-efi that adds support for ELF constructors.
# If ld is called by gcc something about these symbols breaks, resulting
# in sd-boot freezing when gnu-efi runs the constructors. Force defining
# them seems to work around this.
efi_ldflags += [
'-Wl,--defsym=_init_array=0',
'-Wl,--defsym=_init_array_end=0',
'-Wl,--defsym=_fini_array=0',
'-Wl,--defsym=_fini_array_end=0',
'-Wl,--defsym=__CTOR_LIST__=0',
'-Wl,--defsym=__CTOR_END__=0',
'-Wl,--defsym=__DTOR_LIST__=0',
'-Wl,--defsym=__DTOR_END__=0',
]
endif
efi_cc_version = run_command(efi_cc, '--version').stdout().split('\n')[0]
if efi_cc_version.contains('clang') and efi_cc_version.split('.')[0].split(' ')[-1].to_int() <= 10
# clang <= 10 doesn't pass -T to the linker and then even complains about it being unused
efi_ldflags += ['-Wl,-T,' + efi_lds, '-Wno-unused-command-line-argument']
endif
systemd_boot_objects = [] systemd_boot_objects = []
stub_objects = [] stub_objects = []
foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources
@ -321,6 +296,7 @@ foreach file : fundamental_source_paths + common_sources + systemd_boot_sources
endif endif
endforeach endforeach
libgcc_file_name = run_command(efi_cc + ['-print-libgcc-file-name']).stdout().strip()
systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(efi_arch[0]) systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(efi_arch[0])
stub_elf_name = 'linux@0@.elf.stub'.format(efi_arch[0]) stub_elf_name = 'linux@0@.elf.stub'.format(efi_arch[0])
stub_efi_name = 'linux@0@.efi.stub'.format(efi_arch[0]) stub_efi_name = 'linux@0@.efi.stub'.format(efi_arch[0])
@ -332,7 +308,7 @@ foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects
tuple[0], tuple[0],
input : tuple[2], input : tuple[2],
output : tuple[0], output : tuple[0],
command : [efi_cc, '-o', '@OUTPUT@', efi_ldflags, efi_cflags, tuple[2], '-lefi', '-lgnuefi', '-lgcc'], command : [efi_ld, '-o', '@OUTPUT@', efi_ldflags, tuple[2], '-lefi', '-lgnuefi', libgcc_file_name],
install : tuple[3], install : tuple[3],
install_dir : bootlibdir) install_dir : bootlibdir)
@ -341,7 +317,6 @@ foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects
input : so, input : so,
output : tuple[1], output : tuple[1],
command : [objcopy, command : [objcopy,
'-j', '.bss*',
'-j', '.data', '-j', '.data',
'-j', '.dynamic', '-j', '.dynamic',
'-j', '.dynsym', '-j', '.dynsym',

View File

@ -11,7 +11,7 @@
/* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */ /* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
#include "bpf-dlopen.h" #include "bpf-dlopen.h"
#include "bpf-link.h" #include "bpf-link.h"
#include "bpf/socket_bind/socket-bind-skel.h" #include "bpf/socket_bind/socket-bind.skel.h"
#include "bpf/socket_bind/socket-bind-api.bpf.h" #include "bpf/socket_bind/socket-bind-api.bpf.h"
static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) { static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) {

View File

@ -1,61 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1+
if conf.get('BPF_FRAMEWORK') == 1
clang_flags = [
'-Wno-compare-distinct-pointer-types',
'-O2',
'-target',
'bpf',
'-g',
'-c',
]
clang_arch_flag = '-D__@0@__'.format(host_machine.cpu_family())
if meson.version().version_compare('>= 0.58')
libbpf_include_dir = libbpf.get_variable('includedir')
else
libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
endif
bpf_o_unstripped_cmd = [
clang,
clang_flags,
clang_arch_flag,
'-I.'
]
if not meson.is_cross_build()
target_triplet_cmd = run_command('gcc', '-dumpmachine', check: false)
if target_triplet_cmd.returncode() == 0
target_triplet = target_triplet_cmd.stdout().strip()
bpf_o_unstripped_cmd += [
'-isystem',
'/usr/include/@0@'.format(target_triplet)
]
endif
endif
bpf_o_unstripped_cmd += [
'-idirafter',
libbpf_include_dir,
'@INPUT@',
'-o',
'@OUTPUT@'
]
bpf_o_cmd = [
llvm_strip,
'-g',
'@INPUT@',
'-o',
'@OUTPUT@'
]
skel_h_cmd = [
bpftool,
'g',
's',
'@INPUT@'
]
endif

View File

@ -1,22 +1,14 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('BPF_FRAMEWORK') == 1 if conf.get('BPF_FRAMEWORK') == 1
restrict_fs_bpf_o_unstripped = custom_target(
'restrict-fs.bpf.unstripped.o',
input : 'restrict-fs.bpf.c',
output : 'restrict-fs.bpf.unstripped.o',
command : bpf_o_unstripped_cmd)
restrict_fs_bpf_o = custom_target(
'restrict-fs.bpf.o',
input : restrict_fs_bpf_o_unstripped,
output : 'restrict-fs.bpf.o',
command : bpf_o_cmd)
restrict_fs_skel_h = custom_target( restrict_fs_skel_h = custom_target(
'restrict-fs.skel.h', 'restrict-fs-skel.h',
input : restrict_fs_bpf_o, input : 'restrict-fs.bpf.c',
output : 'restrict-fs.skel.h', output : 'restrict-fs-skel.h',
command : skel_h_cmd, command : [build_bpf_skel_py,
capture : true) '--clang_exec', clang.path(),
'--llvm_strip_exec', llvm_strip.path(),
'--bpftool_exec', bpftool.path(),
'--arch', host_machine.cpu_family(),
'@INPUT@', '@OUTPUT@'])
endif endif

View File

@ -1,14 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/* The SPDX header above is actually correct in claiming this was
* LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
* compatible with GPL we will claim this to be GPL however, which should be
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
*/
/* libbpf is used via dlopen(), so rename symbols */
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
#include "bpf/restrict_fs/restrict-fs.skel.h"

View File

@ -1,22 +1,14 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('BPF_FRAMEWORK') == 1 if conf.get('BPF_FRAMEWORK') == 1
restrict_ifaces_bpf_o_unstripped = custom_target(
'restrict-ifaces.bpf.unstripped.o',
input : 'restrict-ifaces.bpf.c',
output : 'restrict-ifaces.bpf.unstripped.o',
command : bpf_o_unstripped_cmd)
restrict_ifaces_bpf_o = custom_target(
'restrict-ifaces.bpf.o',
input : restrict_ifaces_bpf_o_unstripped,
output : 'restrict-ifaces.bpf.o',
command : bpf_o_cmd)
restrict_ifaces_skel_h = custom_target( restrict_ifaces_skel_h = custom_target(
'restrict-ifaces.skel.h', 'restrict-ifaces.skel.h',
input : restrict_ifaces_bpf_o, input : 'restrict-ifaces.bpf.c',
output : 'restrict-ifaces.skel.h', output : 'restrict-ifaces.skel.h',
command : skel_h_cmd, command : [build_bpf_skel_py,
capture : true) '--clang_exec', clang.path(),
'--llvm_strip_exec', llvm_strip.path(),
'--bpftool_exec', bpftool.path(),
'--arch', host_machine.cpu_family(),
'@INPUT@', '@OUTPUT@'])
endif endif

View File

@ -1,14 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/* The SPDX header above is actually correct in claiming this was
* LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
* compatible with GPL we will claim this to be GPL however, which should be
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
*/
/* libbpf is used via dlopen(), so rename symbols */
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
#include "bpf/restrict_ifaces/restrict-ifaces.skel.h"

View File

@ -1,22 +1,14 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('BPF_FRAMEWORK') == 1 if conf.get('BPF_FRAMEWORK') == 1
socket_bind_bpf_o_unstripped = custom_target(
'socket-bind.bpf.unstripped.o',
input : 'socket-bind.bpf.c',
output : 'socket-bind.bpf.unstripped.o',
command : bpf_o_unstripped_cmd)
socket_bind_bpf_o = custom_target(
'socket-bind.bpf.o',
input : socket_bind_bpf_o_unstripped,
output : 'socket-bind.bpf.o',
command : bpf_o_cmd)
socket_bind_skel_h = custom_target( socket_bind_skel_h = custom_target(
'socket-bind.skel.h', 'socket-bind.skel.h',
input : socket_bind_bpf_o, input : 'socket-bind.bpf.c',
output : 'socket-bind.skel.h', output : 'socket-bind.skel.h',
command : skel_h_cmd, command : [build_bpf_skel_py,
capture : true) '--clang_exec', clang.path(),
'--llvm_strip_exec', llvm_strip.path(),
'--bpftool_exec', bpftool.path(),
'--arch', host_machine.cpu_family(),
'@INPUT@', '@OUTPUT@'])
endif endif

View File

@ -1,14 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/* The SPDX header above is actually correct in claiming this was
* LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
* compatible with GPL we will claim this to be GPL however, which should be
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
*/
/* libbpf is used via dlopen(), so rename symbols */
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
#include "bpf/socket_bind/socket-bind.skel.h"

View File

@ -2673,7 +2673,6 @@ const sd_bus_vtable bus_manager_vtable[] = {
BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST), BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD]), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST), BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST), BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
@ -2798,15 +2797,6 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_PARAM(job), SD_BUS_PARAM(job),
method_start_unit, method_start_unit,
SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("StartUnitWithFlags",
"sst",
SD_BUS_PARAM(name)
SD_BUS_PARAM(mode)
SD_BUS_PARAM(flags),
"o",
SD_BUS_PARAM(job),
method_start_unit,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("StartUnitReplace", SD_BUS_METHOD_WITH_NAMES("StartUnitReplace",
"sss", "sss",
SD_BUS_PARAM(old_unit) SD_BUS_PARAM(old_unit)

View File

@ -377,7 +377,6 @@ int bus_unit_method_start_generic(
bool reload_if_possible, bool reload_if_possible,
sd_bus_error *error) { sd_bus_error *error) {
BusUnitQueueFlags job_flags = reload_if_possible ? BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE : 0;
const char *smode, *verb; const char *smode, *verb;
JobMode mode; JobMode mode;
int r; int r;
@ -406,23 +405,6 @@ int bus_unit_method_start_generic(
else else
verb = job_type_to_string(job_type); verb = job_type_to_string(job_type);
if (sd_bus_message_is_method_call(message, NULL, "StartUnitWithFlags")) {
uint64_t input_flags = 0;
r = sd_bus_message_read(message, "t", &input_flags);
if (r < 0)
return r;
/* Let clients know that this version doesn't support any flags at the moment. */
if (input_flags != 0)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS,
"Invalid 'flags' parameter '%" PRIu64 "'",
input_flags);
/* The new method unconditionally uses the new behaviour of returning 'skip' when
* a job is skipped. */
job_flags |= BUS_UNIT_QUEUE_RETURN_SKIP_ON_CONDITION_FAIL;
}
r = bus_verify_manage_units_async_full( r = bus_verify_manage_units_async_full(
u, u,
verb, verb,
@ -436,7 +418,8 @@ int bus_unit_method_start_generic(
if (r == 0) if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
return bus_unit_queue_job(message, u, job_type, mode, job_flags, error); return bus_unit_queue_job(message, u, job_type, mode,
reload_if_possible ? BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE : 0, error);
} }
static int bus_unit_method_start(sd_bus_message *message, void *userdata, sd_bus_error *error) { static int bus_unit_method_start(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@ -1798,9 +1781,6 @@ int bus_unit_queue_job_one(
if (r < 0) if (r < 0)
return r; return r;
if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RETURN_SKIP_ON_CONDITION_FAIL))
j->return_skip_on_cond_failure = true;
r = bus_job_track_sender(j, message); r = bus_job_track_sender(j, message);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -29,9 +29,8 @@ int bus_unit_method_freeze(sd_bus_message *message, void *userdata, sd_bus_error
int bus_unit_method_thaw(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_unit_method_thaw(sd_bus_message *message, void *userdata, sd_bus_error *error);
typedef enum BusUnitQueueFlags { typedef enum BusUnitQueueFlags {
BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE = 1 << 0, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE = 1 << 0,
BUS_UNIT_QUEUE_VERBOSE_REPLY = 1 << 1, BUS_UNIT_QUEUE_VERBOSE_REPLY = 1 << 1,
BUS_UNIT_QUEUE_RETURN_SKIP_ON_CONDITION_FAIL = 1 << 2,
} BusUnitQueueFlags; } BusUnitQueueFlags;
int bus_unit_queue_job_one( int bus_unit_queue_job_one(

View File

@ -889,8 +889,8 @@ int job_run_and_invalidate(Job *j) {
job_set_state(j, JOB_WAITING); /* Hmm, not ready after all, let's return to JOB_WAITING state */ job_set_state(j, JOB_WAITING); /* Hmm, not ready after all, let's return to JOB_WAITING state */
else if (r == -EALREADY) /* already being executed */ else if (r == -EALREADY) /* already being executed */
r = job_finish_and_invalidate(j, JOB_DONE, true, true); r = job_finish_and_invalidate(j, JOB_DONE, true, true);
else if (r == -ECOMM) /* condition failed, but all is good. Return 'skip' if caller requested it. */ else if (r == -ECOMM) /* condition failed, but all is good */
r = job_finish_and_invalidate(j, j->return_skip_on_cond_failure ? JOB_SKIPPED : JOB_DONE, true, false); r = job_finish_and_invalidate(j, JOB_DONE, true, false);
else if (r == -EBADR) else if (r == -EBADR)
r = job_finish_and_invalidate(j, JOB_SKIPPED, true, false); r = job_finish_and_invalidate(j, JOB_SKIPPED, true, false);
else if (r == -ENOEXEC) else if (r == -ENOEXEC)

View File

@ -160,7 +160,6 @@ struct Job {
bool irreversible:1; bool irreversible:1;
bool in_gc_queue:1; bool in_gc_queue:1;
bool ref_by_private_bus:1; bool ref_by_private_bus:1;
bool return_skip_on_cond_failure:1;
}; };
Job* job_new(Unit *unit, JobType type); Job* job_new(Unit *unit, JobType type);

View File

@ -1729,20 +1729,13 @@ static void manager_ready(Manager *m) {
/* Let's finally catch up with any changes that took place while we were reloading/reexecing */ /* Let's finally catch up with any changes that took place while we were reloading/reexecing */
manager_catchup(m); manager_catchup(m);
/* Create a file which will indicate when the manager started loading units the last time. */
(void) touch_file("/run/systemd/systemd-units-load", false,
m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME),
UID_INVALID, GID_INVALID, 0444);
m->honor_device_enumeration = true; m->honor_device_enumeration = true;
} }
Manager* manager_reloading_start(Manager *m) { Manager* manager_reloading_start(Manager *m) {
m->n_reloading++; m->n_reloading++;
dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD);
return m; return m;
} }
void manager_reloading_stopp(Manager **m) { void manager_reloading_stopp(Manager **m) {
if (*m) { if (*m) {
assert((*m)->n_reloading > 0); assert((*m)->n_reloading > 0);
@ -4466,7 +4459,6 @@ static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
[MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish", [MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish",
[MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start", [MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start",
[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish", [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish",
[MANAGER_TIMESTAMP_UNITS_LOAD] = "units-load",
[MANAGER_TIMESTAMP_INITRD_SECURITY_START] = "initrd-security-start", [MANAGER_TIMESTAMP_INITRD_SECURITY_START] = "initrd-security-start",
[MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH] = "initrd-security-finish", [MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH] = "initrd-security-finish",
[MANAGER_TIMESTAMP_INITRD_GENERATORS_START] = "initrd-generators-start", [MANAGER_TIMESTAMP_INITRD_GENERATORS_START] = "initrd-generators-start",

View File

@ -102,7 +102,6 @@ typedef enum ManagerTimestamp {
MANAGER_TIMESTAMP_GENERATORS_FINISH, MANAGER_TIMESTAMP_GENERATORS_FINISH,
MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_START,
MANAGER_TIMESTAMP_UNITS_LOAD_FINISH, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH,
MANAGER_TIMESTAMP_UNITS_LOAD,
MANAGER_TIMESTAMP_INITRD_SECURITY_START, MANAGER_TIMESTAMP_INITRD_SECURITY_START,
MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH, MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH,

View File

@ -133,8 +133,6 @@ libcore_sources = '''
unit.h unit.h
'''.split() '''.split()
subdir('bpf')
subdir('bpf/socket_bind') subdir('bpf/socket_bind')
if conf.get('BPF_FRAMEWORK') == 1 if conf.get('BPF_FRAMEWORK') == 1
libcore_sources += [socket_bind_skel_h] libcore_sources += [socket_bind_skel_h]

View File

@ -10,7 +10,7 @@
#include "bpf-dlopen.h" #include "bpf-dlopen.h"
#include "bpf-link.h" #include "bpf-link.h"
#include "bpf/restrict_ifaces/restrict-ifaces-skel.h" #include "bpf/restrict_ifaces/restrict-ifaces.skel.h"
static struct restrict_ifaces_bpf *restrict_ifaces_bpf_free(struct restrict_ifaces_bpf *obj) { static struct restrict_ifaces_bpf *restrict_ifaces_bpf_free(struct restrict_ifaces_bpf *obj) {
restrict_ifaces_bpf__destroy(obj); restrict_ifaces_bpf__destroy(obj);

View File

@ -70,12 +70,6 @@ struct sd_dhcp_lease {
char *timezone; char *timezone;
uint8_t sixrd_ipv4masklen;
uint8_t sixrd_prefixlen;
struct in6_addr sixrd_prefix;
struct in_addr *sixrd_br_addresses;
size_t sixrd_n_br_addresses;
LIST_HEAD(struct sd_dhcp_raw_option, private_options); LIST_HEAD(struct sd_dhcp_raw_option, private_options);
}; };

View File

@ -251,33 +251,6 @@ int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
return -ENODATA; return -ENODATA;
} }
int sd_dhcp_lease_get_6rd(
sd_dhcp_lease *lease,
uint8_t *ret_ipv4masklen,
uint8_t *ret_prefixlen,
struct in6_addr *ret_prefix,
const struct in_addr **ret_br_addresses,
size_t *ret_n_br_addresses) {
assert_return(lease, -EINVAL);
if (lease->sixrd_n_br_addresses <= 0)
return -ENODATA;
if (ret_ipv4masklen)
*ret_ipv4masklen = lease->sixrd_ipv4masklen;
if (ret_prefixlen)
*ret_prefixlen = lease->sixrd_prefixlen;
if (ret_prefix)
*ret_prefix = lease->sixrd_prefix;
if (ret_br_addresses)
*ret_br_addresses = lease->sixrd_br_addresses;
if (ret_n_br_addresses)
*ret_n_br_addresses = lease->sixrd_n_br_addresses;
return 0;
}
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) { int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
assert_return(lease, -EINVAL); assert_return(lease, -EINVAL);
assert_return(data, -EINVAL); assert_return(data, -EINVAL);
@ -316,7 +289,6 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->client_id); free(lease->client_id);
free(lease->vendor_specific); free(lease->vendor_specific);
strv_free(lease->search_domains); strv_free(lease->search_domains);
free(lease->sixrd_br_addresses);
return mfree(lease); return mfree(lease);
} }
@ -562,61 +534,6 @@ static int lease_parse_classless_routes(
return 0; return 0;
} }
static int lease_parse_6rd(sd_dhcp_lease *lease, const uint8_t *option, size_t len) {
uint8_t ipv4masklen, prefixlen;
struct in6_addr prefix;
_cleanup_free_ struct in_addr *br_addresses = NULL;
size_t n_br_addresses;
assert(lease);
assert(option);
/* See RFC 5969 Section 7.1.1 */
if (lease->sixrd_n_br_addresses > 0)
/* Multiple 6rd option?? */
return -EINVAL;
/* option-length: The length of the DHCP option in octets (22 octets with one BR IPv4 address). */
if (len < 2 + sizeof(struct in6_addr) + sizeof(struct in_addr) ||
(len - 2 - sizeof(struct in6_addr)) % sizeof(struct in_addr) != 0)
return -EINVAL;
/* IPv4MaskLen: The number of high-order bits that are identical across all CE IPv4 addresses
* within a given 6rd domain. This may be any value between 0 and 32. Any value
* greater than 32 is invalid. */
ipv4masklen = option[0];
if (ipv4masklen > 32)
return -EINVAL;
/* 6rdPrefixLen: The IPv6 prefix length of the SP's 6rd IPv6 prefix in number of bits. For the
* purpose of bounds checking by DHCP option processing, the sum of
* (32 - IPv4MaskLen) + 6rdPrefixLen MUST be less than or equal to 128. */
prefixlen = option[1];
if (32 - ipv4masklen + prefixlen > 128)
return -EINVAL;
/* 6rdPrefix: The service provider's 6rd IPv6 prefix represented as a 16-octet IPv6 address.
* The bits in the prefix after the 6rdPrefixlen number of bits are reserved and
* MUST be initialized to zero by the sender and ignored by the receiver. */
memcpy(&prefix, option + 2, sizeof(struct in6_addr));
(void) in6_addr_mask(&prefix, prefixlen);
/* 6rdBRIPv4Address: One or more IPv4 addresses of the 6rd Border Relay(s) for a given 6rd domain. */
n_br_addresses = (len - 2 - sizeof(struct in6_addr)) / sizeof(struct in_addr);
br_addresses = newdup(struct in_addr, option + 2 + sizeof(struct in6_addr), n_br_addresses);
if (!br_addresses)
return -ENOMEM;
lease->sixrd_ipv4masklen = ipv4masklen;
lease->sixrd_prefixlen = prefixlen;
lease->sixrd_prefix = prefix;
lease->sixrd_br_addresses = TAKE_PTR(br_addresses);
lease->sixrd_n_br_addresses = n_br_addresses;
return 0;
}
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata) { int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata) {
sd_dhcp_lease *lease = userdata; sd_dhcp_lease *lease = userdata;
int r; int r;
@ -802,12 +719,6 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
lease->vendor_specific_len = len; lease->vendor_specific_len = len;
break; break;
case SD_DHCP_OPTION_6RD:
r = lease_parse_6rd(lease, option, len);
if (r < 0)
log_debug_errno(r, "Failed to parse 6rd option, ignoring: %m");
break;
case SD_DHCP_OPTION_PRIVATE_BASE ... SD_DHCP_OPTION_PRIVATE_LAST: case SD_DHCP_OPTION_PRIVATE_BASE ... SD_DHCP_OPTION_PRIVATE_LAST:
r = dhcp_lease_insert_private_option(lease, code, option, len); r = dhcp_lease_insert_private_option(lease, code, option, len);
if (r < 0) if (r < 0)

View File

@ -612,20 +612,26 @@ int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t callb
} }
static bool netdev_is_ready_to_create(NetDev *netdev, Link *link) { static bool netdev_is_ready_to_create(NetDev *netdev, Link *link) {
Request req;
assert(netdev); assert(netdev);
assert(link); assert(link);
if (netdev->state != NETDEV_STATE_LOADING) if (netdev->state != NETDEV_STATE_LOADING)
return false; return false;
if (!IN_SET(link->state, LINK_STATE_INITIALIZED, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return false; return false;
if (netdev_get_create_type(netdev) == NETDEV_CREATE_AFTER_CONFIGURED && if (netdev_get_create_type(netdev) == NETDEV_CREATE_AFTER_CONFIGURED &&
link->state != LINK_STATE_CONFIGURED) link->state != LINK_STATE_CONFIGURED)
return false; return false;
if (link->set_link_messages > 0) req = (Request) {
.link = link,
.type = REQUEST_TYPE_SET_LINK,
.set_link_operation_ptr = INT_TO_PTR(SET_LINK_MTU),
};
if (ordered_set_contains(link->manager->request_queue, &req))
return false; return false;
return true; return true;

View File

@ -8,12 +8,9 @@
#include <linux/ip6_tunnel.h> #include <linux/ip6_tunnel.h>
#include "conf-parser.h" #include "conf-parser.h"
#include "hexdecoct.h"
#include "missing_network.h" #include "missing_network.h"
#include "netlink-util.h" #include "netlink-util.h"
#include "networkd-manager.h"
#include "parse-util.h" #include "parse-util.h"
#include "siphash24.h"
#include "string-table.h" #include "string-table.h"
#include "string-util.h" #include "string-util.h"
#include "tunnel.h" #include "tunnel.h"
@ -32,146 +29,6 @@ static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(ip6tnl_mode, Ip6TnlMode); DEFINE_STRING_TABLE_LOOKUP(ip6tnl_mode, Ip6TnlMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode, ip6tnl_mode, Ip6TnlMode, "Failed to parse ip6 tunnel Mode"); DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode, ip6tnl_mode, Ip6TnlMode, "Failed to parse ip6 tunnel Mode");
#define HASH_KEY SD_ID128_MAKE(74,c4,de,12,f3,d9,41,34,bb,3d,c1,a4,42,93,50,87)
int dhcp4_pd_create_6rd_tunnel_name(Link *link, char **ret) {
_cleanup_free_ char *ifname_alloc = NULL;
uint8_t ipv4masklen, sixrd_prefixlen, *buf, *p;
struct in_addr ipv4address;
struct in6_addr sixrd_prefix;
char ifname[IFNAMSIZ];
uint64_t result;
size_t sz;
int r;
assert(link);
assert(link->dhcp_lease);
r = sd_dhcp_lease_get_address(link->dhcp_lease, &ipv4address);
if (r < 0)
return log_link_debug_errno(link, r, "Failed to get DHCPv4 address: %m");
r = sd_dhcp_lease_get_6rd(link->dhcp_lease, &ipv4masklen, &sixrd_prefixlen, &sixrd_prefix, NULL, NULL);
if (r < 0)
return log_link_debug_errno(link, r, "Failed to get 6rd option: %m");
sz = sizeof(uint8_t) * 2 + sizeof(struct in6_addr) + sizeof(struct in_addr);
buf = newa(uint8_t, sz);
p = buf;
p = mempcpy(p, &ipv4masklen, sizeof(uint8_t));
p = mempcpy(p, &ipv4address, sizeof(struct in_addr));
p = mempcpy(p, &sixrd_prefixlen, sizeof(uint8_t));
p = mempcpy(p, &sixrd_prefix, sizeof(struct in6_addr));
result = siphash24(buf, sz, HASH_KEY.bytes);
memcpy(ifname, "6rd-", STRLEN("6rd-"));
ifname[STRLEN("6rd-") ] = urlsafe_base64char(result >> 54);
ifname[STRLEN("6rd-") + 1] = urlsafe_base64char(result >> 48);
ifname[STRLEN("6rd-") + 2] = urlsafe_base64char(result >> 42);
ifname[STRLEN("6rd-") + 3] = urlsafe_base64char(result >> 36);
ifname[STRLEN("6rd-") + 4] = urlsafe_base64char(result >> 30);
ifname[STRLEN("6rd-") + 5] = urlsafe_base64char(result >> 24);
ifname[STRLEN("6rd-") + 6] = urlsafe_base64char(result >> 18);
ifname[STRLEN("6rd-") + 7] = urlsafe_base64char(result >> 12);
ifname[STRLEN("6rd-") + 8] = urlsafe_base64char(result >> 6);
ifname[STRLEN("6rd-") + 9] = urlsafe_base64char(result);
ifname[STRLEN("6rd-") + 10] = '\0';
assert_cc(STRLEN("6rd-") + 10 <= IFNAMSIZ);
ifname_alloc = strdup(ifname);
if (!ifname_alloc)
return log_oom_debug();
*ret = TAKE_PTR(ifname_alloc);
return 0;
}
int dhcp4_pd_create_6rd_tunnel(Link *link, link_netlink_message_handler_t callback) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
uint8_t ipv4masklen, sixrd_prefixlen;
struct in_addr ipv4address, relay_prefix;
struct in6_addr sixrd_prefix;
int r;
assert(link);
assert(link->ifindex > 0);
assert(link->manager);
assert(link->dhcp_lease);
assert(link->dhcp4_6rd_tunnel_name);
assert(callback);
r = sd_dhcp_lease_get_address(link->dhcp_lease, &ipv4address);
if (r < 0)
return log_link_debug_errno(link, r, "Failed to get DHCPv4 address: %m");
r = sd_dhcp_lease_get_6rd(link->dhcp_lease, &ipv4masklen, &sixrd_prefixlen, &sixrd_prefix, NULL, NULL);
if (r < 0)
return log_link_debug_errno(link, r, "Failed to get 6rd option: %m");
r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0)
return log_link_debug_errno(link, r, "Could not allocate RTM_NEWLINK message: %m");
r = sd_netlink_message_append_string(m, IFLA_IFNAME, link->dhcp4_6rd_tunnel_name);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IFNAME, attribute: %m");
r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "sit");
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &ipv4address);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
r = sd_netlink_message_append_u8(m, IFLA_IPTUN_TTL, 64);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
r = sd_netlink_message_append_in6_addr(m, IFLA_IPTUN_6RD_PREFIX, &sixrd_prefix);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_6RD_PREFIX attribute: %m");
r = sd_netlink_message_append_u16(m, IFLA_IPTUN_6RD_PREFIXLEN, sixrd_prefixlen);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_6RD_PREFIXLEN attribute: %m");
relay_prefix = ipv4address;
(void) in4_addr_mask(&relay_prefix, ipv4masklen);
r = sd_netlink_message_append_u32(m, IFLA_IPTUN_6RD_RELAY_PREFIX, relay_prefix.s_addr);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_6RD_RELAY_PREFIX attribute: %m");
r = sd_netlink_message_append_u16(m, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, ipv4masklen);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_6RD_RELAY_PREFIXLEN attribute: %m");
r = sd_netlink_message_close_container(m);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
r = sd_netlink_message_close_container(m);
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_debug_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
return 0;
}
static int netdev_ipip_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_ipip_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Tunnel *t; Tunnel *t;
int r; int r;

View File

@ -6,7 +6,6 @@
#include "conf-parser.h" #include "conf-parser.h"
#include "fou-tunnel.h" #include "fou-tunnel.h"
#include "netdev.h" #include "netdev.h"
#include "networkd-link.h"
typedef enum Ip6TnlMode { typedef enum Ip6TnlMode {
NETDEV_IP6_TNL_MODE_IP6IP6, NETDEV_IP6_TNL_MODE_IP6IP6,
@ -61,9 +60,6 @@ typedef struct Tunnel {
uint8_t sixrd_prefixlen; uint8_t sixrd_prefixlen;
} Tunnel; } Tunnel;
int dhcp4_pd_create_6rd_tunnel_name(Link *link, char **ret);
int dhcp4_pd_create_6rd_tunnel(Link *link, link_netlink_message_handler_t callback);
DEFINE_NETDEV_CAST(IPIP, Tunnel); DEFINE_NETDEV_CAST(IPIP, Tunnel);
DEFINE_NETDEV_CAST(GRE, Tunnel); DEFINE_NETDEV_CAST(GRE, Tunnel);
DEFINE_NETDEV_CAST(GRETAP, Tunnel); DEFINE_NETDEV_CAST(GRETAP, Tunnel);

View File

@ -22,7 +22,7 @@
#define RESERVED_SUBNET_ANYCAST_ADDRESSES ((const struct in6_addr) { .s6_addr = { 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80 } }) #define RESERVED_SUBNET_ANYCAST_ADDRESSES ((const struct in6_addr) { .s6_addr = { 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80 } })
#define RESERVED_SUBNET_ANYCAST_PREFIXLEN 57 #define RESERVED_SUBNET_ANYCAST_PREFIXLEN 57
#define DHCP_PD_APP_ID SD_ID128_MAKE(fb,b9,37,ca,4a,ed,4a,4d,b0,70,7f,aa,71,c0,c9,85) #define DHCP6PD_APP_ID SD_ID128_MAKE(fb,b9,37,ca,4a,ed,4a,4d,b0,70,7f,aa,71,c0,c9,85)
#define NDISC_APP_ID SD_ID128_MAKE(13,ac,81,a7,d5,3f,49,78,92,79,5d,0c,29,3a,bc,7e) #define NDISC_APP_ID SD_ID128_MAKE(13,ac,81,a7,d5,3f,49,78,92,79,5d,0c,29,3a,bc,7e)
#define RADV_APP_ID SD_ID128_MAKE(1f,1e,90,c8,5c,78,4f,dc,8e,61,2d,59,0d,53,c1,25) #define RADV_APP_ID SD_ID128_MAKE(1f,1e,90,c8,5c,78,4f,dc,8e,61,2d,59,0d,53,c1,25)
@ -230,7 +230,7 @@ static int generate_addresses(
/* fall back to EUI-64 if no token is provided */ /* fall back to EUI-64 if no token is provided */
if (set_isempty(addresses)) { if (set_isempty(addresses)) {
_cleanup_free_ struct in6_addr *addr = NULL; struct in6_addr *addr;
addr = new(struct in6_addr, 1); addr = new(struct in6_addr, 1);
if (!addr) if (!addr)
@ -243,7 +243,7 @@ static int generate_addresses(
if (r < 0) if (r < 0)
return r; return r;
r = set_ensure_consume(&addresses, &in6_addr_hash_ops_free, TAKE_PTR(addr)); r = set_ensure_consume(&addresses, &in6_addr_hash_ops_free, addr);
if (r < 0) if (r < 0)
return r; return r;
} }
@ -252,8 +252,8 @@ static int generate_addresses(
return 0; return 0;
} }
int dhcp_pd_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret) { int dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret) {
return generate_addresses(link, link->network->dhcp_pd_tokens, &DHCP_PD_APP_ID, prefix, prefixlen, ret); return generate_addresses(link, link->network->dhcp6_pd_tokens, &DHCP6PD_APP_ID, prefix, 64, ret);
} }
int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret) { int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret) {

View File

@ -7,7 +7,7 @@
typedef struct Link Link; typedef struct Link Link;
int dhcp_pd_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret); int dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret);
int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret); int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret);
int radv_generate_addresses(Link *link, Set *tokens, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret); int radv_generate_addresses(Link *link, Set *tokens, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret);

View File

@ -39,6 +39,15 @@ uint32_t link_get_dhcp4_route_table(Link *link) {
return link_get_vrf_table(link); return link_get_vrf_table(link);
} }
uint32_t link_get_dhcp6_route_table(Link *link) {
assert(link);
assert(link->network);
if (link->network->dhcp6_route_table_set)
return link->network->dhcp6_route_table;
return link_get_vrf_table(link);
}
uint32_t link_get_ipv6_accept_ra_route_table(Link *link) { uint32_t link_get_ipv6_accept_ra_route_table(Link *link) {
assert(link); assert(link);
assert(link->network); assert(link->network);
@ -524,9 +533,13 @@ int config_parse_dhcp_or_ra_route_table(
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(IN_SET(ltype, AF_INET, AF_INET6)); assert(IN_SET(ltype,
(RTPROT_DHCP<<16) | AF_UNSPEC,
(RTPROT_DHCP<<16) | AF_INET,
(RTPROT_DHCP<<16) | AF_INET6,
(RTPROT_RA<<16) | AF_INET6));
assert(rvalue); assert(rvalue);
assert(userdata); assert(data);
r = safe_atou32(rvalue, &rt); r = safe_atou32(rvalue, &rt);
if (r < 0) { if (r < 0) {
@ -536,11 +549,28 @@ int config_parse_dhcp_or_ra_route_table(
} }
switch(ltype) { switch(ltype) {
case AF_INET: case (RTPROT_DHCP<<16) | AF_INET:
network->dhcp_route_table = rt; network->dhcp_route_table = rt;
network->dhcp_route_table_set = true; network->dhcp_route_table_set = true;
network->dhcp_route_table_set_explicitly = true;
break; break;
case AF_INET6: case (RTPROT_DHCP<<16) | AF_INET6:
network->dhcp6_route_table = rt;
network->dhcp6_route_table_set = true;
network->dhcp6_route_table_set_explicitly = true;
break;
case (RTPROT_DHCP<<16) | AF_UNSPEC:
/* For backward compatibility. */
if (!network->dhcp_route_table_set_explicitly) {
network->dhcp_route_table = rt;
network->dhcp_route_table_set = true;
}
if (!network->dhcp6_route_table_set_explicitly) {
network->dhcp6_route_table = rt;
network->dhcp6_route_table_set = true;
}
break;
case (RTPROT_RA<<16) | AF_INET6:
network->ipv6_accept_ra_route_table = rt; network->ipv6_accept_ra_route_table = rt;
network->ipv6_accept_ra_route_table_set = true; network->ipv6_accept_ra_route_table_set = true;
break; break;
@ -1267,9 +1297,9 @@ int config_parse_uplink(
} else if (streq(section, "IPv6SendRA")) { } else if (streq(section, "IPv6SendRA")) {
index = &network->router_uplink_index; index = &network->router_uplink_index;
name = &network->router_uplink_name; name = &network->router_uplink_name;
} else if (STR_IN_SET(section, "DHCPv6PrefixDelegation", "DHCPPrefixDelegation")) { } else if (streq(section, "DHCPv6PrefixDelegation")) {
index = &network->dhcp_pd_uplink_index; index = &network->dhcp6_pd_uplink_index;
name = &network->dhcp_pd_uplink_name; name = &network->dhcp6_pd_uplink_name;
accept_none = false; accept_none = false;
} else } else
assert_not_reached(); assert_not_reached();

View File

@ -51,6 +51,7 @@ typedef struct DUID {
} DUID; } DUID;
uint32_t link_get_dhcp4_route_table(Link *link); uint32_t link_get_dhcp4_route_table(Link *link);
uint32_t link_get_dhcp6_route_table(Link *link);
uint32_t link_get_ipv6_accept_ra_route_table(Link *link); uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
bool link_dhcp_enabled(Link *link, int family); bool link_dhcp_enabled(Link *link, int family);

File diff suppressed because it is too large Load Diff

View File

@ -3,23 +3,17 @@
#include <stdbool.h> #include <stdbool.h>
#include "sd-dhcp-lease.h"
#include "sd-dhcp6-lease.h"
#include "conf-parser.h" #include "conf-parser.h"
typedef struct Link Link; typedef struct Link Link;
bool link_dhcp_pd_is_enabled(Link *link); bool link_dhcp6_pd_is_enabled(Link *link);
bool dhcp_pd_is_uplink(Link *link, Link *target, bool accept_auto); bool dhcp6_pd_is_uplink(Link *link, Link *target, bool accept_auto);
int dhcp_pd_find_uplink(Link *link, Link **ret); int dhcp6_pd_find_uplink(Link *link, Link **ret);
bool dhcp4_lease_has_pd_prefix(sd_dhcp_lease *lease);
bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease); bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease);
int dhcp_pd_remove(Link *link, bool only_marked); int dhcp6_pd_remove(Link *link, bool only_marked);
int dhcp_request_prefix_delegation(Link *link); int dhcp6_request_prefix_delegation(Link *link);
int dhcp4_pd_prefix_acquired(Link *uplink); int dhcp6_pd_prefix_acquired(Link *dhcp6_link);
int dhcp6_pd_prefix_acquired(Link *uplink); void dhcp6_pd_prefix_lost(Link *dhcp6_link);
void dhcp_pd_prefix_lost(Link *uplink);
void dhcp4_pd_prefix_lost(Link *uplink);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_pd_subnet_id); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_subnet_id);

View File

@ -12,7 +12,6 @@
#include "parse-util.h" #include "parse-util.h"
#include "network-internal.h" #include "network-internal.h"
#include "networkd-address.h" #include "networkd-address.h"
#include "networkd-dhcp-prefix-delegation.h"
#include "networkd-dhcp4.h" #include "networkd-dhcp4.h"
#include "networkd-ipv4acd.h" #include "networkd-ipv4acd.h"
#include "networkd-link.h" #include "networkd-link.h"
@ -28,6 +27,7 @@
#include "sysctl-util.h" #include "sysctl-util.h"
static int dhcp4_request_address_and_routes(Link *link, bool announce); static int dhcp4_request_address_and_routes(Link *link, bool announce);
static int dhcp4_check_ready(Link *link);
void network_adjust_dhcp4(Network *network) { void network_adjust_dhcp4(Network *network) {
assert(network); assert(network);
@ -119,7 +119,7 @@ static int dhcp4_address_ready_callback(Address *address) {
return dhcp4_check_ready(address->link); return dhcp4_check_ready(address->link);
} }
int dhcp4_check_ready(Link *link) { static int dhcp4_check_ready(Link *link) {
Address *address; Address *address;
int r; int r;
@ -789,16 +789,11 @@ int dhcp4_lease_lost(Link *link) {
assert(link); assert(link);
assert(link->dhcp_lease); assert(link->dhcp_lease);
assert(link->network);
log_link_info(link, "DHCP lease lost"); log_link_info(link, "DHCP lease lost");
link->dhcp4_configured = false; link->dhcp4_configured = false;
if (link->network->dhcp_use_6rd &&
dhcp4_lease_has_pd_prefix(link->dhcp_lease))
dhcp4_pd_prefix_lost(link);
k = dhcp4_remove_address_and_routes(link, /* only_marked = */ false); k = dhcp4_remove_address_and_routes(link, /* only_marked = */ false);
if (k < 0) if (k < 0)
r = k; r = k;
@ -969,31 +964,20 @@ static int dhcp4_request_address_and_routes(Link *link, bool announce) {
} }
static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) { static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
_cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *old_lease = NULL;
sd_dhcp_lease *lease; sd_dhcp_lease *lease;
int r; int r;
assert(link); assert(link);
assert(link->network);
assert(client); assert(client);
r = sd_dhcp_client_get_lease(client, &lease); r = sd_dhcp_client_get_lease(client, &lease);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "DHCP error: no lease: %m"); return log_link_warning_errno(link, r, "DHCP error: no lease: %m");
old_lease = TAKE_PTR(link->dhcp_lease); sd_dhcp_lease_unref(link->dhcp_lease);
link->dhcp_lease = sd_dhcp_lease_ref(lease); link->dhcp_lease = sd_dhcp_lease_ref(lease);
link_dirty(link); link_dirty(link);
if (link->network->dhcp_use_6rd) {
if (dhcp4_lease_has_pd_prefix(link->dhcp_lease)) {
r = dhcp4_pd_prefix_acquired(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to process 6rd option: %m");
} else if (dhcp4_lease_has_pd_prefix(old_lease))
dhcp4_pd_prefix_lost(link);
}
return dhcp4_request_address_and_routes(link, false); return dhcp4_request_address_and_routes(link, false);
} }
@ -1059,13 +1043,6 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
} }
} }
if (link->network->dhcp_use_6rd &&
dhcp4_lease_has_pd_prefix(link->dhcp_lease)) {
r = dhcp4_pd_prefix_acquired(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to process 6rd option: %m");
}
return dhcp4_request_address_and_routes(link, true); return dhcp4_request_address_and_routes(link, true);
} }
@ -1462,12 +1439,6 @@ static int dhcp4_configure(Link *link) {
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for timezone: %m"); return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for timezone: %m");
} }
if (link->network->dhcp_use_6rd) {
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_6RD);
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for 6rd: %m");
}
SET_FOREACH(request_options, link->network->dhcp_request_options) { SET_FOREACH(request_options, link->network->dhcp_request_options) {
uint32_t option = PTR_TO_UINT32(request_options); uint32_t option = PTR_TO_UINT32(request_options);

View File

@ -23,7 +23,6 @@ void network_adjust_dhcp4(Network *network);
int dhcp4_update_mac(Link *link); int dhcp4_update_mac(Link *link);
int dhcp4_start(Link *link); int dhcp4_start(Link *link);
int dhcp4_lease_lost(Link *link); int dhcp4_lease_lost(Link *link);
int dhcp4_check_ready(Link *link);
int request_process_dhcp4_client(Request *req); int request_process_dhcp4_client(Request *req);
int link_request_dhcp4_client(Link *link); int link_request_dhcp4_client(Link *link);

View File

@ -36,7 +36,7 @@ static DHCP6ClientStartMode link_get_dhcp6_client_start_mode(Link *link) {
return link->network->dhcp6_client_start_mode; return link->network->dhcp6_client_start_mode;
/* When this interface itself is an uplink interface, then start dhcp6 client in managed mode. */ /* When this interface itself is an uplink interface, then start dhcp6 client in managed mode. */
if (dhcp_pd_is_uplink(link, link, /* accept_auto = */ false)) if (dhcp6_pd_is_uplink(link, link, /* accept_auto = */ false))
return DHCP6_CLIENT_START_MODE_SOLICIT; return DHCP6_CLIENT_START_MODE_SOLICIT;
/* Otherwise, start dhcp6 client when RA is received. */ /* Otherwise, start dhcp6 client when RA is received. */
@ -323,7 +323,7 @@ static int dhcp6_lease_ip_acquired(sd_dhcp6_client *client, Link *link) {
return r; return r;
} else if (dhcp6_lease_has_pd_prefix(lease_old)) } else if (dhcp6_lease_has_pd_prefix(lease_old))
/* When we had PD prefixes but not now, we need to remove them. */ /* When we had PD prefixes but not now, we need to remove them. */
dhcp_pd_prefix_lost(link); dhcp6_pd_prefix_lost(link);
if (link->dhcp6_messages == 0) { if (link->dhcp6_messages == 0) {
link->dhcp6_configured = true; link->dhcp6_configured = true;
@ -354,7 +354,7 @@ static int dhcp6_lease_lost(Link *link) {
log_link_info(link, "DHCPv6 lease lost"); log_link_info(link, "DHCPv6 lease lost");
if (dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) if (dhcp6_lease_has_pd_prefix(link->dhcp6_lease))
dhcp_pd_prefix_lost(link); dhcp6_pd_prefix_lost(link);
link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease); link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease);

View File

@ -172,6 +172,9 @@ bool link_is_ready_to_configure(Link *link, bool allow_unmanaged) {
if (link->set_link_messages > 0) if (link->set_link_messages > 0)
return false; return false;
if (!link->stacked_netdevs_created)
return false;
if (!link->activated) if (!link->activated)
return false; return false;
@ -208,7 +211,6 @@ static void link_free_engines(Link *link) {
link->dhcp_server = sd_dhcp_server_unref(link->dhcp_server); link->dhcp_server = sd_dhcp_server_unref(link->dhcp_server);
link->dhcp_client = sd_dhcp_client_unref(link->dhcp_client); link->dhcp_client = sd_dhcp_client_unref(link->dhcp_client);
link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease); link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
link->dhcp4_6rd_tunnel_name = mfree(link->dhcp4_6rd_tunnel_name);
link->lldp_rx = sd_lldp_rx_unref(link->lldp_rx); link->lldp_rx = sd_lldp_rx_unref(link->lldp_rx);
link->lldp_tx = sd_lldp_tx_unref(link->lldp_tx); link->lldp_tx = sd_lldp_tx_unref(link->lldp_tx);
@ -236,7 +238,7 @@ static Link *link_free(Link *link) {
link->addresses = set_free(link->addresses); link->addresses = set_free(link->addresses);
link->dhcp_pd_prefixes = set_free(link->dhcp_pd_prefixes); link->dhcp6_pd_prefixes = set_free(link->dhcp6_pd_prefixes);
link_free_engines(link); link_free_engines(link);
@ -382,7 +384,7 @@ int link_stop_engines(Link *link, bool may_keep_dhcp) {
if (k < 0) if (k < 0)
r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m"); r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m");
k = dhcp_pd_remove(link, /* only_marked = */ false); k = dhcp6_pd_remove(link, /* only_marked = */ false);
if (k < 0) if (k < 0)
r = log_link_warning_errno(link, k, "Could not remove DHCPv6 PD addresses and routes: %m"); r = log_link_warning_errno(link, k, "Could not remove DHCPv6 PD addresses and routes: %m");
@ -439,9 +441,6 @@ void link_check_ready(Link *link) {
return; return;
} }
if (!link->stacked_netdevs_created)
return (void) log_link_debug(link, "%s(): stacked netdevs are not created.", __func__);
if (!link->static_addresses_configured) if (!link->static_addresses_configured)
return (void) log_link_debug(link, "%s(): static addresses are not configured.", __func__); return (void) log_link_debug(link, "%s(): static addresses are not configured.", __func__);
@ -496,7 +495,7 @@ void link_check_ready(Link *link) {
NETWORK_CONFIG_SOURCE_IPV4LL, NETWORK_CONFIG_SOURCE_IPV4LL,
NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP4,
NETWORK_CONFIG_SOURCE_DHCP6, NETWORK_CONFIG_SOURCE_DHCP6,
NETWORK_CONFIG_SOURCE_DHCP_PD, NETWORK_CONFIG_SOURCE_DHCP6PD,
NETWORK_CONFIG_SOURCE_NDISC)) { NETWORK_CONFIG_SOURCE_NDISC)) {
has_dynamic_address = true; has_dynamic_address = true;
break; break;
@ -504,26 +503,26 @@ void link_check_ready(Link *link) {
} }
if ((link_ipv4ll_enabled(link) || link_dhcp4_enabled(link) || link_dhcp6_with_address_enabled(link) || if ((link_ipv4ll_enabled(link) || link_dhcp4_enabled(link) || link_dhcp6_with_address_enabled(link) ||
(link_dhcp_pd_is_enabled(link) && link->network->dhcp_pd_assign)) && !has_dynamic_address) (link_dhcp6_pd_is_enabled(link) && link->network->dhcp6_pd_assign)) && !has_dynamic_address)
/* When DHCP[46] or IPv4LL is enabled, at least one address is acquired by them. */ /* When DHCP[46] or IPv4LL is enabled, at least one address is acquired by them. */
return (void) log_link_debug(link, "%s(): DHCPv4, DHCPv6, DHCP-PD or IPv4LL is enabled but no dynamic address is assigned yet.", __func__); return (void) log_link_debug(link, "%s(): DHCPv4, DHCPv6, DHCPv6PD or IPv4LL is enabled but no dynamic address is assigned yet.", __func__);
/* Ignore NDisc when ConfigureWithoutCarrier= is enabled, as IPv6AcceptRA= is enabled by default. */ /* Ignore NDisc when ConfigureWithoutCarrier= is enabled, as IPv6AcceptRA= is enabled by default. */
if (link_ipv4ll_enabled(link) || link_dhcp4_enabled(link) || if (link_ipv4ll_enabled(link) || link_dhcp4_enabled(link) ||
link_dhcp6_enabled(link) || link_dhcp_pd_is_enabled(link) || link_dhcp6_enabled(link) || link_dhcp6_pd_is_enabled(link) ||
(!link->network->configure_without_carrier && link_ipv6_accept_ra_enabled(link))) { (!link->network->configure_without_carrier && link_ipv6_accept_ra_enabled(link))) {
if (!link->ipv4ll_address_configured && !link->dhcp4_configured && if (!link->ipv4ll_address_configured && !link->dhcp4_configured &&
!link->dhcp6_configured && !link->dhcp_pd_configured && !link->ndisc_configured) !link->dhcp6_configured && !link->dhcp6_pd_configured && !link->ndisc_configured)
/* When DHCP[46], NDisc, or IPv4LL is enabled, at least one protocol must be finished. */ /* When DHCP[46], NDisc, or IPv4LL is enabled, at least one protocol must be finished. */
return (void) log_link_debug(link, "%s(): dynamic addresses or routes are not configured.", __func__); return (void) log_link_debug(link, "%s(): dynamic addresses or routes are not configured.", __func__);
log_link_debug(link, "%s(): IPv4LL:%s DHCPv4:%s DHCPv6:%s DHCP-PD:%s NDisc:%s", log_link_debug(link, "%s(): IPv4LL:%s DHCPv4:%s DHCPv6:%s DHCPv6PD:%s NDisc:%s",
__func__, __func__,
yes_no(link->ipv4ll_address_configured), yes_no(link->ipv4ll_address_configured),
yes_no(link->dhcp4_configured), yes_no(link->dhcp4_configured),
yes_no(link->dhcp6_configured), yes_no(link->dhcp6_configured),
yes_no(link->dhcp_pd_configured), yes_no(link->dhcp6_pd_configured),
yes_no(link->ndisc_configured)); yes_no(link->ndisc_configured));
} }
@ -670,14 +669,14 @@ static int link_acquire_dynamic_conf(Link *link) {
return r; return r;
} }
if (!link_radv_enabled(link) || !link->network->dhcp_pd_announce) { if (!link_radv_enabled(link) || !link->network->dhcp6_pd_announce) {
/* DHCPv6PD downstream does not require IPv6LL address. But may require RADV to be /* DHCPv6PD downstream does not require IPv6LL address. But may require RADV to be
* configured, and RADV may not be configured yet here. Only acquire subnet prefix when * configured, and RADV may not be configured yet here. Only acquire subnet prefix when
* RADV is disabled, or the announcement of the prefix is disabled. Otherwise, the * RADV is disabled, or the announcement of the prefix is disabled. Otherwise, the
* below will be called in radv_start(). */ * below will be called in radv_start(). */
r = dhcp_request_prefix_delegation(link); r = dhcp6_request_prefix_delegation(link);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to request DHCP delegated subnet prefix: %m"); return log_link_warning_errno(link, r, "Failed to request DHCPv6 prefix delegation: %m");
} }
if (link->lldp_tx) { if (link->lldp_tx) {

View File

@ -114,7 +114,6 @@ typedef struct Link {
bool dhcp4_route_failed:1; bool dhcp4_route_failed:1;
bool dhcp4_route_retrying:1; bool dhcp4_route_retrying:1;
bool dhcp4_configured:1; bool dhcp4_configured:1;
char *dhcp4_6rd_tunnel_name;
sd_ipv4ll *ipv4ll; sd_ipv4ll *ipv4ll;
bool ipv4ll_address_configured:1; bool ipv4ll_address_configured:1;
@ -147,12 +146,11 @@ typedef struct Link {
sd_dhcp6_client *dhcp6_client; sd_dhcp6_client *dhcp6_client;
sd_dhcp6_lease *dhcp6_lease; sd_dhcp6_lease *dhcp6_lease;
Set *dhcp6_pd_prefixes;
unsigned dhcp6_messages; unsigned dhcp6_messages;
bool dhcp6_configured; unsigned dhcp6_pd_messages;
bool dhcp6_configured:1;
Set *dhcp_pd_prefixes; bool dhcp6_pd_configured:1;
unsigned dhcp_pd_messages;
bool dhcp_pd_configured;
/* This is about LLDP reception */ /* This is about LLDP reception */
sd_lldp_rx *lldp_rx; sd_lldp_rx *lldp_rx;

View File

@ -499,10 +499,10 @@ Manager* manager_free(Manager *m) {
m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref); m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
m->links_by_name = hashmap_free(m->links_by_name); m->links_by_name = hashmap_free(m->links_by_name);
m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr); m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
m->links_by_dhcp_pd_subnet_prefix = hashmap_free(m->links_by_dhcp_pd_subnet_prefix); m->links_by_dhcp6_pd_prefix = hashmap_free(m->links_by_dhcp6_pd_prefix);
m->links_by_index = hashmap_free_with_destructor(m->links_by_index, link_unref); m->links_by_index = hashmap_free_with_destructor(m->links_by_index, link_unref);
m->dhcp_pd_subnet_ids = set_free(m->dhcp_pd_subnet_ids); m->dhcp6_pd_subnet_ids = set_free(m->dhcp6_pd_subnet_ids);
m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref); m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref); m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
@ -586,7 +586,7 @@ int manager_load_config(Manager *m) {
if (r < 0) if (r < 0)
return r; return r;
return manager_build_dhcp_pd_subnet_ids(m); return manager_build_dhcp6_pd_subnet_ids(m);
} }
bool manager_should_reload(Manager *m) { bool manager_should_reload(Manager *m) {

View File

@ -48,11 +48,11 @@ struct Manager {
Hashmap *links_by_index; Hashmap *links_by_index;
Hashmap *links_by_name; Hashmap *links_by_name;
Hashmap *links_by_hw_addr; Hashmap *links_by_hw_addr;
Hashmap *links_by_dhcp_pd_subnet_prefix; Hashmap *links_by_dhcp6_pd_prefix;
Hashmap *netdevs; Hashmap *netdevs;
OrderedHashmap *networks; OrderedHashmap *networks;
OrderedSet *address_pools; OrderedSet *address_pools;
Set *dhcp_pd_subnet_ids; Set *dhcp6_pd_subnet_ids;
usec_t network_dirs_ts_usec; usec_t network_dirs_ts_usec;

View File

@ -140,7 +140,7 @@ Network.ConfigureWithoutCarrier, config_parse_bool,
Network.IgnoreCarrierLoss, config_parse_ignore_carrier_loss, 0, 0 Network.IgnoreCarrierLoss, config_parse_ignore_carrier_loss, 0, 0
Network.KeepConfiguration, config_parse_keep_configuration, 0, offsetof(Network, keep_configuration) Network.KeepConfiguration, config_parse_keep_configuration, 0, offsetof(Network, keep_configuration)
Network.IPv6SendRA, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation) Network.IPv6SendRA, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation)
Network.DHCPPrefixDelegation, config_parse_tristate, 0, offsetof(Network, dhcp_pd) Network.DHCPv6PrefixDelegation, config_parse_tristate, 0, offsetof(Network, dhcp6_pd)
Address.Address, config_parse_address, 0, 0 Address.Address, config_parse_address, 0, 0
Address.Peer, config_parse_address, 0, 0 Address.Peer, config_parse_address, 0, 0
Address.Broadcast, config_parse_broadcast, 0, 0 Address.Broadcast, config_parse_broadcast, 0, 0
@ -228,7 +228,7 @@ DHCPv4.IAID, config_parse_iaid,
DHCPv4.DUIDType, config_parse_network_duid_type, 0, 0 DHCPv4.DUIDType, config_parse_network_duid_type, 0, 0
DHCPv4.DUIDRawData, config_parse_network_duid_rawdata, 0, 0 DHCPv4.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
DHCPv4.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET, 0 DHCPv4.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET, 0
DHCPv4.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET, 0 DHCPv4.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_DHCP<<16) | AF_INET, 0
DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release) DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
@ -240,7 +240,6 @@ DHCPv4.SendOption, config_parse_dhcp_send_option,
DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options) DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options)
DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu) DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu)
DHCPv4.FallbackLeaseLifetimeSec, config_parse_dhcp_fallback_lease_lifetime, 0, 0 DHCPv4.FallbackLeaseLifetimeSec, config_parse_dhcp_fallback_lease_lifetime, 0, 0
DHCPv4.Use6RD, config_parse_bool, 0, offsetof(Network, dhcp_use_6rd)
DHCPv6.UseAddress, config_parse_bool, 0, offsetof(Network, dhcp6_use_address) DHCPv6.UseAddress, config_parse_bool, 0, offsetof(Network, dhcp6_use_address)
DHCPv6.UseDelegatedPrefix, config_parse_bool, 0, offsetof(Network, dhcp6_use_pd_prefix) DHCPv6.UseDelegatedPrefix, config_parse_bool, 0, offsetof(Network, dhcp6_use_pd_prefix)
DHCPv6.UseDNS, config_parse_dhcp_use_dns, AF_INET6, 0 DHCPv6.UseDNS, config_parse_dhcp_use_dns, AF_INET6, 0
@ -258,6 +257,7 @@ DHCPv6.SendOption, config_parse_dhcp_send_option,
DHCPv6.IAID, config_parse_iaid, AF_INET6, 0 DHCPv6.IAID, config_parse_iaid, AF_INET6, 0
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Network, dhcp6_duid) DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Network, dhcp6_duid)
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, dhcp6_duid) DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, dhcp6_duid)
DHCPv6.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_DHCP<<16) | AF_INET6, 0
IPv6AcceptRA.UseGateway, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_gateway) IPv6AcceptRA.UseGateway, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_gateway)
IPv6AcceptRA.UseRoutePrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_route_prefix) IPv6AcceptRA.UseRoutePrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_route_prefix)
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix) IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
@ -266,7 +266,7 @@ IPv6AcceptRA.UseDNS, config_parse_bool,
IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains) IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
IPv6AcceptRA.UseMTU, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_mtu) IPv6AcceptRA.UseMTU, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_mtu)
IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client) IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET6, 0 IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_RA<<16) | AF_INET6, 0
IPv6AcceptRA.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET6, 0 IPv6AcceptRA.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET6, 0
IPv6AcceptRA.RouterAllowList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_allow_listed_router) IPv6AcceptRA.RouterAllowList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_allow_listed_router)
IPv6AcceptRA.RouterDenyList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_deny_listed_router) IPv6AcceptRA.RouterDenyList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_deny_listed_router)
@ -330,13 +330,13 @@ BridgeMDB.VLANId, config_parse_mdb_vlan_id,
BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0 BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0 BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0 BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
DHCPPrefixDelegation.UplinkInterface, config_parse_uplink, 0, 0 DHCPv6PrefixDelegation.UplinkInterface, config_parse_uplink, 0, 0
DHCPPrefixDelegation.SubnetId, config_parse_dhcp_pd_subnet_id, 0, offsetof(Network, dhcp_pd_subnet_id) DHCPv6PrefixDelegation.SubnetId, config_parse_dhcp6_pd_subnet_id, 0, offsetof(Network, dhcp6_pd_subnet_id)
DHCPPrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp_pd_announce) DHCPv6PrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp6_pd_announce)
DHCPPrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp_pd_assign) DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign)
DHCPPrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp_pd_manage_temporary_address) DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address)
DHCPPrefixDelegation.Token, config_parse_address_generation_type, 0, offsetof(Network, dhcp_pd_tokens) DHCPv6PrefixDelegation.Token, config_parse_address_generation_type, 0, offsetof(Network, dhcp6_pd_tokens)
DHCPPrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp_pd_route_metric) DHCPv6PrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp6_pd_route_metric)
IPv6SendRA.RouterLifetimeSec, config_parse_router_lifetime, 0, offsetof(Network, router_lifetime_usec) IPv6SendRA.RouterLifetimeSec, config_parse_router_lifetime, 0, offsetof(Network, router_lifetime_usec)
IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed) IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
IPv6SendRA.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information) IPv6SendRA.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
@ -514,7 +514,6 @@ TrivialLinkEqualizer.Id, config_parse_trivial_link_equalizer
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
Network.IPv6Token, config_parse_address_generation_type, 0, offsetof(Network, ndisc_tokens) Network.IPv6Token, config_parse_address_generation_type, 0, offsetof(Network, ndisc_tokens)
Network.IPv6PrefixDelegation, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation) Network.IPv6PrefixDelegation, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation)
Network.DHCPv6PrefixDelegation, config_parse_tristate, 0, offsetof(Network, dhcp_pd)
IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec) IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed) IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
IPv6PrefixDelegation.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information) IPv6PrefixDelegation.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
@ -544,7 +543,7 @@ DHCP.IAID, config_parse_iaid,
DHCP.DUIDType, config_parse_network_duid_type, 0, 0 DHCP.DUIDType, config_parse_network_duid_type, 0, 0
DHCP.DUIDRawData, config_parse_network_duid_rawdata, 0, 0 DHCP.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
DHCP.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_UNSPEC, 0 DHCP.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_UNSPEC, 0
DHCP.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET, 0 DHCP.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_DHCP<<16) | AF_UNSPEC, 0
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCP.RapidCommit, config_parse_warn_compat, DISABLED_LEGACY, 0 DHCP.RapidCommit, config_parse_warn_compat, DISABLED_LEGACY, 0
@ -554,12 +553,6 @@ DHCPv4.CriticalConnection, config_parse_tristate,
DHCPv6.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET6, 0 DHCPv6.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET6, 0
DHCPv6.RapidCommit, config_parse_warn_compat, DISABLED_LEGACY, 0 DHCPv6.RapidCommit, config_parse_warn_compat, DISABLED_LEGACY, 0
DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_warn_compat, DISABLED_LEGACY, 0 DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_warn_compat, DISABLED_LEGACY, 0
DHCPv6PrefixDelegation.SubnetId, config_parse_dhcp_pd_subnet_id, 0, offsetof(Network, dhcp_pd_subnet_id)
DHCPv6PrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp_pd_announce)
DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp_pd_assign)
DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp_pd_manage_temporary_address)
DHCPv6PrefixDelegation.Token, config_parse_address_generation_type, 0, offsetof(Network, dhcp_pd_tokens)
DHCPv6PrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp_pd_route_metric)
IPv6AcceptRA.DenyList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_deny_listed_prefix) IPv6AcceptRA.DenyList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_deny_listed_prefix)
IPv6AcceptRA.BlackList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_deny_listed_prefix) IPv6AcceptRA.BlackList, config_parse_in_addr_prefixes, AF_INET6, offsetof(Network, ndisc_deny_listed_prefix)
TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0 TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0

View File

@ -412,12 +412,12 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp6_duid.type = _DUID_TYPE_INVALID, .dhcp6_duid.type = _DUID_TYPE_INVALID,
.dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID, .dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID,
.dhcp_pd = -1, .dhcp6_pd = -1,
.dhcp_pd_announce = true, .dhcp6_pd_announce = true,
.dhcp_pd_assign = true, .dhcp6_pd_assign = true,
.dhcp_pd_manage_temporary_address = true, .dhcp6_pd_manage_temporary_address = true,
.dhcp_pd_subnet_id = -1, .dhcp6_pd_subnet_id = -1,
.dhcp_pd_route_metric = DHCP6PD_ROUTE_METRIC, .dhcp6_pd_route_metric = DHCP6PD_ROUTE_METRIC,
.dhcp_server_bind_to_interface = true, .dhcp_server_bind_to_interface = true,
.dhcp_server_emit[SD_DHCP_LEASE_DNS].emit = true, .dhcp_server_emit[SD_DHCP_LEASE_DNS].emit = true,
@ -498,8 +498,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"DHCP\0" /* compat */ "DHCP\0" /* compat */
"DHCPv4\0" "DHCPv4\0"
"DHCPv6\0" "DHCPv6\0"
"DHCPv6PrefixDelegation\0" /* compat */ "DHCPv6PrefixDelegation\0"
"DHCPPrefixDelegation\0"
"DHCPServer\0" "DHCPServer\0"
"DHCPServerStaticLease\0" "DHCPServerStaticLease\0"
"IPv6AcceptRA\0" "IPv6AcceptRA\0"
@ -649,7 +648,7 @@ int network_reload(Manager *manager) {
ordered_hashmap_free_with_destructor(manager->networks, network_unref); ordered_hashmap_free_with_destructor(manager->networks, network_unref);
manager->networks = new_networks; manager->networks = new_networks;
return manager_build_dhcp_pd_subnet_ids(manager); return manager_build_dhcp6_pd_subnet_ids(manager);
failure: failure:
ordered_hashmap_free_with_destructor(new_networks, network_unref); ordered_hashmap_free_with_destructor(new_networks, network_unref);
@ -657,25 +656,25 @@ failure:
return r; return r;
} }
int manager_build_dhcp_pd_subnet_ids(Manager *manager) { int manager_build_dhcp6_pd_subnet_ids(Manager *manager) {
Network *n; Network *n;
int r; int r;
assert(manager); assert(manager);
set_clear(manager->dhcp_pd_subnet_ids); set_clear(manager->dhcp6_pd_subnet_ids);
ORDERED_HASHMAP_FOREACH(n, manager->networks) { ORDERED_HASHMAP_FOREACH(n, manager->networks) {
if (n->unmanaged) if (n->unmanaged)
continue; continue;
if (!n->dhcp_pd) if (!n->dhcp6_pd)
continue; continue;
if (n->dhcp_pd_subnet_id < 0) if (n->dhcp6_pd_subnet_id < 0)
continue; continue;
r = set_ensure_put(&manager->dhcp_pd_subnet_ids, &uint64_hash_ops, &n->dhcp_pd_subnet_id); r = set_ensure_put(&manager->dhcp6_pd_subnet_ids, &uint64_hash_ops, &n->dhcp6_pd_subnet_id);
if (r < 0) if (r < 0)
return r; return r;
} }
@ -757,7 +756,7 @@ static Network *network_free(Network *network) {
free(network->dhcp_server_timezone); free(network->dhcp_server_timezone);
free(network->dhcp_server_uplink_name); free(network->dhcp_server_uplink_name);
free(network->router_uplink_name); free(network->router_uplink_name);
free(network->dhcp_pd_uplink_name); free(network->dhcp6_pd_uplink_name);
for (sd_dhcp_lease_server_type_t t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++) for (sd_dhcp_lease_server_type_t t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++)
free(network->dhcp_server_emit[t].addresses); free(network->dhcp_server_emit[t].addresses);
@ -772,7 +771,7 @@ static Network *network_free(Network *network) {
ordered_hashmap_free(network->dhcp_server_send_vendor_options); ordered_hashmap_free(network->dhcp_server_send_vendor_options);
ordered_hashmap_free(network->dhcp6_client_send_options); ordered_hashmap_free(network->dhcp6_client_send_options);
ordered_hashmap_free(network->dhcp6_client_send_vendor_options); ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
set_free(network->dhcp_pd_tokens); set_free(network->dhcp6_pd_tokens);
set_free(network->ndisc_tokens); set_free(network->ndisc_tokens);
return mfree(network); return mfree(network);

View File

@ -133,6 +133,7 @@ struct Network {
bool dhcp_route_metric_set; bool dhcp_route_metric_set;
uint32_t dhcp_route_table; uint32_t dhcp_route_table;
bool dhcp_route_table_set; bool dhcp_route_table_set;
bool dhcp_route_table_set_explicitly;
uint32_t dhcp_fallback_lease_lifetime; uint32_t dhcp_fallback_lease_lifetime;
uint32_t dhcp_route_mtu; uint32_t dhcp_route_mtu;
uint16_t dhcp_client_port; uint16_t dhcp_client_port;
@ -153,7 +154,6 @@ struct Network {
int dhcp_use_gateway; int dhcp_use_gateway;
bool dhcp_use_timezone; bool dhcp_use_timezone;
bool dhcp_use_hostname; bool dhcp_use_hostname;
bool dhcp_use_6rd;
bool dhcp_send_release; bool dhcp_send_release;
bool dhcp_send_decline; bool dhcp_send_decline;
DHCPUseDomains dhcp_use_domains; DHCPUseDomains dhcp_use_domains;
@ -172,6 +172,9 @@ struct Network {
bool dhcp6_use_hostname; bool dhcp6_use_hostname;
bool dhcp6_use_ntp; bool dhcp6_use_ntp;
bool dhcp6_use_ntp_set; bool dhcp6_use_ntp_set;
bool dhcp6_route_table;
bool dhcp6_route_table_set;
bool dhcp6_route_table_set_explicitly;
DHCPUseDomains dhcp6_use_domains; DHCPUseDomains dhcp6_use_domains;
bool dhcp6_use_domains_set; bool dhcp6_use_domains_set;
uint32_t dhcp6_iaid; uint32_t dhcp6_iaid;
@ -230,16 +233,16 @@ struct Network {
int router_uplink_index; int router_uplink_index;
char *router_uplink_name; char *router_uplink_name;
/* DHCP Prefix Delegation support */ /* DHCPv6 Prefix Delegation support */
int dhcp_pd; int dhcp6_pd;
bool dhcp_pd_announce; bool dhcp6_pd_announce;
bool dhcp_pd_assign; bool dhcp6_pd_assign;
bool dhcp_pd_manage_temporary_address; bool dhcp6_pd_manage_temporary_address;
int64_t dhcp_pd_subnet_id; int64_t dhcp6_pd_subnet_id;
uint32_t dhcp_pd_route_metric; uint32_t dhcp6_pd_route_metric;
Set *dhcp_pd_tokens; Set *dhcp6_pd_tokens;
int dhcp_pd_uplink_index; int dhcp6_pd_uplink_index;
char *dhcp_pd_uplink_name; char *dhcp6_pd_uplink_name;
/* Bridge Support */ /* Bridge Support */
int use_bpdu; int use_bpdu;
@ -367,7 +370,7 @@ int network_reload(Manager *manager);
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename); int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename);
int network_verify(Network *network); int network_verify(Network *network);
int manager_build_dhcp_pd_subnet_ids(Manager *manager); int manager_build_dhcp6_pd_subnet_ids(Manager *manager);
int network_get_by_name(Manager *manager, const char *name, Network **ret); int network_get_by_name(Manager *manager, const char *name, Network **ret);
void network_apply_anonymize_if_set(Network *network); void network_apply_anonymize_if_set(Network *network);

View File

@ -27,9 +27,9 @@ void network_adjust_radv(Network *network) {
/* After this function is called, network->router_prefix_delegation can be treated as a boolean. */ /* After this function is called, network->router_prefix_delegation can be treated as a boolean. */
if (network->dhcp_pd < 0) if (network->dhcp6_pd < 0)
/* For backward compatibility. */ /* For backward compatibility. */
network->dhcp_pd = FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_DHCP6); network->dhcp6_pd = FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_DHCP6);
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) { if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE) if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE)
@ -421,8 +421,8 @@ static int radv_find_uplink(Link *link, Link **ret) {
return link_get_by_index(link->manager, link->network->router_uplink_index, ret); return link_get_by_index(link->manager, link->network->router_uplink_index, ret);
if (link->network->router_uplink_index == UPLINK_INDEX_AUTO) { if (link->network->router_uplink_index == UPLINK_INDEX_AUTO) {
if (link_dhcp_pd_is_enabled(link)) if (link_dhcp6_pd_is_enabled(link))
r = dhcp_pd_find_uplink(link, ret); /* When DHCP-PD is enabled, use its uplink. */ r = dhcp6_pd_find_uplink(link, ret); /* When DHCPv6PD is enabled, use its uplink. */
else else
r = manager_find_uplink(link->manager, AF_INET6, link, ret); r = manager_find_uplink(link->manager, AF_INET6, link, ret);
if (r < 0) if (r < 0)
@ -642,10 +642,10 @@ int radv_start(Link *link) {
if (sd_radv_is_running(link->radv)) if (sd_radv_is_running(link->radv))
return 0; return 0;
if (link->network->dhcp_pd_announce) { if (link->network->dhcp6_pd_announce) {
r = dhcp_request_prefix_delegation(link); r = dhcp6_request_prefix_delegation(link);
if (r < 0) if (r < 0)
return log_link_debug_errno(link, r, "Failed to request DHCP delegated subnet prefix: %m"); return log_link_debug_errno(link, r, "Failed to request DHCPv6 prefix delegation: %m");
} }
log_link_debug(link, "Starting IPv6 Router Advertisements"); log_link_debug(link, "Starting IPv6 Router Advertisements");

View File

@ -568,19 +568,12 @@ static bool link_is_ready_to_call_set_link(Request *req) {
break; break;
case SET_LINK_MASTER: { case SET_LINK_MASTER: {
uint32_t m = 0; uint32_t m = 0;
Request req_mac = {
.link = link,
.type = REQUEST_TYPE_SET_LINK,
.set_link_operation_ptr = INT_TO_PTR(SET_LINK_MAC),
};
if (link->network->batadv) { if (link->network->batadv) {
if (!netdev_is_ready(link->network->batadv)) if (!netdev_is_ready(link->network->batadv))
return false; return false;
m = link->network->batadv->ifindex; m = link->network->batadv->ifindex;
} else if (link->network->bond) { } else if (link->network->bond) {
if (ordered_set_contains(link->manager->request_queue, &req_mac))
return false;
if (!netdev_is_ready(link->network->bond)) if (!netdev_is_ready(link->network->bond))
return false; return false;
m = link->network->bond->ifindex; m = link->network->bond->ifindex;
@ -596,8 +589,6 @@ static bool link_is_ready_to_call_set_link(Request *req) {
} }
} }
} else if (link->network->bridge) { } else if (link->network->bridge) {
if (ordered_set_contains(link->manager->request_queue, &req_mac))
return false;
if (!netdev_is_ready(link->network->bridge)) if (!netdev_is_ready(link->network->bridge))
return false; return false;
m = link->network->bridge->ifindex; m = link->network->bridge->ifindex;
@ -1180,43 +1171,3 @@ int link_request_to_bring_up_or_down(Link *link, bool up) {
log_link_debug(link, "Requested to bring link %s", up_or_down(up)); log_link_debug(link, "Requested to bring link %s", up_or_down(up));
return 0; return 0;
} }
static int link_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(m);
assert(link);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
r = sd_netlink_message_get_errno(m);
if (r < 0)
log_link_message_warning_errno(link, m, r, "Could not remove interface, ignoring");
return 0;
}
int link_remove(Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
assert(link);
assert(link->manager);
assert(link->manager->rtnl);
log_link_debug(link, "Removing link.");
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_DELLINK, link->ifindex);
if (r < 0)
return log_link_debug_errno(link, r, "Could not allocate RTM_DELLINK message: %m");
r = netlink_call_async(link->manager->rtnl, NULL, req, link_remove_handler,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_debug_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
return 0;
}

View File

@ -49,5 +49,3 @@ int link_request_to_activate(Link *link);
int request_process_link_up_or_down(Request *req); int request_process_link_up_or_down(Request *req);
int link_request_to_bring_up_or_down(Link *link, bool up); int link_request_to_bring_up_or_down(Link *link, bool up);
int link_remove(Link *link);

View File

@ -17,7 +17,7 @@ static const char * const network_config_source_table[_NETWORK_CONFIG_SOURCE_MAX
[NETWORK_CONFIG_SOURCE_IPV4LL] = "IPv4LL", [NETWORK_CONFIG_SOURCE_IPV4LL] = "IPv4LL",
[NETWORK_CONFIG_SOURCE_DHCP4] = "DHCPv4", [NETWORK_CONFIG_SOURCE_DHCP4] = "DHCPv4",
[NETWORK_CONFIG_SOURCE_DHCP6] = "DHCPv6", [NETWORK_CONFIG_SOURCE_DHCP6] = "DHCPv6",
[NETWORK_CONFIG_SOURCE_DHCP_PD] = "DHCP-PD", [NETWORK_CONFIG_SOURCE_DHCP6PD] = "DHCPv6-PD",
[NETWORK_CONFIG_SOURCE_NDISC] = "NDisc", [NETWORK_CONFIG_SOURCE_NDISC] = "NDisc",
[NETWORK_CONFIG_SOURCE_RUNTIME] = "runtime", [NETWORK_CONFIG_SOURCE_RUNTIME] = "runtime",
}; };

View File

@ -25,7 +25,7 @@ typedef enum NetworkConfigSource {
NETWORK_CONFIG_SOURCE_IPV4LL, NETWORK_CONFIG_SOURCE_IPV4LL,
NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP4,
NETWORK_CONFIG_SOURCE_DHCP6, NETWORK_CONFIG_SOURCE_DHCP6,
NETWORK_CONFIG_SOURCE_DHCP_PD, NETWORK_CONFIG_SOURCE_DHCP6PD,
NETWORK_CONFIG_SOURCE_NDISC, NETWORK_CONFIG_SOURCE_NDISC,
NETWORK_CONFIG_SOURCE_RUNTIME, /* through D-Bus method */ NETWORK_CONFIG_SOURCE_RUNTIME, /* through D-Bus method */
_NETWORK_CONFIG_SOURCE_MAX, _NETWORK_CONFIG_SOURCE_MAX,

View File

@ -282,6 +282,11 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve
if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0) if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1; level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1;
/* Even if we successfully receive a reply to a request announcing support for large packets, that
* does not mean we can necessarily receive large packets. */
if (level == DNS_SERVER_FEATURE_LEVEL_LARGE)
level = DNS_SERVER_FEATURE_LEVEL_LARGE - 1;
dns_server_verified(s, level); dns_server_verified(s, level);
/* Remember the size of the largest UDP packet fragment we received from a server, we know that we /* Remember the size of the largest UDP packet fragment we received from a server, we know that we
@ -424,7 +429,7 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
* better than EDNS0, hence don't even try. */ * better than EDNS0, hence don't even try. */
if (dns_server_get_dnssec_mode(s) != DNSSEC_NO) if (dns_server_get_dnssec_mode(s) != DNSSEC_NO)
best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ? best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ?
DNS_SERVER_FEATURE_LEVEL_DO : DNS_SERVER_FEATURE_LEVEL_LARGE :
DNS_SERVER_FEATURE_LEVEL_TLS_DO; DNS_SERVER_FEATURE_LEVEL_TLS_DO;
else else
best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ? best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ?
@ -592,7 +597,7 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
} }
int dns_server_adjust_opt(DnsServer *server, DnsPacket *packet, DnsServerFeatureLevel level) { int dns_server_adjust_opt(DnsServer *server, DnsPacket *packet, DnsServerFeatureLevel level) {
size_t packet_size, udp_size; size_t packet_size;
bool edns_do; bool edns_do;
int r; int r;
@ -611,29 +616,40 @@ int dns_server_adjust_opt(DnsServer *server, DnsPacket *packet, DnsServerFeature
edns_do = level >= DNS_SERVER_FEATURE_LEVEL_DO; edns_do = level >= DNS_SERVER_FEATURE_LEVEL_DO;
udp_size = udp_header_size(server->family); if (level == DNS_SERVER_FEATURE_LEVEL_LARGE) {
size_t udp_size;
if (in_addr_is_localhost(server->family, &server->address) > 0) /* In large mode, advertise the local MTU, in order to avoid fragmentation (for security
packet_size = 65536 - udp_size; /* force linux loopback MTU if localhost address */ * reasons) except if we are talking to localhost (where the security considerations don't
else { * matter). If we see fragmentation, lower the reported size to the largest fragment, to
/* Use the MTU pointing to the server, subtract the IP/UDP header size */ * avoid it. */
packet_size = LESS_BY(dns_server_get_mtu(server), udp_size);
/* On the Internet we want to avoid fragmentation for security reasons. If we saw udp_size = udp_header_size(server->family);
* fragmented packets, the above was too large, let's clamp it to the largest
* fragment we saw */
if (server->packet_fragmented)
packet_size = MIN(server->received_udp_fragment_max, packet_size);
/* Let's not pick ridiculously large sizes, i.e. not more than 4K. No one appears if (in_addr_is_localhost(server->family, &server->address) > 0)
* to ever use such large sized on the Internet IRL, hence let's not either. */ packet_size = 65536 - udp_size; /* force linux loopback MTU if localhost address */
packet_size = MIN(packet_size, 4096U); else {
} /* Use the MTU pointing to the server, subtract the IP/UDP header size */
packet_size = LESS_BY(dns_server_get_mtu(server), udp_size);
/* Strictly speaking we quite possibly can receive larger datagrams than the MTU (since the /* On the Internet we want to avoid fragmentation for security reasons. If we saw
* MTU is for egress, not for ingress), but more often than not the value is symmetric, and * fragmented packets, the above was too large, let's clamp it to the largest
* we want something that does the right thing in the majority of cases, and not just in the * fragment we saw */
* theoretical edge case. */ if (server->packet_fragmented)
packet_size = MIN(server->received_udp_fragment_max, packet_size);
/* Let's not pick ridiculously large sizes, i.e. not more than 4K. No one appears
* to ever use such large sized on the Internet IRL, hence let's not either. */
packet_size = MIN(packet_size, 4096U);
}
/* Strictly speaking we quite possibly can receive larger datagrams than the MTU (since the
* MTU is for egress, not for ingress), but more often than not the value is symmetric, and
* we want something that does the right thing in the majority of cases, and not just in the
* theoretical edge case. */
} else
/* In non-large mode, let's advertise the size of the largest fragment we ever managed to accept. */
packet_size = server->received_udp_fragment_max;
/* Safety clamp, never advertise less than 512 or more than 65535 */ /* Safety clamp, never advertise less than 512 or more than 65535 */
packet_size = CLAMP(packet_size, packet_size = CLAMP(packet_size,
@ -1081,6 +1097,7 @@ static const char* const dns_server_feature_level_table[_DNS_SERVER_FEATURE_LEVE
[DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0", [DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
[DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN] = "TLS+EDNS0", [DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN] = "TLS+EDNS0",
[DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO", [DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
[DNS_SERVER_FEATURE_LEVEL_LARGE] = "UDP+EDNS0+DO+LARGE",
[DNS_SERVER_FEATURE_LEVEL_TLS_DO] = "TLS+EDNS0+D0", [DNS_SERVER_FEATURE_LEVEL_TLS_DO] = "TLS+EDNS0+D0",
}; };
DEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel); DEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);

View File

@ -32,6 +32,7 @@ typedef enum DnsServerFeatureLevel {
DNS_SERVER_FEATURE_LEVEL_EDNS0, DNS_SERVER_FEATURE_LEVEL_EDNS0,
DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN, DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN,
DNS_SERVER_FEATURE_LEVEL_DO, DNS_SERVER_FEATURE_LEVEL_DO,
DNS_SERVER_FEATURE_LEVEL_LARGE,
DNS_SERVER_FEATURE_LEVEL_TLS_DO, DNS_SERVER_FEATURE_LEVEL_TLS_DO,
_DNS_SERVER_FEATURE_LEVEL_MAX, _DNS_SERVER_FEATURE_LEVEL_MAX,
_DNS_SERVER_FEATURE_LEVEL_INVALID = -EINVAL, _DNS_SERVER_FEATURE_LEVEL_INVALID = -EINVAL,
@ -42,7 +43,7 @@ typedef enum DnsServerFeatureLevel {
#define DNS_SERVER_FEATURE_LEVEL_IS_EDNS0(x) ((x) >= DNS_SERVER_FEATURE_LEVEL_EDNS0) #define DNS_SERVER_FEATURE_LEVEL_IS_EDNS0(x) ((x) >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
#define DNS_SERVER_FEATURE_LEVEL_IS_TLS(x) IN_SET(x, DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN, DNS_SERVER_FEATURE_LEVEL_TLS_DO) #define DNS_SERVER_FEATURE_LEVEL_IS_TLS(x) IN_SET(x, DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN, DNS_SERVER_FEATURE_LEVEL_TLS_DO)
#define DNS_SERVER_FEATURE_LEVEL_IS_DNSSEC(x) ((x) >= DNS_SERVER_FEATURE_LEVEL_DO) #define DNS_SERVER_FEATURE_LEVEL_IS_DNSSEC(x) ((x) >= DNS_SERVER_FEATURE_LEVEL_DO)
#define DNS_SERVER_FEATURE_LEVEL_IS_UDP(x) IN_SET(x, DNS_SERVER_FEATURE_LEVEL_UDP, DNS_SERVER_FEATURE_LEVEL_EDNS0, DNS_SERVER_FEATURE_LEVEL_DO) #define DNS_SERVER_FEATURE_LEVEL_IS_UDP(x) IN_SET(x, DNS_SERVER_FEATURE_LEVEL_UDP, DNS_SERVER_FEATURE_LEVEL_EDNS0, DNS_SERVER_FEATURE_LEVEL_DO, DNS_SERVER_FEATURE_LEVEL_LARGE)
const char* dns_server_feature_level_to_string(int i) _const_; const char* dns_server_feature_level_to_string(int i) _const_;
int dns_server_feature_level_from_string(const char *s) _pure_; int dns_server_feature_level_from_string(const char *s) _pure_;

View File

@ -97,7 +97,6 @@ enum {
SD_DHCP_OPTION_SIP_SERVER = 120, SD_DHCP_OPTION_SIP_SERVER = 120,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_MUD_URL = 161, SD_DHCP_OPTION_MUD_URL = 161,
SD_DHCP_OPTION_6RD = 212,
SD_DHCP_OPTION_PRIVATE_BASE = 224, SD_DHCP_OPTION_PRIVATE_BASE = 224,
/* Windows 10 option to send when Anonymize=true */ /* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249, SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249,

View File

@ -71,13 +71,6 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len); int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len);
int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len); int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len);
int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone);
int sd_dhcp_lease_get_6rd(
sd_dhcp_lease *lease,
uint8_t *ret_ipv4masklen,
uint8_t *ret_prefixlen,
struct in6_addr *ret_prefix,
const struct in_addr **ret_br_addresses,
size_t *ret_n_br_addresses);
int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination); int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination);
int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length); int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length);

View File

@ -128,7 +128,6 @@ SendDecline=
MUDURL= MUDURL=
RouteMTUBytes= RouteMTUBytes=
FallbackLeaseLifetimeSec= FallbackLeaseLifetimeSec=
Use6RD=
[DHCPv6] [DHCPv6]
UseAddress= UseAddress=
UseDelegatedPrefix= UseDelegatedPrefix=
@ -150,14 +149,8 @@ RouteMetric=
IAID= IAID=
DUIDType= DUIDType=
DUIDRawData= DUIDRawData=
RouteTable=
[DHCPv6PrefixDelegation] [DHCPv6PrefixDelegation]
SubnetId=
Announce=
Assign=
ManageTemporaryAddress=
Token=
RouteMetric=
[DHCPPrefixDelegation]
UplinkInterface= UplinkInterface=
SubnetId= SubnetId=
Announce= Announce=
@ -248,7 +241,6 @@ VRF=
IgnoreCarrierLoss= IgnoreCarrierLoss=
KeepConfiguration= KeepConfiguration=
DHCPv6PrefixDelegation= DHCPv6PrefixDelegation=
DHCPPrefixDelegation=
BatmanAdvanced= BatmanAdvanced=
IPoIB= IPoIB=
[IPv6Prefix] [IPv6Prefix]

View File

@ -1,18 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This network file matches 6rd-* SIT devices which is automatically created by
# systemd-networkd when DHCPv4 6RD option is received.
[Match]
Name=6rd-*
Type=sit
[Network]
DHCPPrefixDelegation=yes

View File

@ -1,7 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Name=veth-peer
[Network]
IPv6AcceptRA=no
Address=10.0.0.1/8

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Name=veth99
[Network]
IPv6PrivacyExtensions=yes
IPv6AcceptRA=no
DHCP=ipv4
DHCPPrefixDelegation=yes
[DHCPv4]
Use6RD=yes
[DHCPPrefixDelegation]
UplinkInterface=:self
SubnetId=10
Announce=no
Token=eui64
Token=::1a:2b:3c:4d

View File

@ -6,9 +6,9 @@ Name=dummy97
IPv6PrivacyExtensions=yes IPv6PrivacyExtensions=yes
IPv6AcceptRA=no IPv6AcceptRA=no
DHCP=no DHCP=no
DHCPPrefixDelegation=yes DHCPv6PrefixDelegation=yes
[DHCPPrefixDelegation] [DHCPv6PrefixDelegation]
UplinkInterface=veth99 UplinkInterface=veth99
SubnetId=1 SubnetId=1
Announce=no Announce=no

View File

@ -6,9 +6,9 @@ Name=dummy98
IPv6PrivacyExtensions=yes IPv6PrivacyExtensions=yes
IPv6AcceptRA=no IPv6AcceptRA=no
DHCP=no DHCP=no
DHCPPrefixDelegation=yes DHCPv6PrefixDelegation=yes
[DHCPPrefixDelegation] [DHCPv6PrefixDelegation]
UplinkInterface=veth99 UplinkInterface=veth99
SubnetId=2 SubnetId=2
Announce=no Announce=no

View File

@ -6,9 +6,9 @@ Name=dummy99
IPv6PrivacyExtensions=yes IPv6PrivacyExtensions=yes
IPv6AcceptRA=no IPv6AcceptRA=no
DHCP=no DHCP=no
DHCPPrefixDelegation=yes DHCPv6PrefixDelegation=yes
[DHCPPrefixDelegation] [DHCPv6PrefixDelegation]
UplinkInterface=veth99 UplinkInterface=veth99
Assign=no Assign=no
Announce=no Announce=no

View File

@ -6,9 +6,9 @@ Name=test1
IPv6PrivacyExtensions=yes IPv6PrivacyExtensions=yes
IPv6AcceptRA=no IPv6AcceptRA=no
DHCP=no DHCP=no
DHCPPrefixDelegation=yes DHCPv6PrefixDelegation=yes
[DHCPPrefixDelegation] [DHCPv6PrefixDelegation]
UplinkInterface=veth99 UplinkInterface=veth99
SubnetId=0 SubnetId=0
Announce=no Announce=no

View File

@ -6,10 +6,10 @@ Name=veth97
IPv6PrivacyExtensions=yes IPv6PrivacyExtensions=yes
IPv6AcceptRA=no IPv6AcceptRA=no
DHCP=no DHCP=no
DHCPPrefixDelegation=yes DHCPv6PrefixDelegation=yes
IPv6SendRA=yes IPv6SendRA=yes
[DHCPPrefixDelegation] [DHCPv6PrefixDelegation]
SubnetId=8 SubnetId=8
Announce=yes Announce=yes
Token=eui64 Token=eui64

View File

@ -6,10 +6,10 @@ Name=veth98
IPv6PrivacyExtensions=yes IPv6PrivacyExtensions=yes
IPv6AcceptRA=no IPv6AcceptRA=no
DHCP=no DHCP=no
DHCPPrefixDelegation=yes DHCPv6PrefixDelegation=yes
IPv6SendRA=yes IPv6SendRA=yes
[DHCPPrefixDelegation] [DHCPv6PrefixDelegation]
UplinkInterface=veth99 UplinkInterface=veth99
SubnetId=9 SubnetId=9
Announce=yes Announce=yes

View File

@ -6,12 +6,12 @@ Name=veth99
IPv6PrivacyExtensions=yes IPv6PrivacyExtensions=yes
IPv6AcceptRA=no IPv6AcceptRA=no
DHCP=ipv6 DHCP=ipv6
DHCPPrefixDelegation=yes DHCPv6PrefixDelegation=yes
[DHCPv6] [DHCPv6]
WithoutRA=solicit WithoutRA=solicit
[DHCPPrefixDelegation] [DHCPv6PrefixDelegation]
UplinkInterface=:self UplinkInterface=:self
SubnetId=10 SubnetId=10
Announce=no Announce=no

View File

@ -1,22 +0,0 @@
default-lease-time 2592000;
preferred-lifetime 604800;
default-lease-time 600;
max-lease-time 7200;
option domain-name-servers 10.0.0.2;
option domain-search "test.example.com","example.com";
# ipv4masklen = 8
# 6rd prefix = 2001:db8::/32
# BR address = 10.0.0.1
option option-6rd code 212 = {
integer 8, integer 8, ip6-address, array of ip-address
};
option option-6rd 8 32 2001:db8:: 10.0.0.1;
subnet 10.0.0.0 netmask 255.0.0.0 {
# Addresses available to clients
range 10.100.100.100 10.100.100.199;
}

View File

@ -4994,7 +4994,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
class NetworkdDHCPPDTests(unittest.TestCase, Utilities): class NetworkdDHCP6PDTests(unittest.TestCase, Utilities):
links = [ links = [
'dummy97', 'dummy97',
'dummy98', 'dummy98',
@ -5012,17 +5012,14 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
'25-veth.netdev', '25-veth.netdev',
'25-veth-downstream-veth97.netdev', '25-veth-downstream-veth97.netdev',
'25-veth-downstream-veth98.netdev', '25-veth-downstream-veth98.netdev',
'80-6rd-tunnel.network', 'dhcp6pd-downstream-dummy97.network',
'dhcp-pd-downstream-dummy97.network', 'dhcp6pd-downstream-dummy98.network',
'dhcp-pd-downstream-dummy98.network', 'dhcp6pd-downstream-dummy99.network',
'dhcp-pd-downstream-dummy99.network', 'dhcp6pd-downstream-test1.network',
'dhcp-pd-downstream-test1.network', 'dhcp6pd-downstream-veth97.network',
'dhcp-pd-downstream-veth97.network', 'dhcp6pd-downstream-veth97-peer.network',
'dhcp-pd-downstream-veth97-peer.network', 'dhcp6pd-downstream-veth98.network',
'dhcp-pd-downstream-veth98.network', 'dhcp6pd-downstream-veth98-peer.network',
'dhcp-pd-downstream-veth98-peer.network',
'dhcp4-6rd-server.network',
'dhcp4-6rd-upstream.network',
'dhcp6pd-server.network', 'dhcp6pd-server.network',
'dhcp6pd-upstream.network', 'dhcp6pd-upstream.network',
] ]
@ -5040,12 +5037,12 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
def test_dhcp6pd(self): def test_dhcp6pd(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp6pd-server.network', 'dhcp6pd-upstream.network', copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp6pd-server.network', 'dhcp6pd-upstream.network',
'25-veth-downstream-veth97.netdev', 'dhcp-pd-downstream-veth97.network', 'dhcp-pd-downstream-veth97-peer.network', '25-veth-downstream-veth97.netdev', 'dhcp6pd-downstream-veth97.network', 'dhcp6pd-downstream-veth97-peer.network',
'25-veth-downstream-veth98.netdev', 'dhcp-pd-downstream-veth98.network', 'dhcp-pd-downstream-veth98-peer.network', '25-veth-downstream-veth98.netdev', 'dhcp6pd-downstream-veth98.network', 'dhcp6pd-downstream-veth98-peer.network',
'11-dummy.netdev', 'dhcp-pd-downstream-test1.network', '11-dummy.netdev', 'dhcp6pd-downstream-test1.network',
'dhcp-pd-downstream-dummy97.network', 'dhcp6pd-downstream-dummy97.network',
'12-dummy.netdev', 'dhcp-pd-downstream-dummy98.network', '12-dummy.netdev', 'dhcp6pd-downstream-dummy98.network',
'13-dummy.netdev', 'dhcp-pd-downstream-dummy99.network') '13-dummy.netdev', 'dhcp6pd-downstream-dummy99.network')
start_networkd() start_networkd()
self.wait_online(['veth-peer:routable']) self.wait_online(['veth-peer:routable'])
@ -5066,7 +5063,7 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
dummy99: auto -> 0x03 (No address assignment) dummy99: auto -> 0x03 (No address assignment)
veth97: 0x08 veth97: 0x08
veth98: 0x09 veth98: 0x09
veth99: 0x10 (ignored, as it is upstream) veth99: 0x10
''' '''
print('### ip -6 address show dev veth99 scope global') print('### ip -6 address show dev veth99 scope global')
@ -5075,9 +5072,12 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
# IA_NA # IA_NA
self.assertRegex(output, 'inet6 3ffe:501:ffff:100::[0-9]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)') self.assertRegex(output, 'inet6 3ffe:501:ffff:100::[0-9]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
# address in IA_PD (Token=static) # address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/56 (metric 256 |)scope global dynamic') self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (Token=eui64) # address in IA_PD (Token=eui64)
self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1034:56ff:fe78:9abc/56 (metric 256 |)scope global dynamic') self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]10:1034:56ff:fe78:9abc/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
# Note that the temporary addresses may appear after the link enters configured state
self.wait_address('veth99', 'inet6 3ffe:501:ffff:[2-9a-f]10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev test1 scope global') print('### ip -6 address show dev test1 scope global')
output = check_output('ip -6 address show dev test1 scope global') output = check_output('ip -6 address show dev test1 scope global')
@ -5085,7 +5085,6 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
# address in IA_PD (Token=static) # address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary) # address in IA_PD (temporary)
# Note that the temporary addresses may appear after the link enters configured state
self.wait_address('test1', 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6') self.wait_address('test1', 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev dummy98 scope global') print('### ip -6 address show dev dummy98 scope global')
@ -5150,7 +5149,7 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
print('### ip -6 route show dev veth99') print('### ip -6 route show dev veth99')
output = check_output('ip -6 route show dev veth99') output = check_output('ip -6 route show dev veth99')
print(output) print(output)
self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]00::/56 proto kernel metric [0-9]* expires') self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]10::/64 proto kernel metric [0-9]* expires')
print('### ip -6 route show dev test1') print('### ip -6 route show dev test1')
output = check_output('ip -6 route show dev test1') output = check_output('ip -6 route show dev test1')
@ -5232,242 +5231,6 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]03::/64 proto dhcp metric [0-9]* expires') self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]03::/64 proto dhcp metric [0-9]* expires')
def test_dhcp4_6rd(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp4-6rd-server.network', 'dhcp4-6rd-upstream.network',
'25-veth-downstream-veth97.netdev', 'dhcp-pd-downstream-veth97.network', 'dhcp-pd-downstream-veth97-peer.network',
'25-veth-downstream-veth98.netdev', 'dhcp-pd-downstream-veth98.network', 'dhcp-pd-downstream-veth98-peer.network',
'11-dummy.netdev', 'dhcp-pd-downstream-test1.network',
'dhcp-pd-downstream-dummy97.network',
'12-dummy.netdev', 'dhcp-pd-downstream-dummy98.network',
'13-dummy.netdev', 'dhcp-pd-downstream-dummy99.network',
'80-6rd-tunnel.network')
start_networkd()
self.wait_online(['veth-peer:routable'])
start_isc_dhcpd('veth-peer', 'isc-dhcpd-6rd.conf', ip='-4')
self.wait_online(['veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded',
'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable'])
print('### ip -4 address show dev veth-peer scope global')
output = check_output('ip -4 address show dev veth-peer scope global')
print(output)
self.assertIn('inet 10.0.0.1/8 brd 10.255.255.255 scope global veth-peer', output)
'''
Link Subnet IDs
test1: 0x00
dummy97: 0x01 (The link will appear later)
dummy98: 0x02
dummy99: auto -> 0x03 (No address assignment)
veth97: 0x08
veth98: 0x09
veth99: 0x10
'''
print('### ip -4 address show dev veth99 scope global')
output = check_output('ip -4 address show dev veth99 scope global')
print(output)
self.assertRegex(output, 'inet 10.100.100.[0-9]*/8 (metric 1024 |)brd 10.255.255.255 scope global dynamic veth99')
print('### ip -6 address show dev veth99 scope global')
output = check_output('ip -6 address show dev veth99 scope global')
print(output)
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (Token=eui64)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1034:56ff:fe78:9abc/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
# Note that the temporary addresses may appear after the link enters configured state
self.wait_address('veth99', 'inet6 2001:db8:6464:[0-9a-f]+10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev test1 scope global')
output = check_output('ip -6 address show dev test1 scope global')
print(output)
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
self.wait_address('test1', 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev dummy98 scope global')
output = check_output('ip -6 address show dev dummy98 scope global')
print(output)
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+02:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
self.wait_address('dummy98', 'inet6 2001:db8:6464:[0-9a-f]+02:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev dummy99 scope global')
output = check_output('ip -6 address show dev dummy99 scope global')
print(output)
# Assign=no
self.assertNotRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+03')
print('### ip -6 address show dev veth97 scope global')
output = check_output('ip -6 address show dev veth97 scope global')
print(output)
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (Token=eui64)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9ace/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
self.wait_address('veth97', 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev veth97-peer scope global')
output = check_output('ip -6 address show dev veth97-peer scope global')
print(output)
# NDisc address (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
# NDisc address (Token=eui64)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9acf/64 (metric 256 |)scope global dynamic mngtmpaddr')
# NDisc address (temporary)
self.wait_address('veth97-peer', 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev veth98 scope global')
output = check_output('ip -6 address show dev veth98 scope global')
print(output)
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (Token=eui64)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abe/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
self.wait_address('veth98', 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev veth98-peer scope global')
output = check_output('ip -6 address show dev veth98-peer scope global')
print(output)
# NDisc address (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
# NDisc address (Token=eui64)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abf/64 (metric 256 |)scope global dynamic mngtmpaddr')
# NDisc address (temporary)
self.wait_address('veth98-peer', 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 route show type unreachable')
output = check_output('ip -6 route show type unreachable')
print(output)
self.assertRegex(output, 'unreachable 2001:db8:6464:[0-9a-f]+00::/56 dev lo proto dhcp')
print('### ip -6 route show dev veth99')
output = check_output('ip -6 route show dev veth99')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+10::/64 proto kernel metric [0-9]* expires')
print('### ip -6 route show dev test1')
output = check_output('ip -6 route show dev test1')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+00::/64 proto kernel metric [0-9]* expires')
print('### ip -6 route show dev dummy98')
output = check_output('ip -6 route show dev dummy98')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+02::/64 proto kernel metric [0-9]* expires')
print('### ip -6 route show dev dummy99')
output = check_output('ip -6 route show dev dummy99')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+03::/64 proto dhcp metric [0-9]* expires')
print('### ip -6 route show dev veth97')
output = check_output('ip -6 route show dev veth97')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+08::/64 proto kernel metric [0-9]* expires')
print('### ip -6 route show dev veth97-peer')
output = check_output('ip -6 route show dev veth97-peer')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+08::/64 proto ra metric [0-9]* expires')
print('### ip -6 route show dev veth98')
output = check_output('ip -6 route show dev veth98')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+09::/64 proto kernel metric [0-9]* expires')
print('### ip -6 route show dev veth98-peer')
output = check_output('ip -6 route show dev veth98-peer')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+09::/64 proto ra metric [0-9]* expires')
# Test case for a downstream which appears later
check_output('ip link add dummy97 type dummy')
self.wait_online(['dummy97:routable'])
print('### ip -6 address show dev dummy97 scope global')
output = check_output('ip -6 address show dev dummy97 scope global')
print(output)
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+01:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
self.wait_address('dummy97', 'inet6 2001:db8:6464:[0-9a-f]+01:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 route show dev dummy97')
output = check_output('ip -6 route show dev dummy97')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+01::/64 proto kernel metric [0-9]* expires')
# Test case for reconfigure
check_output(*networkctl_cmd, 'reconfigure', 'dummy98', 'dummy99', env=env)
self.wait_online(['dummy98:routable'])
print('### ip -6 address show dev dummy98 scope global')
output = check_output('ip -6 address show dev dummy98 scope global')
print(output)
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+02:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
# address in IA_PD (temporary)
self.wait_address('dummy98', 'inet6 2001:db8:6464:[0-9a-f]+02:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
print('### ip -6 address show dev dummy99 scope global')
output = check_output('ip -6 address show dev dummy99 scope global')
print(output)
# Assign=no
self.assertNotRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+03')
print('### ip -6 route show dev dummy98')
output = check_output('ip -6 route show dev dummy98')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+02::/64 proto kernel metric [0-9]* expires')
print('### ip -6 route show dev dummy99')
output = check_output('ip -6 route show dev dummy99')
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+03::/64 proto dhcp metric [0-9]* expires')
tunnel_name = None
for name in os.listdir('/sys/class/net/'):
if name.startswith('6rd-'):
tunnel_name = name
break
self.wait_online(['{}:routable'.format(tunnel_name)])
print('### ip -d link show dev {}'.format(tunnel_name))
output = check_output('ip -d link show dev {}'.format(tunnel_name))
print(output)
self.assertIn('link/sit 10.100.100.', output)
self.assertIn('local 10.100.100.', output)
self.assertIn('dev veth99', output)
self.assertIn('ttl 64', output)
self.assertIn('6rd-prefix 2001:db8::/32', output)
self.assertIn('6rd-relay_prefix 10.0.0.0/8', output)
print('### ip -6 address show dev {}'.format(tunnel_name))
output = check_output('ip -6 address show dev {}'.format(tunnel_name))
print(output)
self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/56 (metric 256 |)scope global dynamic')
self.assertRegex(output, 'inet6 ::10.100.100.[0-9]+/96 scope global')
print('### ip -6 route show dev {}'.format(tunnel_name))
output = check_output('ip -6 route show dev {}'.format(tunnel_name))
print(output)
self.assertRegex(output, '2001:db8:6464:[0-9a-f]+00::/56 proto kernel metric [0-9]* expires')
self.assertRegex(output, '::/96 proto kernel metric [0-9]*')
print('### ip -6 route show default')
output = check_output('ip -6 route show default')
print(output)
self.assertIn('default', output)
self.assertIn('via ::10.0.0.1 dev {}'.format(tunnel_name), output)
class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities): class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
links = [ links = [
'dummy98', 'dummy98',

128
tools/build-bpf-skel.py Executable file
View File

@ -0,0 +1,128 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
import argparse
import logging
import pathlib
import re
import subprocess
import sys
def clang_arch_flag(arch):
return '-D__{}__'.format(arch)
def target_triplet():
gcc_exec = 'gcc'
try:
return subprocess.check_output([gcc_exec, '-dumpmachine'],
universal_newlines=True).strip()
except subprocess.CalledProcessError as e:
logging.error('Failed to get target triplet: {}'.format(e))
except FileNotFoundError:
logging.error('gcc not installed')
return None
def clang_compile(clang_exec, clang_flags, src_c, out_file, target_arch,
target_triplet):
clang_args = [clang_exec, *clang_flags, target_arch, '-I.']
if target_triplet:
clang_args += [
'-isystem',
'/usr/include/{}'.format(target_triplet)]
clang_args += [
'-idirafter',
'/usr/local/include',
'-idirafter',
'/usr/include']
clang_args += [src_c, '-o', out_file]
logging.debug('{}'.format(' '.join(clang_args)))
subprocess.check_call(clang_args)
def llvm_strip(llvm_strip_exec, in_file):
llvm_strip_args = [llvm_strip_exec, '-g', in_file]
logging.debug('Stripping useless DWARF info:')
logging.debug('{}'.format(' '.join(llvm_strip_args)))
subprocess.check_call(llvm_strip_args)
def gen_bpf_skeleton(bpftool_exec, in_file, out_fd):
bpftool_args = [bpftool_exec, 'g', 's', in_file]
logging.debug('Generating BPF skeleton:')
logging.debug('{}'.format(' '.join(bpftool_args)))
skel = subprocess.check_output(bpftool_args, universal_newlines=True)
# libbpf is used via dlopen(), so rename symbols as defined
# in src/shared/bpf-dlopen.h
skel = re.sub(r'(bpf_object__\w+_skeleton)', r'sym_\1', skel)
out_fd.write(skel)
def bpf_build(args):
clang_flags = [
'-Wno-compare-distinct-pointer-types',
'-O2',
'-target',
'bpf',
'-g',
'-c',
]
clang_out_path = pathlib.Path(args.bpf_src_c).with_suffix('.o')
with clang_out_path.open(mode='w') as clang_out, \
open(args.bpf_skel_h, mode='w') as bpf_skel_h:
clang_compile(clang_exec=args.clang_exec,
clang_flags=clang_flags,
src_c=args.bpf_src_c,
out_file=clang_out.name,
target_arch=clang_arch_flag(args.arch),
target_triplet=target_triplet())
llvm_strip(llvm_strip_exec=args.llvm_strip_exec, in_file=clang_out.name)
gen_bpf_skeleton(bpftool_exec=args.bpftool_exec,
in_file=clang_out.name,
out_fd=bpf_skel_h)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'bpf_src_c',
help='Path to *.c source of BPF program in systemd source tree \
relative to the work directory')
parser.add_argument(
'bpf_skel_h',
help='Path to C header file')
parser.add_argument(
'--clang_exec',
help='Path to clang exec')
parser.add_argument(
'--llvm_strip_exec',
help='Path to llvm-strip exec')
parser.add_argument(
'--bpftool_exec',
help='Path to bpftool exec')
parser.add_argument(
'--arch',
help='Target CPU architecture',
default='x86_64')
args = parser.parse_args();
logging.basicConfig(stream=sys.stderr, level=logging.WARNING)
bpf_build(args)