Compare commits
20 Commits
838d39af93
...
a68da22257
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | a68da22257 | |
Yu Watanabe | c03ef420fa | |
hadess | 25b67032a8 | |
Zbigniew Jędrzejewski-Szmek | cc832f9772 | |
Zbigniew Jędrzejewski-Szmek | 63b7e7b4ba | |
Yu Watanabe | cbdf02952e | |
Yu Watanabe | 1447dc625a | |
Jiri Slaby | 74986a0f88 | |
Zbigniew Jędrzejewski-Szmek | 52e085af82 | |
Yu Watanabe | 13adf35343 | |
Yu Watanabe | 5e958e1d6c | |
Yu Watanabe | 1a6c913676 | |
Yu Watanabe | 7fa69c0a6f | |
Zbigniew Jędrzejewski-Szmek | 15e6a6e87b | |
Zbigniew Jędrzejewski-Szmek | 37b22b3b47 | |
Yu Watanabe | 3d2c26925f | |
Yu Watanabe | c3a5025dc6 | |
Yu Watanabe | e64b31c848 | |
Susant Sahani | 518cd6b527 | |
Susant Sahani | 5908ddd763 |
12
NEWS
12
NEWS
|
@ -178,12 +178,12 @@ CHANGES WITH 246 in spe:
|
|||
traffic). DataBitRate=, DataSamplePoint=, FDMode=, FDNonISO= have
|
||||
been added to configure various CAN-FD aspects.
|
||||
|
||||
* systemd-networkd's [DHCPv6] section gained a new WithoutRA= boolean
|
||||
setting. If enabled, DHCPv6 will be attempted right-away without
|
||||
requiring an Router Advertisement packet suggesting it
|
||||
first. Conversely, the [IPv6AcceptRA] gained a boolean option
|
||||
DHCPv6Client= that may be used to turn off the DHCPv6 client even if
|
||||
the RA packets suggest it.
|
||||
* systemd-networkd's [DHCPv6] section gained a new boolean option
|
||||
WithoutRA=. When enabled, DHCPv6 will be attempted right-away without
|
||||
requiring an Router Advertisement packet suggesting it first
|
||||
(i.e. without the 'M' or 'O' flags set). The [IPv6AcceptRA] section
|
||||
gained a boolean option DHCPv6Client= that may be used to turn off
|
||||
the DHCPv6 client even if the RA packets suggest it.
|
||||
|
||||
* systemd-networkd's [DHCPv4] section gained a new setting UseGateway=
|
||||
which may be used to turn off use of the gateway information provided
|
||||
|
|
|
@ -47,7 +47,7 @@ functionality. Here's why we think that it is not enough for our uses:
|
|||
|
||||
* The various EFI implementations implement the boot order/boot item logic to different levels. Some firmware implementations do not offer a boot menu at all and instead unconditionally follow the EFI boot order, booting the first item that is working.
|
||||
* If the firmware setup is used to reset all data usually all EFI boot entries are lost, making the system entirely unbootable, as the firmware setups generally do not offer a UI to define additional boot items. By placing the menu item information on disk, it is always available, regardless if the BIOS setup data is lost.
|
||||
* Harddisk images should be moveable between machines and be bootable without requiring explicit EFI variables to be set. This also requires that the list of boot options is defined on disk, and not in EFI variables alone.
|
||||
* Harddisk images should be movable between machines and be bootable without requiring explicit EFI variables to be set. This also requires that the list of boot options is defined on disk, and not in EFI variables alone.
|
||||
* EFI is not universal yet (especially on non-x86 platforms), this specification is useful both for EFI and non-EFI boot loaders.
|
||||
* Many EFI systems disable USB support during early boot to optimize boot times, thus making keyboard input unavailable in the EFI menu. It is thus useful if the OS UI has a standardized way to discover available boot options which can be booted to.
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ medium. (Moreover it allows to embed additional partitions later on, for
|
|||
example for allowing a multi-purpose USB stick that contains both a home
|
||||
directory and a generic storage volume.)
|
||||
|
||||
Rationale for including the encrypted user record in the the LUKS2 header:
|
||||
Rationale for including the encrypted user record in the LUKS2 header:
|
||||
Linux kernel file system implementations are generally not robust towards
|
||||
maliciously formatted file systems; there's a good chance that file system
|
||||
images can be used as attack vectors, exploiting the kernel. Thus it is
|
||||
|
|
|
@ -36,7 +36,7 @@ interfaces are currently used by dracut and the ArchLinux initrds.
|
|||
optionally followed (in `argv[2]`, `argv[3]`, … systemd's original command
|
||||
line options, for example `--log-level=` and similar.
|
||||
|
||||
* Storage daemons run from the initrd should follow the the guide on [systemd
|
||||
* Storage daemons run from the initrd should follow the guide on [systemd
|
||||
and Storage Daemons for the Root File
|
||||
System](https://systemd.io/ROOT_STORAGE_DAEMONS) to survive properly from the
|
||||
boot initrd all the way to the point where systemd jumps back into the initrd
|
||||
|
|
|
@ -212,10 +212,10 @@ boot, in order to ensure the entropy pool is filled up quickly.
|
|||
random-seed`](https://www.freedesktop.org/software/systemd/man/bootctl.html#random-seed))
|
||||
a seed file with an initial seed is placed in a file `/loader/random-seed`
|
||||
in the ESP. In addition, an identically sized randomized EFI variable called
|
||||
the the 'system token' is set, which is written to the machine's firmware
|
||||
NVRAM. During boot, when `systemd-boot` finds both the random seed file and
|
||||
the system token they are combined and hashed with SHA256 (in counter mode,
|
||||
to generate sufficient data), to generate a new random seed file to store in
|
||||
the 'system token' is set, which is written to the machine's firmware NVRAM.
|
||||
During boot, when `systemd-boot` finds both the random seed file and the
|
||||
system token they are combined and hashed with SHA256 (in counter mode, to
|
||||
generate sufficient data), to generate a new random seed file to store in
|
||||
the ESP as well as a random seed to pass to the OS kernel. The new random
|
||||
seed file for the ESP is then written to the ESP, ensuring this is completed
|
||||
before the OS is invoked. Very early during initialization PID 1 will read
|
||||
|
|
|
@ -689,6 +689,9 @@ sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnPRIMEBOOKC11B:*
|
|||
#########################################
|
||||
# Umax
|
||||
#########################################
|
||||
sensor:modalias:acpi:KIOX000A*:dmi:*:svnUMAX:pnVisionBook10WiPro:*
|
||||
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
|
||||
|
||||
sensor:modalias:acpi:SMO8500*:dmi:*:svnUMAX:pnVisionBook10WiPlus:*
|
||||
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
|
||||
|
||||
|
|
|
@ -401,7 +401,7 @@
|
|||
<option>--password-change-min=</option> configures how much time has to pass after changing the
|
||||
password of the user until the password may be changed again. If the user tries to change their
|
||||
password before this time passes the attempt is refused. <option>--password-change-max=</option>
|
||||
configures how much time has to pass after the the password is changed until the password expires and
|
||||
configures how much time has to pass after the password is changed until the password expires and
|
||||
needs to be changed again. After this time passes any attempts to log in may only proceed after the
|
||||
password is changed. <option>--password-change-warn=</option> specifies how much earlier than then
|
||||
the time configured with <option>--password-change-max=</option> the user is warned at login to
|
||||
|
|
|
@ -83,7 +83,7 @@ node /org/freedesktop/LogControl1 {
|
|||
<para><varname>LogTarget</varname> describes the log target (mechanism). It should be one of
|
||||
<literal>console</literal> (log to the console or standard output),
|
||||
<literal>kmsg</literal> (log to the kernel ring buffer),
|
||||
<literal>journal</literal> (log the the journal natively, see
|
||||
<literal>journal</literal> (log to the journal natively, see
|
||||
<citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>),
|
||||
<literal>syslog</literal> (log using the
|
||||
<citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call).
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
<para><function>sd_hwdb_get()</function> queries the <parameter>hwdb</parameter> object created earlier
|
||||
with <citerefentry><refentrytitle>sd_hwdb_new</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
|
||||
entries matching the specified string <parameter>modalias</parameter>, and returns the value
|
||||
corresponding to the the key <parameter>key</parameter>. The value is returned as a
|
||||
corresponding to the key <parameter>key</parameter>. The value is returned as a
|
||||
<constant>NUL</constant>-terminated string in <parameter>value</parameter>. It must not be modified by
|
||||
the caller and is valid as long as a reference to <parameter>hwdb</parameter> is kept. When multiple
|
||||
patterns in the database match <parameter>modalias</parameter>, the one with the highest priority is
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<para>Configuration files are read from directories in <filename>/etc/</filename>,
|
||||
<filename>/run/</filename>, <filename>/usr/local/lib/</filename>, and <filename>/usr/lib/</filename>, in
|
||||
order of precedence, as listed in the SYNOPSIS section above. Files must have the the
|
||||
order of precedence, as listed in the SYNOPSIS section above. Files must have the
|
||||
<literal>.conf</literal> extension. Files in <filename>/etc/</filename> override files with the same name
|
||||
in <filename>/run/</filename>, <filename>/usr/local/lib/</filename>, and
|
||||
<filename>/usr/lib/</filename>. Files in <filename>/run/</filename> override files with the same name
|
||||
|
|
|
@ -237,6 +237,93 @@
|
|||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[SR-IOV] Section Options</title>
|
||||
<para>The <literal>[SR-IOV]</literal> section accepts the
|
||||
following keys. Specify several <literal>[SR-IOV]</literal>
|
||||
sections to configure several SR-IOVs. SR-IOV provides the ability to partition a single physical PCI resource
|
||||
into virtual PCI functions which can then be injected into a VM. In the case of network VFs, SR-IOV improves
|
||||
north-south network performance (that is, traffic with endpoints outside the host machine) by allowing traffic to
|
||||
bypass the host machine’s network stack.</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>VirtualFunction=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies a Virtual Function (VF), lightweight PCIe function designed solely to move data
|
||||
in and out. Takes an unsigned integer in the range 0..2147483646. This option is compulsory.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>VLANId=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies VLAN ID of the virtual function. Takes an unsigned integer in the range 1..4095.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>QualityOfService=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies quality of service of the virtual function. Takes an unsigned integer in the range 1..4294967294.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>VLANProtocol=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies VLAN protocol of the virtual function. Takes <literal>802.1Q</literal> or
|
||||
<literal>802.1ad</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>MACSpoofCheck=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a boolean. Controls the MAC spoof checking. When unset, the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>QueryReceiveSideScaling=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a boolean. Toggle the ability of querying the receive side scaling (RSS)
|
||||
configuration of the virtual function (VF). The VF RSS information like RSS hash key may be
|
||||
considered sensitive on some devices where this information is shared between VF and the
|
||||
physical function (PF). When unset, the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Trust=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a boolean. Allows to set trust mode of the virtual function (VF). When set, VF
|
||||
users can set a specific feature which may impact security and/or performance. When unset,
|
||||
the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>LinkState=</varname></term>
|
||||
<listitem>
|
||||
<para>Allows to set the link state of the virtual function (VF). Takes a boolean or a
|
||||
special value <literal>auto</literal>. Setting to <literal>auto</literal> means a
|
||||
reflection of the physical function (PF) link state, <literal>yes</literal> lets the VF to
|
||||
communicate with other VFs on this host even if the PF link state is down,
|
||||
<literal>no</literal> causes the hardware to drop any packets sent by the VF. When unset,
|
||||
the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>MACAddress=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the MAC address for the virtual function.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[Network] Section Options</title>
|
||||
|
||||
|
@ -2637,20 +2724,20 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>LimitSize=</varname></term>
|
||||
<term><varname>LimitBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes the number of bytes that can be queued waiting for tokens to become available.
|
||||
When the size is suffixed with K, M, or G, it is parsed as Kilobytes, Megabytes, or Gigabytes,
|
||||
respectively, to the base of 1000. Defaults to unset.</para>
|
||||
respectively, to the base of 1024. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Burst=</varname></term>
|
||||
<term><varname>BurstBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the size of the bucket. This is the maximum amount of bytes that tokens
|
||||
can be available for instantaneous transfer. When the size is suffixed with K, M, or G, it is
|
||||
parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1000. Defaults to
|
||||
parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to
|
||||
unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -2669,7 +2756,7 @@
|
|||
<listitem>
|
||||
<para>The Minimum Packet Unit (MPU) determines the minimal token usage (specified in bytes)
|
||||
for a packet. When suffixed with K, M, or G, the specified size is parsed as Kilobytes,
|
||||
Megabytes, or Gigabytes, respectively, to the base of 1000. Defaults to zero.</para>
|
||||
Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to zero.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -2686,7 +2773,7 @@
|
|||
<term><varname>MTUBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the size of the peakrate bucket. When suffixed with K, M, or G, the specified
|
||||
size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1000.
|
||||
size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024.
|
||||
Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -2759,7 +2846,7 @@
|
|||
<xi:include href="tc.xml" xpointer="qdisc-handle" />
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>LimitSize=</varname></term>
|
||||
<term><varname>LimitBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the hard limit on the FIFO size in bytes. The size limit (a buffer size) to prevent it
|
||||
from overflowing in case it is unable to dequeue packets as quickly as it receives them. When this limit
|
||||
|
@ -2828,7 +2915,7 @@
|
|||
<xi:include href="tc.xml" xpointer="qdisc-handle" />
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Overhead=</varname></term>
|
||||
<term><varname>OverheadBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies that bytes to be addeded to the size of each packet. Bytes may be negative.
|
||||
Takes an integer ranges -64 to 256. Defaults to unset and kernel's default is used.</para>
|
||||
|
@ -2918,11 +3005,12 @@
|
|||
<xi:include href="tc.xml" xpointer="tclass-classid" />
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Quantum=</varname></term>
|
||||
<term><varname>QuantumBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the amount of bytes a flow is allowed to dequeue before the
|
||||
scheduler moves to the next class. An unsigned integer ranges 1 to 4294967294.
|
||||
Defaults to the MTU of the interface.</para>
|
||||
<para>Specifies the amount of bytes a flow is allowed to dequeue before the scheduler moves
|
||||
to the next class. When suffixed with K, M, or G, the specified size is parsed as Kilobytes,
|
||||
Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to the MTU of the
|
||||
interface.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -3033,7 +3121,7 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>MemoryLimit=</varname></term>
|
||||
<term><varname>MemoryLimitBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the limit on the total number of bytes that can be queued in this FQ-CoDel instance.
|
||||
When suffixed with K, M, or G, the specified size is parsed as Kilobytes, Megabytes, or Gigabytes,
|
||||
|
@ -3066,7 +3154,7 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Quantum=</varname></term>
|
||||
<term><varname>QuantumBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the number of bytes used as 'deficit' in the fair queuing algorithmtimespan.
|
||||
When suffixed with K, M, or G, the specified size is parsed as Kilobytes, Megabytes, or Gigabytes,
|
||||
|
@ -3118,7 +3206,7 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Quantum=</varname></term>
|
||||
<term><varname>QuantumBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the credit per dequeue RR round, i.e. the amount of bytes a flow is allowed
|
||||
to dequeue at once. When suffixed with K, M, or G, the specified size is parsed as Kilobytes,
|
||||
|
@ -3128,7 +3216,7 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>InitialQuantum=</varname></term>
|
||||
<term><varname>InitialQuantumBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the initial sending rate credit, i.e. the amount of bytes a new flow is
|
||||
allowed to dequeue initially. When suffixed with K, M, or G, the specified size is parsed as
|
||||
|
@ -3359,10 +3447,10 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>MaxPacketSize=</varname></term>
|
||||
<term><varname>MaxPacketBytes=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the maximum packet size in bytes for the class. When suffixed with K, M, or G, the specified
|
||||
size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1000. When unset,
|
||||
size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024. When unset,
|
||||
the kernel default is used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
|
@ -884,7 +884,7 @@
|
|||
project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
||||
a list of signal names.</para>
|
||||
|
||||
<para>Note that this setting does not change the the mapping between numeric exit statuses and their
|
||||
<para>Note that this setting does not change the mapping between numeric exit statuses and their
|
||||
names, i.e. regardless how this setting is used 0 will still be mapped to <literal>SUCCESS</literal>
|
||||
(and thus typically shown as <literal>0/SUCCESS</literal> in tool outputs) and 1 to
|
||||
<literal>FAILURE</literal> (and thus typically shown as <literal>1/FAILURE</literal>), and so on. It
|
||||
|
|
|
@ -218,7 +218,7 @@
|
|||
|
||||
<para>Note that <command>userdbctl</command> has internal support for NSS-based lookups too. This means
|
||||
that if neither <constant>io.systemd.Multiplexer</constant> nor
|
||||
<constant>io.systemd.NameSeviceSwitch</constant> are running look-ups into the the basic user/group
|
||||
<constant>io.systemd.NameSeviceSwitch</constant> are running look-ups into the basic user/group
|
||||
databases will still work.</para>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
@ -1130,6 +1130,7 @@ int socket_bind_to_ifname(int fd, const char *ifname) {
|
|||
|
||||
int socket_bind_to_ifindex(int fd, int ifindex) {
|
||||
char ifname[IF_NAMESIZE + 1];
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
|
@ -1141,10 +1142,9 @@ int socket_bind_to_ifindex(int fd, int ifindex) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTOIFINDEX, &ifindex, sizeof(ifindex)) >= 0)
|
||||
return 0;
|
||||
if (errno != ENOPROTOOPT)
|
||||
return -errno;
|
||||
r = setsockopt_int(fd, SOL_SOCKET, SO_BINDTOIFINDEX, ifindex);
|
||||
if (r != -ENOPROTOOPT)
|
||||
return r;
|
||||
|
||||
/* Fall back to SO_BINDTODEVICE on kernels < 5.0 which didn't have SO_BINDTOIFINDEX */
|
||||
if (!format_ifname(ifindex, ifname))
|
||||
|
|
|
@ -544,7 +544,7 @@ int bpf_firewall_compile(Unit *u) {
|
|||
"BPF_F_ALLOW_MULTI is not supported on this manager, not doing BPF firewall on slice units.");
|
||||
|
||||
/* Note that when we compile a new firewall we first flush out the access maps and the BPF programs themselves,
|
||||
* but we reuse the the accounting maps. That way the firewall in effect always maps to the actual
|
||||
* but we reuse the accounting maps. That way the firewall in effect always maps to the actual
|
||||
* configuration, but we don't flush out the accounting unnecessarily */
|
||||
|
||||
u->ip_bpf_ingress = bpf_program_unref(u->ip_bpf_ingress);
|
||||
|
|
|
@ -2855,7 +2855,7 @@ static int setup_keyring(
|
|||
}
|
||||
|
||||
out:
|
||||
/* Revert back uid & gid for the the last time, and exit */
|
||||
/* Revert back uid & gid for the last time, and exit */
|
||||
/* no extra logging, as only the first already reported error matters */
|
||||
if (getuid() != saved_uid)
|
||||
(void) setreuid(saved_uid, -1);
|
||||
|
|
|
@ -668,7 +668,7 @@ int config_parse_kill_mode(
|
|||
if (m == KILL_NONE)
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Unit configured to use KillMode=none. "
|
||||
"This is unsafe, as it disables systemd's process life-cycle management for the service. "
|
||||
"This is unsafe, as it disables systemd's process lifecycle management for the service. "
|
||||
"Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. "
|
||||
"Support for KillMode=none is deprecated and will eventually be removed.");
|
||||
|
||||
|
|
|
@ -747,7 +747,7 @@ static int mount_private_dev(MountEntry *m) {
|
|||
|
||||
NULSTR_FOREACH(d, devnodes) {
|
||||
r = clone_device_node(d, temporary_mount, &can_mknod);
|
||||
/* ENXIO means the the *source* is not a device file, skip creation in that case */
|
||||
/* ENXIO means the *source* is not a device file, skip creation in that case */
|
||||
if (r < 0 && r != -ENXIO)
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -499,7 +499,7 @@ static int acquire_home(
|
|||
return r;
|
||||
|
||||
/* Implement our own retry loop here instead of relying on the PAM client's one. That's because it
|
||||
* might happen that the the record we stored on the host does not match the encryption password of
|
||||
* might happen that the record we stored on the host does not match the encryption password of
|
||||
* the LUKS image in case the image was used in a different system where the password was
|
||||
* changed. In that case it will happen that the LUKS password and the host password are
|
||||
* different, and we handle that by collecting and passing multiple passwords in that case. Hence we
|
||||
|
|
|
@ -172,7 +172,7 @@ int user_record_reconcile(
|
|||
* -REMCHG: identity records are not about the same user
|
||||
* -ESTALE: embedded identity record is equally new or newer than supplied record
|
||||
*
|
||||
* Return the new record to use, which is either the the embedded record updated with the host
|
||||
* Return the new record to use, which is either the embedded record updated with the host
|
||||
* binding or the host record. In both cases the secret data is stripped. */
|
||||
|
||||
assert(host);
|
||||
|
|
|
@ -112,7 +112,7 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
|||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr);
|
||||
|
||||
int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
|
||||
int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address);
|
||||
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
|
||||
const void *packet, size_t len);
|
||||
|
||||
|
|
|
@ -17,16 +17,16 @@
|
|||
#include "fd-util.h"
|
||||
#include "socket-util.h"
|
||||
|
||||
int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
|
||||
int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) {
|
||||
union sockaddr_union src = {
|
||||
.in6.sin6_family = AF_INET6,
|
||||
.in6.sin6_port = htobe16(DHCP6_PORT_CLIENT),
|
||||
.in6.sin6_scope_id = index,
|
||||
.in6.sin6_scope_id = ifindex,
|
||||
};
|
||||
_cleanup_close_ int s = -1;
|
||||
int r;
|
||||
|
||||
assert(index > 0);
|
||||
assert(ifindex > 0);
|
||||
assert(local_address);
|
||||
|
||||
src.in6.sin6_addr = *local_address;
|
||||
|
|
|
@ -81,11 +81,11 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter,
|
|||
return TAKE_FD(s);
|
||||
}
|
||||
|
||||
int icmp6_bind_router_solicitation(int index) {
|
||||
int icmp6_bind_router_solicitation(int ifindex) {
|
||||
struct icmp6_filter filter = {};
|
||||
struct ipv6_mreq mreq = {
|
||||
.ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
|
||||
.ipv6mr_interface = index,
|
||||
.ipv6mr_interface = ifindex,
|
||||
};
|
||||
|
||||
ICMP6_FILTER_SETBLOCKALL(&filter);
|
||||
|
@ -94,11 +94,11 @@ int icmp6_bind_router_solicitation(int index) {
|
|||
return icmp6_bind_router_message(&filter, &mreq);
|
||||
}
|
||||
|
||||
int icmp6_bind_router_advertisement(int index) {
|
||||
int icmp6_bind_router_advertisement(int ifindex) {
|
||||
struct icmp6_filter filter = {};
|
||||
struct ipv6_mreq mreq = {
|
||||
.ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
|
||||
.ipv6mr_interface = index,
|
||||
.ipv6mr_interface = ifindex,
|
||||
};
|
||||
|
||||
ICMP6_FILTER_SETBLOCKALL(&filter);
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
|
||||
|
||||
int icmp6_bind_router_solicitation(int index);
|
||||
int icmp6_bind_router_advertisement(int index);
|
||||
int icmp6_bind_router_solicitation(int ifindex);
|
||||
int icmp6_bind_router_advertisement(int ifindex);
|
||||
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
|
||||
int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
|
||||
triple_timestamp *timestamp);
|
||||
|
|
|
@ -159,7 +159,7 @@ int sd_dhcp6_client_set_callback(
|
|||
int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) {
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(ifindex >= -1, -EINVAL);
|
||||
assert_return(ifindex > 0, -EINVAL);
|
||||
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
|
||||
|
||||
client->ifindex = ifindex;
|
||||
|
|
|
@ -415,7 +415,7 @@ _public_ int sd_radv_start(sd_radv *ra) {
|
|||
|
||||
_public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
|
||||
assert_return(ra, -EINVAL);
|
||||
assert_return(ifindex >= -1, -EINVAL);
|
||||
assert_return(ifindex > 0, -EINVAL);
|
||||
|
||||
if (ra->state != SD_RADV_STATE_IDLE)
|
||||
return -EBUSY;
|
||||
|
|
|
@ -258,7 +258,7 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const
|
|||
}
|
||||
|
||||
int dhcp_network_bind_raw_socket(
|
||||
int index,
|
||||
int ifindex,
|
||||
union sockaddr_union *link,
|
||||
uint32_t id,
|
||||
const uint8_t *addr, size_t addr_len,
|
||||
|
|
|
@ -30,7 +30,7 @@ static struct ether_addr mac_addr = {
|
|||
|
||||
static sd_event_source *hangcheck;
|
||||
static int test_dhcp_fd[2];
|
||||
static int test_index = 42;
|
||||
static int test_ifindex = 42;
|
||||
static int test_client_message_num;
|
||||
static be32_t test_iaid = 0;
|
||||
static uint8_t test_duid[14] = { };
|
||||
|
@ -48,7 +48,7 @@ static int test_client_basic(sd_event *e) {
|
|||
|
||||
assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0);
|
||||
assert_se(sd_dhcp6_client_set_ifindex(client, -42) == -EINVAL);
|
||||
assert_se(sd_dhcp6_client_set_ifindex(client, -1) == 0);
|
||||
assert_se(sd_dhcp6_client_set_ifindex(client, -1) == -EINVAL);
|
||||
assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0);
|
||||
|
||||
assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
|
||||
|
@ -877,8 +877,8 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
|
|||
return len;
|
||||
}
|
||||
|
||||
int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
|
||||
assert_se(index == test_index);
|
||||
int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) {
|
||||
assert_se(ifindex == test_ifindex);
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_dhcp_fd) < 0)
|
||||
return -errno;
|
||||
|
@ -899,7 +899,7 @@ static int test_client_solicit(sd_event *e) {
|
|||
|
||||
assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
|
||||
|
||||
assert_se(sd_dhcp6_client_set_ifindex(client, test_index) == 0);
|
||||
assert_se(sd_dhcp6_client_set_ifindex(client, test_ifindex) == 0);
|
||||
assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
|
||||
sizeof (mac_addr),
|
||||
ARPHRD_ETHER) >= 0);
|
||||
|
|
|
@ -78,7 +78,7 @@ int arp_send_announcement(int fd, int ifindex,
|
|||
return arp_network_send_raw_socket(fd, ifindex, &ea);
|
||||
}
|
||||
|
||||
int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_addr *eth_mac) {
|
||||
int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
|
||||
return -errno;
|
||||
|
||||
|
|
|
@ -159,8 +159,8 @@ static void test_radv(void) {
|
|||
assert_se(ra);
|
||||
|
||||
assert_se(sd_radv_set_ifindex(NULL, 0) < 0);
|
||||
assert_se(sd_radv_set_ifindex(ra, 0) >= 0);
|
||||
assert_se(sd_radv_set_ifindex(ra, -1) >= 0);
|
||||
assert_se(sd_radv_set_ifindex(ra, 0) < 0);
|
||||
assert_se(sd_radv_set_ifindex(ra, -1) < 0);
|
||||
assert_se(sd_radv_set_ifindex(ra, -2) < 0);
|
||||
assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
|
||||
|
||||
|
@ -219,12 +219,12 @@ static void test_radv(void) {
|
|||
assert_se(!ra);
|
||||
}
|
||||
|
||||
int icmp6_bind_router_solicitation(int index) {
|
||||
int icmp6_bind_router_solicitation(int ifindex) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int icmp6_bind_router_advertisement(int index) {
|
||||
assert_se(index == 42);
|
||||
int icmp6_bind_router_advertisement(int ifindex) {
|
||||
assert_se(ifindex == 42);
|
||||
|
||||
return test_fd[1];
|
||||
}
|
||||
|
|
|
@ -174,8 +174,8 @@ static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int icmp6_bind_router_solicitation(int index) {
|
||||
assert_se(index == 42);
|
||||
int icmp6_bind_router_solicitation(int ifindex) {
|
||||
assert_se(ifindex == 42);
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
|
||||
return -errno;
|
||||
|
@ -183,8 +183,7 @@ int icmp6_bind_router_solicitation(int index) {
|
|||
return test_fd[0];
|
||||
}
|
||||
|
||||
int icmp6_bind_router_advertisement(int index) {
|
||||
|
||||
int icmp6_bind_router_advertisement(int ifindex) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
|
|
@ -537,6 +537,43 @@ static const NLTypeSystem rtnl_prop_list_type_system = {
|
|||
.types = rtnl_prop_list_types,
|
||||
};
|
||||
|
||||
static const NLType rtnl_vf_vlan_list_types[] = {
|
||||
[IFLA_VF_VLAN_INFO] = { .size = sizeof(struct ifla_vf_vlan_info) },
|
||||
};
|
||||
|
||||
static const NLTypeSystem rtnl_vf_vlan_type_system = {
|
||||
.count = ELEMENTSOF(rtnl_vf_vlan_list_types),
|
||||
.types = rtnl_vf_vlan_list_types,
|
||||
};
|
||||
|
||||
static const NLType rtnl_vf_vlan_info_types[] = {
|
||||
[IFLA_VF_MAC] = { .size = sizeof(struct ifla_vf_mac) },
|
||||
[IFLA_VF_VLAN] = { .size = sizeof(struct ifla_vf_vlan) },
|
||||
[IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_type_system},
|
||||
[IFLA_VF_TX_RATE] = { .size = sizeof(struct ifla_vf_tx_rate) },
|
||||
[IFLA_VF_SPOOFCHK] = { .size = sizeof(struct ifla_vf_spoofchk) },
|
||||
[IFLA_VF_RATE] = { .size = sizeof(struct ifla_vf_rate) },
|
||||
[IFLA_VF_LINK_STATE] = { .size = sizeof(struct ifla_vf_link_state) },
|
||||
[IFLA_VF_RSS_QUERY_EN] = { .size = sizeof(struct ifla_vf_rss_query_en) },
|
||||
[IFLA_VF_TRUST] = { .size = sizeof(struct ifla_vf_trust) },
|
||||
[IFLA_VF_IB_NODE_GUID] = { .size = sizeof(struct ifla_vf_guid) },
|
||||
[IFLA_VF_IB_PORT_GUID] = { .size = sizeof(struct ifla_vf_guid) },
|
||||
};
|
||||
|
||||
static const NLTypeSystem rtnl_vf_vlan_info_type_system = {
|
||||
.count = ELEMENTSOF(rtnl_vf_vlan_info_types),
|
||||
.types = rtnl_vf_vlan_info_types,
|
||||
};
|
||||
|
||||
static const NLType rtnl_link_io_srv_types[] = {
|
||||
[IFLA_VF_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_info_type_system },
|
||||
};
|
||||
|
||||
static const NLTypeSystem rtnl_io_srv_type_system = {
|
||||
.count = ELEMENTSOF(rtnl_link_io_srv_types),
|
||||
.types = rtnl_link_io_srv_types,
|
||||
};
|
||||
|
||||
static const NLType rtnl_link_types[] = {
|
||||
[IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR },
|
||||
[IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR },
|
||||
|
@ -564,10 +601,8 @@ static const NLType rtnl_link_types[] = {
|
|||
[IFLA_LINKINFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system },
|
||||
[IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 },
|
||||
[IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 },
|
||||
/*
|
||||
[IFLA_NUM_VF],
|
||||
[IFLA_VFINFO_LIST] = {. type = NETLINK_TYPE_NESTED, },
|
||||
*/
|
||||
[IFLA_NUM_VF] = { .type = NETLINK_TYPE_U32 },
|
||||
[IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_io_srv_type_system },
|
||||
[IFLA_STATS64] = { .size = sizeof(struct rtnl_link_stats64) },
|
||||
/*
|
||||
[IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED },
|
||||
|
|
|
@ -468,7 +468,7 @@ static bool validate_runtime_directory(pam_handle_t *handle, const char *path, u
|
|||
/* Some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually
|
||||
* set up properly for us. This is supposed to provide a careful safety net for supporting su/sudo
|
||||
* type transitions: in that case the UID changes, but the session and thus the user owning it
|
||||
* doesn't change. Since the $XDG_RUNTIME_DIR life-cycle is bound to the session's user being logged
|
||||
* doesn't change. Since the $XDG_RUNTIME_DIR lifecycle is bound to the session's user being logged
|
||||
* in at least once we should be particularly careful when setting the environment variable, since
|
||||
* otherwise we might end up setting $XDG_RUNTIME_DIR to some directory owned by the wrong user. */
|
||||
|
||||
|
|
|
@ -105,6 +105,8 @@ sources = files('''
|
|||
networkd-routing-policy-rule.h
|
||||
networkd-speed-meter.c
|
||||
networkd-speed-meter.h
|
||||
networkd-sriov.c
|
||||
networkd-sriov.h
|
||||
networkd-util.c
|
||||
networkd-util.h
|
||||
networkd-wifi.c
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
|
@ -31,6 +32,7 @@
|
|||
#include "networkd-manager.h"
|
||||
#include "networkd-ndisc.h"
|
||||
#include "networkd-neighbor.h"
|
||||
#include "networkd-sriov.h"
|
||||
#include "networkd-radv.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-wifi.h"
|
||||
|
@ -1127,6 +1129,9 @@ void link_check_ready(Link *link) {
|
|||
if (!link->tc_configured)
|
||||
return;
|
||||
|
||||
if (!link->sr_iov_configured)
|
||||
return;
|
||||
|
||||
if (link_has_carrier(link) || !link->network->configure_without_carrier) {
|
||||
|
||||
if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4) && !link->ipv4ll_address)
|
||||
|
@ -2838,6 +2843,28 @@ static int link_configure_traffic_control(Link *link) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int link_configure_sr_iov(Link *link) {
|
||||
SRIOV *sr_iov;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
link->sr_iov_configured = false;
|
||||
link->sr_iov_messages = 0;
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(sr_iov, link->network->sr_iov_by_section, i) {
|
||||
r = sr_iov_configure(link, sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (link->sr_iov_messages == 0)
|
||||
link->sr_iov_configured = true;
|
||||
else
|
||||
log_link_debug(link, "Configuring SR-IOV");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_configure(Link *link) {
|
||||
int r;
|
||||
|
||||
|
@ -2849,6 +2876,10 @@ static int link_configure(Link *link) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_configure_sr_iov(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->iftype == ARPHRD_CAN)
|
||||
return link_configure_can(link);
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef struct Link {
|
|||
unsigned routing_policy_rule_messages;
|
||||
unsigned routing_policy_rule_remove_messages;
|
||||
unsigned tc_messages;
|
||||
unsigned sr_iov_messages;
|
||||
unsigned enslaving;
|
||||
|
||||
Set *addresses;
|
||||
|
@ -118,6 +119,7 @@ typedef struct Link {
|
|||
bool static_nexthops_configured:1;
|
||||
bool routing_policy_rules_configured:1;
|
||||
bool tc_configured:1;
|
||||
bool sr_iov_configured:1;
|
||||
bool setting_mtu:1;
|
||||
bool setting_genmode:1;
|
||||
bool ipv6_mtu_set:1;
|
||||
|
|
|
@ -15,6 +15,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
|
|||
#include "networkd-ipv4ll.h"
|
||||
#include "networkd-ndisc.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-sriov.h"
|
||||
#include "qdisc.h"
|
||||
#include "tclass.h"
|
||||
#include "vlan-util.h"
|
||||
|
@ -53,6 +54,15 @@ Link.Multicast, config_parse_tristate,
|
|||
Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
|
||||
Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
|
||||
Link.RequiredForOnline, config_parse_required_for_online, 0, 0
|
||||
SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, 0
|
||||
SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, 0
|
||||
SR-IOV.QualityOfService, config_parse_sr_iov_uint32, 0, 0
|
||||
SR-IOV.VLANProtocol, config_parse_sr_iov_vlan_proto, 0, 0
|
||||
SR-IOV.MACSpoofCheck, config_parse_sr_iov_boolean, 0, 0
|
||||
SR-IOV.QueryReceiveSideScaling, config_parse_sr_iov_boolean, 0, 0
|
||||
SR-IOV.Trust, config_parse_sr_iov_boolean, 0, 0
|
||||
SR-IOV.LinkState, config_parse_sr_iov_link_state, 0, 0
|
||||
SR-IOV.MACAddress, config_parse_sr_iov_mac, 0, 0
|
||||
Network.Description, config_parse_string, 0, offsetof(Network, description)
|
||||
Network.Bridge, config_parse_ifname, 0, offsetof(Network, bridge_name)
|
||||
Network.Bond, config_parse_ifname, 0, offsetof(Network, bond_name)
|
||||
|
@ -294,11 +304,11 @@ QDisc.Parent, config_parse_qdisc_parent,
|
|||
QDisc.Handle, config_parse_qdisc_handle, _QDISC_KIND_INVALID, 0
|
||||
BFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_BFIFO, 0
|
||||
BFIFO.Handle, config_parse_qdisc_handle, QDISC_KIND_BFIFO, 0
|
||||
BFIFO.LimitSize, config_parse_bfifo_size, QDISC_KIND_BFIFO, 0
|
||||
BFIFO.LimitBytes, config_parse_bfifo_size, QDISC_KIND_BFIFO, 0
|
||||
CAKE.Parent, config_parse_qdisc_parent, QDISC_KIND_CAKE, 0
|
||||
CAKE.Handle, config_parse_qdisc_handle, QDISC_KIND_CAKE, 0
|
||||
CAKE.Bandwidth, config_parse_cake_bandwidth, QDISC_KIND_CAKE, 0
|
||||
CAKE.Overhead, config_parse_cake_overhead, QDISC_KIND_CAKE, 0
|
||||
CAKE.OverheadBytes, config_parse_cake_overhead, QDISC_KIND_CAKE, 0
|
||||
ControlledDelay.Parent, config_parse_qdisc_parent, QDISC_KIND_CODEL, 0
|
||||
ControlledDelay.Handle, config_parse_qdisc_handle, QDISC_KIND_CODEL, 0
|
||||
ControlledDelay.PacketLimit, config_parse_controlled_delay_u32, QDISC_KIND_CODEL, 0
|
||||
|
@ -310,7 +320,7 @@ DeficitRoundRobinScheduler.Parent, config_parse_qdisc_parent,
|
|||
DeficitRoundRobinScheduler.Handle, config_parse_qdisc_handle, QDISC_KIND_DRR, 0
|
||||
DeficitRoundRobinSchedulerClass.Parent, config_parse_tclass_parent, TCLASS_KIND_DRR, 0
|
||||
DeficitRoundRobinSchedulerClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_DRR, 0
|
||||
DeficitRoundRobinSchedulerClass.Quantum, config_parse_drr_size, TCLASS_KIND_DRR, 0
|
||||
DeficitRoundRobinSchedulerClass.QuantumBytes, config_parse_drr_size, TCLASS_KIND_DRR, 0
|
||||
EnhancedTransmissionSelection.Parent, config_parse_qdisc_parent, QDISC_KIND_ETS, 0
|
||||
EnhancedTransmissionSelection.Handle, config_parse_qdisc_handle, QDISC_KIND_ETS, 0
|
||||
EnhancedTransmissionSelection.Bands, config_parse_ets_u8, QDISC_KIND_ETS, 0
|
||||
|
@ -330,13 +340,13 @@ QuickFairQueueing.Handle, config_parse_qdisc_handle,
|
|||
QuickFairQueueingClass.Parent, config_parse_tclass_parent, TCLASS_KIND_QFQ, 0
|
||||
QuickFairQueueingClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_QFQ, 0
|
||||
QuickFairQueueingClass.Weight, config_parse_quick_fair_queueing_weight, TCLASS_KIND_QFQ, 0
|
||||
QuickFairQueueingClass.MaxPacketSize, config_parse_quick_fair_queueing_max_packet, TCLASS_KIND_QFQ, 0
|
||||
QuickFairQueueingClass.MaxPacketBytes, config_parse_quick_fair_queueing_max_packet, TCLASS_KIND_QFQ, 0
|
||||
FairQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_FQ, 0
|
||||
FairQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_FQ, 0
|
||||
FairQueueing.PacketLimit, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
|
||||
FairQueueing.FlowLimit, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
|
||||
FairQueueing.Quantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
|
||||
FairQueueing.InitialQuantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
|
||||
FairQueueing.QuantumBytes, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
|
||||
FairQueueing.InitialQuantumBytes, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
|
||||
FairQueueing.MaximumRate, config_parse_fair_queueing_max_rate, QDISC_KIND_FQ, 0
|
||||
FairQueueing.Buckets, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
|
||||
FairQueueing.OrphanMask, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
|
||||
|
@ -345,9 +355,9 @@ FairQueueing.CEThresholdSec, config_parse_fair_queueing_usec,
|
|||
FairQueueingControlledDelay.Parent, config_parse_qdisc_parent, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.Handle, config_parse_qdisc_handle, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.PacketLimit, config_parse_fair_queueing_controlled_delay_u32, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.MemoryLimit, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.MemoryLimitBytes, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.Flows, config_parse_fair_queueing_controlled_delay_u32, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.Quantum, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.QuantumBytes, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.TargetSec, config_parse_fair_queueing_controlled_delay_usec, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.IntervalSec, config_parse_fair_queueing_controlled_delay_usec, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.CEThresholdSec, config_parse_fair_queueing_controlled_delay_usec, QDISC_KIND_FQ_CODEL, 0
|
||||
|
@ -392,12 +402,12 @@ StochasticFairnessQueueing.Handle, config_parse_qdisc_handle,
|
|||
StochasticFairnessQueueing.PerturbPeriodSec, config_parse_stochastic_fairness_queueing_perturb_period, QDISC_KIND_SFQ, 0
|
||||
TokenBucketFilter.Parent, config_parse_qdisc_parent, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.Handle, config_parse_qdisc_handle, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.Rate, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.Burst, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.LimitSize, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.Rate, config_parse_token_bucket_filter_rate, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.BurstBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.LimitBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.MTUBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.MPUBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.PeakRate, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.PeakRate, config_parse_token_bucket_filter_rate, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.LatencySec, config_parse_token_bucket_filter_latency, QDISC_KIND_TBF, 0
|
||||
TrivialLinkEqualizer.Parent, config_parse_qdisc_parent, QDISC_KIND_TEQL, 0
|
||||
TrivialLinkEqualizer.Handle, config_parse_qdisc_handle, QDISC_KIND_TEQL, 0
|
||||
|
@ -436,3 +446,9 @@ TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_net
|
|||
TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_network_emulator_rate, 0, 0
|
||||
TrafficControlQueueingDiscipline.NetworkEmulatorDuplicateRate, config_parse_network_emulator_rate, 0, 0
|
||||
TrafficControlQueueingDiscipline.NetworkEmulatorPacketLimit, config_parse_network_emulator_packet_limit, 0, 0
|
||||
FairQueueing.Quantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
|
||||
FairQueueing.InitialQuantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
|
||||
FairQueueingControlledDelay.MemoryLimit, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
|
||||
FairQueueingControlledDelay.Quantum, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
|
||||
TokenBucketFilter.Burst, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
TokenBucketFilter.LimitSize, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "network-internal.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-sriov.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-lookup.h"
|
||||
#include "set.h"
|
||||
|
@ -158,6 +159,7 @@ int network_verify(Network *network) {
|
|||
Route *route, *route_next;
|
||||
FdbEntry *fdb, *fdb_next;
|
||||
TrafficControl *tc;
|
||||
SRIOV *sr_iov;
|
||||
Iterator i;
|
||||
|
||||
assert(network);
|
||||
|
@ -330,6 +332,10 @@ int network_verify(Network *network) {
|
|||
if (traffic_control_section_verify(tc, &has_root, &has_clsact) < 0)
|
||||
traffic_control_free(tc);
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(sr_iov, network->sr_iov_by_section, i)
|
||||
if (sr_iov_section_verify(sr_iov) < 0)
|
||||
sr_iov_free(sr_iov);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -484,6 +490,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||
filename, NETWORK_DIRS, dropin_dirname,
|
||||
"Match\0"
|
||||
"Link\0"
|
||||
"SR-IOV\0"
|
||||
"Network\0"
|
||||
"Address\0"
|
||||
"Neighbor\0"
|
||||
|
@ -731,6 +738,7 @@ static Network *network_free(Network *network) {
|
|||
hashmap_free(network->prefixes_by_section);
|
||||
hashmap_free(network->route_prefixes_by_section);
|
||||
hashmap_free(network->rules_by_section);
|
||||
ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free);
|
||||
ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
|
||||
|
||||
if (network->manager &&
|
||||
|
|
|
@ -312,6 +312,7 @@ struct Network {
|
|||
Hashmap *route_prefixes_by_section;
|
||||
Hashmap *rules_by_section;
|
||||
OrderedHashmap *tc_by_section;
|
||||
OrderedHashmap *sr_iov_by_section;
|
||||
|
||||
/* All kinds of DNS configuration */
|
||||
struct in_addr_data *dns;
|
||||
|
|
|
@ -0,0 +1,501 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-sriov.h"
|
||||
#include "parse-util.h"
|
||||
#include "set.h"
|
||||
#include "string-util.h"
|
||||
|
||||
static int sr_iov_new(SRIOV **ret) {
|
||||
SRIOV *sr_iov;
|
||||
|
||||
sr_iov = new(SRIOV, 1);
|
||||
if (!sr_iov)
|
||||
return -ENOMEM;
|
||||
|
||||
*sr_iov = (SRIOV) {
|
||||
.vf = (uint32_t) -1,
|
||||
.vlan_proto = ETH_P_8021Q,
|
||||
.vf_spoof_check_setting = -1,
|
||||
.trust = -1,
|
||||
.query_rss = -1,
|
||||
.link_state = _SR_IOV_LINK_STATE_INVALID,
|
||||
};
|
||||
|
||||
*ret = TAKE_PTR(sr_iov);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sr_iov_new_static(Network *network, const char *filename, unsigned section_line, SRIOV **ret) {
|
||||
_cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
|
||||
_cleanup_(sr_iov_freep) SRIOV *sr_iov = NULL;
|
||||
SRIOV *existing = NULL;
|
||||
int r;
|
||||
|
||||
assert(network);
|
||||
assert(ret);
|
||||
assert(filename);
|
||||
assert(section_line > 0);
|
||||
|
||||
r = network_config_section_new(filename, section_line, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
existing = ordered_hashmap_get(network->sr_iov_by_section, n);
|
||||
if (existing) {
|
||||
*ret = existing;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sr_iov_new(&sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
sr_iov->network = network;
|
||||
sr_iov->section = TAKE_PTR(n);
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(&network->sr_iov_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_hashmap_put(network->sr_iov_by_section, sr_iov->section, sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SRIOV *sr_iov_free(SRIOV *sr_iov) {
|
||||
if (!sr_iov)
|
||||
return NULL;
|
||||
|
||||
if (sr_iov->network && sr_iov->section)
|
||||
ordered_hashmap_remove(sr_iov->network->sr_iov_by_section, sr_iov->section);
|
||||
|
||||
network_config_section_free(sr_iov->section);
|
||||
|
||||
return mfree(sr_iov);
|
||||
}
|
||||
|
||||
static int sr_iov_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->sr_iov_messages > 0);
|
||||
link->sr_iov_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_error_errno(link, m, r, "Could not set up SR-IOV");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->sr_iov_messages == 0) {
|
||||
log_link_debug(link, "SR-IOV configured");
|
||||
link->sr_iov_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sr_iov_configure(Link *link, SRIOV *sr_iov) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(link->ifindex > 0);
|
||||
|
||||
log_link_debug(link, "Setting SR-IOV virtual function %"PRIu32, sr_iov->vf);
|
||||
|
||||
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
|
||||
|
||||
r = sd_netlink_message_open_container(req, IFLA_VFINFO_LIST);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not open IFLA_VFINFO_LIST container: %m");
|
||||
|
||||
r = sd_netlink_message_open_container(req, IFLA_VF_INFO);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not open IFLA_VF_INFO container: %m");
|
||||
|
||||
if (!ether_addr_is_null(&sr_iov->mac)) {
|
||||
struct ifla_vf_mac ivm = {
|
||||
.vf = sr_iov->vf,
|
||||
};
|
||||
|
||||
memcpy(ivm.mac, &sr_iov->mac, ETH_ALEN);
|
||||
r = sd_netlink_message_append_data(req, IFLA_VF_MAC, &ivm, sizeof(struct ifla_vf_mac));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_VF_MAC: %m");
|
||||
}
|
||||
|
||||
if (sr_iov->vf_spoof_check_setting >= 0) {
|
||||
struct ifla_vf_spoofchk ivs = {
|
||||
.vf = sr_iov->vf,
|
||||
.setting = sr_iov->vf_spoof_check_setting,
|
||||
};
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_VF_SPOOFCHK, &ivs, sizeof(struct ifla_vf_spoofchk));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_VF_SPOOFCHK: %m");
|
||||
}
|
||||
|
||||
if (sr_iov->query_rss >= 0) {
|
||||
struct ifla_vf_rss_query_en ivs = {
|
||||
.vf = sr_iov->vf,
|
||||
.setting = sr_iov->query_rss,
|
||||
};
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_VF_RSS_QUERY_EN, &ivs, sizeof(struct ifla_vf_rss_query_en));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_VF_RSS_QUERY_EN: %m");
|
||||
}
|
||||
|
||||
if (sr_iov->trust >= 0) {
|
||||
struct ifla_vf_trust ivt = {
|
||||
.vf = sr_iov->vf,
|
||||
.setting = sr_iov->trust,
|
||||
};
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_VF_TRUST, &ivt, sizeof(struct ifla_vf_trust));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_VF_TRUST: %m");
|
||||
}
|
||||
|
||||
if (sr_iov->link_state >= 0) {
|
||||
struct ifla_vf_link_state ivl = {
|
||||
.vf = sr_iov->vf,
|
||||
.link_state = sr_iov->link_state,
|
||||
};
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_VF_LINK_STATE, &ivl, sizeof(struct ifla_vf_link_state));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_VF_LINK_STATE: %m");
|
||||
}
|
||||
|
||||
if (sr_iov->vlan > 0) {
|
||||
/* Because of padding, first the buffer must be initialized with 0. */
|
||||
struct ifla_vf_vlan_info ivvi = {};
|
||||
ivvi.vf = sr_iov->vf;
|
||||
ivvi.vlan = sr_iov->vlan;
|
||||
ivvi.qos = sr_iov->qos;
|
||||
ivvi.vlan_proto = htobe16(sr_iov->vlan_proto);
|
||||
|
||||
r = sd_netlink_message_open_container(req, IFLA_VF_VLAN_LIST);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not open IFLA_VF_VLAN_LIST container: %m");
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_VF_VLAN_INFO, &ivvi, sizeof(struct ifla_vf_vlan_info));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_VF_VLAN_INFO: %m");
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not close IFLA_VF_VLAN_LIST container: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not close IFLA_VF_INFO container: %m");
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not close IFLA_VFINFO_LIST container: %m");
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req, sr_iov_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
link->sr_iov_messages++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sr_iov_section_verify(SRIOV *sr_iov) {
|
||||
assert(sr_iov);
|
||||
|
||||
if (section_is_invalid(sr_iov->section))
|
||||
return -EINVAL;
|
||||
|
||||
if (sr_iov->vf == (uint32_t) -1)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s: [SRIOV] section without VirtualFunction= field configured. "
|
||||
"Ignoring [SRIOV] section from line %u.",
|
||||
sr_iov->section->filename, sr_iov->section->line);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_sr_iov_uint32(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
|
||||
Network *network = data;
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = sr_iov_new_static(network, filename, section_line, &sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
if (streq(lvalue, "VirtualFunction"))
|
||||
sr_iov->vf = (uint32_t) -1;
|
||||
else if (streq(lvalue, "VLANId"))
|
||||
sr_iov->vlan = 0;
|
||||
else if (streq(lvalue, "QualityOfService"))
|
||||
sr_iov->qos = 0;
|
||||
else
|
||||
assert_not_reached("Invalid lvalue");
|
||||
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(lvalue, "VLANId")) {
|
||||
if (k == 0 || k > 4095) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid SR-IOV VLANId: %d", k);
|
||||
return 0;
|
||||
}
|
||||
sr_iov->vlan = k;
|
||||
} else if (streq(lvalue, "VirtualFunction")) {
|
||||
if (k >= INT_MAX) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid SR-IOV virtual function: %d", k);
|
||||
return 0;
|
||||
}
|
||||
sr_iov->vf = k;
|
||||
} else if (streq(lvalue, "QualityOfService"))
|
||||
sr_iov->qos = k;
|
||||
else
|
||||
assert_not_reached("Invalid lvalue");
|
||||
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_sr_iov_vlan_proto(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
|
||||
Network *network = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = sr_iov_new_static(network, filename, section_line, &sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isempty(rvalue) || streq(rvalue, "802.1Q"))
|
||||
sr_iov->vlan_proto = ETH_P_8021Q;
|
||||
else if (streq(rvalue, "802.1ad"))
|
||||
sr_iov->vlan_proto = ETH_P_8021AD;
|
||||
else {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Invalid SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_sr_iov_link_state(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
|
||||
Network *network = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = sr_iov_new_static(network, filename, section_line, &sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Unfortunately, SR_IOV_LINK_STATE_DISABLE is 2, not 0. So, we cannot use
|
||||
* DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN() macro. */
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
sr_iov->link_state = _SR_IOV_LINK_STATE_INVALID;
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(rvalue, "auto")) {
|
||||
sr_iov->link_state = SR_IOV_LINK_STATE_AUTO;
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_boolean(rvalue);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sr_iov->link_state = r ? SR_IOV_LINK_STATE_ENABLE : SR_IOV_LINK_STATE_DISABLE;
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_sr_iov_boolean(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
|
||||
Network *network = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = sr_iov_new_static(network, filename, section_line, &sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
if (streq(lvalue, "MACSpoofCheck"))
|
||||
sr_iov->vf_spoof_check_setting = -1;
|
||||
else if (streq(lvalue, "QueryReceiveSideScaling"))
|
||||
sr_iov->query_rss = -1;
|
||||
else if (streq(lvalue, "Trust"))
|
||||
sr_iov->trust = -1;
|
||||
else
|
||||
assert_not_reached("Invalid lvalue");
|
||||
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_boolean(rvalue);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse '%s=', ignoring: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(lvalue, "MACSpoofCheck"))
|
||||
sr_iov->vf_spoof_check_setting = r;
|
||||
else if (streq(lvalue, "QueryReceiveSideScaling"))
|
||||
sr_iov->query_rss = r;
|
||||
else if (streq(lvalue, "Trust"))
|
||||
sr_iov->trust = r;
|
||||
else
|
||||
assert_not_reached("Invalid lvalue");
|
||||
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_sr_iov_mac(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
|
||||
Network *network = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = sr_iov_new_static(network, filename, section_line, &sr_iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
sr_iov->mac = ETHER_ADDR_NULL;
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ether_addr_from_string(rvalue, &sr_iov->mac);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(sr_iov);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
#pragma once
|
||||
|
||||
#include <linux/if_link.h>
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-util.h"
|
||||
|
||||
typedef enum SRIOVLinkState {
|
||||
SR_IOV_LINK_STATE_AUTO = IFLA_VF_LINK_STATE_AUTO,
|
||||
SR_IOV_LINK_STATE_ENABLE = IFLA_VF_LINK_STATE_ENABLE,
|
||||
SR_IOV_LINK_STATE_DISABLE = IFLA_VF_LINK_STATE_DISABLE,
|
||||
_SR_IOV_LINK_STATE_MAX,
|
||||
_SR_IOV_LINK_STATE_INVALID = -1,
|
||||
} SRIOVLinkState;
|
||||
|
||||
typedef struct SRIOV {
|
||||
NetworkConfigSection *section;
|
||||
Network *network;
|
||||
|
||||
uint32_t vf; /* 0 - 2147483646 */
|
||||
uint32_t vlan; /* 0 - 4095, 0 disables VLAN filter */
|
||||
uint32_t qos;
|
||||
uint16_t vlan_proto; /* ETH_P_8021Q or ETH_P_8021AD */
|
||||
int vf_spoof_check_setting;
|
||||
int query_rss;
|
||||
int trust;
|
||||
SRIOVLinkState link_state;
|
||||
struct ether_addr mac;
|
||||
} SRIOV;
|
||||
|
||||
SRIOV *sr_iov_free(SRIOV *sr_iov);
|
||||
|
||||
int sr_iov_configure(Link *link, SRIOV *sr_iov);
|
||||
int sr_iov_section_verify(SRIOV *sr_iov);
|
||||
|
||||
DEFINE_NETWORK_SECTION_FUNCTIONS(SRIOV, sr_iov_free);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_uint32);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_boolean);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_link_state);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_vlan_proto);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_mac);
|
|
@ -136,14 +136,14 @@ int config_parse_cake_overhead(
|
|||
r = safe_atoi32(rvalue, &v);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse 'Overhead=', ignoring assignment: %s",
|
||||
rvalue);
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (v < -64 || v > 256) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Invalid 'Overhead=', ignoring assignment: %s",
|
||||
rvalue);
|
||||
"Invalid '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ int config_parse_drr_size(
|
|||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1000, &u);
|
||||
r = parse_size(rvalue, 1024, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
|
|
|
@ -140,7 +140,7 @@ int config_parse_bfifo_size(
|
|||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1000, &u);
|
||||
r = parse_size(rvalue, 1024, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "parse-util.h"
|
||||
#include "qdisc.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
static int fair_queueing_controlled_delay_init(QDisc *qdisc) {
|
||||
FairQueueingControlledDelay *fqcd;
|
||||
|
@ -301,15 +302,15 @@ int config_parse_fair_queueing_controlled_delay_size(
|
|||
|
||||
fqcd = FQ_CODEL(qdisc);
|
||||
|
||||
if (streq(lvalue, "MemoryLimit"))
|
||||
if (STR_IN_SET(lvalue, "MemoryLimitBytes", "MemoryLimit"))
|
||||
p = &fqcd->memory_limit;
|
||||
else if (streq(lvalue, "Quantum"))
|
||||
else if (STR_IN_SET(lvalue, "QuantumBytes", "Quantum"))
|
||||
p = &fqcd->quantum;
|
||||
else
|
||||
assert_not_reached("Invalid lvalue.");
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
if (streq(lvalue, "MemoryLimit"))
|
||||
if (STR_IN_SET(lvalue, "MemoryLimitBytes", "MemoryLimit"))
|
||||
*p = UINT32_MAX;
|
||||
else
|
||||
*p = 0;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "netlink-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
|
||||
static int fair_queueing_init(QDisc *qdisc) {
|
||||
FairQueueing *fq;
|
||||
|
@ -198,9 +198,9 @@ int config_parse_fair_queueing_size(
|
|||
|
||||
fq = FQ(qdisc);
|
||||
|
||||
if (streq(lvalue, "Quantum"))
|
||||
if (STR_IN_SET(lvalue, "QuantumBytes", "Quantum"))
|
||||
p = &fq->quantum;
|
||||
else if (streq(lvalue, "InitialQuantum"))
|
||||
else if (STR_IN_SET(lvalue, "InitialQuantumBytes", "InitialQuantum"))
|
||||
p = &fq->initial_quantum;
|
||||
else
|
||||
assert_not_reached("Invalid lvalue");
|
||||
|
|
|
@ -142,7 +142,7 @@ int config_parse_quick_fair_queueing_max_packet(
|
|||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1000, &v);
|
||||
r = parse_size(rvalue, 1024, &v);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#include "parse-util.h"
|
||||
#include "qdisc.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "tc-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int token_bucket_filter_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
|
||||
uint32_t rtab[256], ptab[256];
|
||||
|
@ -143,18 +143,85 @@ int config_parse_token_bucket_filter_size(
|
|||
tbf = TBF(qdisc);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
if (streq(lvalue, "Rate"))
|
||||
tbf->rate = 0;
|
||||
else if (streq(lvalue, "Burst"))
|
||||
if (STR_IN_SET(lvalue, "BurstBytes", "Burst"))
|
||||
tbf->burst = 0;
|
||||
else if (streq(lvalue, "LimitSize"))
|
||||
else if (STR_IN_SET(lvalue, "LimitBytes", "LimitSize"))
|
||||
tbf->limit = 0;
|
||||
else if (streq(lvalue, "MTUBytes"))
|
||||
tbf->mtu = 0;
|
||||
else if (streq(lvalue, "MPUBytes"))
|
||||
tbf->mpu = 0;
|
||||
else if (streq(lvalue, "PeakRate"))
|
||||
tbf->peak_rate = 0;
|
||||
else
|
||||
assert_not_reached("unknown lvalue");
|
||||
|
||||
qdisc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1024, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(lvalue, "BurstBytes", "Burst"))
|
||||
tbf->burst = k;
|
||||
else if (STR_IN_SET(lvalue, "LimitBytes", "LimitSize"))
|
||||
tbf->limit = k;
|
||||
else if (streq(lvalue, "MPUBytes"))
|
||||
tbf->mpu = k;
|
||||
else if (streq(lvalue, "MTUBytes"))
|
||||
tbf->mtu = k;
|
||||
else
|
||||
assert_not_reached("unknown lvalue");
|
||||
|
||||
qdisc = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_token_bucket_filter_rate(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
||||
Network *network = data;
|
||||
TokenBucketFilter *tbf;
|
||||
uint64_t k, *p;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = qdisc_new_static(QDISC_KIND_TBF, network, filename, section_line, &qdisc);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"More than one kind of queueing discipline, ignoring assignment: %m");
|
||||
|
||||
tbf = TBF(qdisc);
|
||||
if (streq(lvalue, "Rate"))
|
||||
p = &tbf->rate;
|
||||
else if (streq(lvalue, "PeakRate"))
|
||||
p = &tbf->peak_rate;
|
||||
else
|
||||
assert_not_reached("unknown lvalue");
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
*p = 0;
|
||||
|
||||
qdisc = NULL;
|
||||
return 0;
|
||||
|
@ -168,18 +235,7 @@ int config_parse_token_bucket_filter_size(
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (streq(lvalue, "Rate"))
|
||||
tbf->rate = k / 8;
|
||||
else if (streq(lvalue, "Burst"))
|
||||
tbf->burst = k;
|
||||
else if (streq(lvalue, "LimitSize"))
|
||||
tbf->limit = k;
|
||||
else if (streq(lvalue, "MPUBytes"))
|
||||
tbf->mpu = k;
|
||||
else if (streq(lvalue, "MTUBytes"))
|
||||
tbf->mtu = k;
|
||||
else if (streq(lvalue, "PeakRate"))
|
||||
tbf->peak_rate = k / 8;
|
||||
*p = k / 8;
|
||||
|
||||
qdisc = NULL;
|
||||
|
||||
|
|
|
@ -23,3 +23,4 @@ extern const QDiscVTable tbf_vtable;
|
|||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_latency);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_size);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_rate);
|
||||
|
|
|
@ -839,7 +839,7 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAns
|
|||
|
||||
rds = p->size - saved_size;
|
||||
|
||||
switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
|
||||
|
@ -1125,7 +1125,7 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAns
|
|||
|
||||
case DNS_TYPE_OPT:
|
||||
case DNS_TYPE_OPENPGPKEY:
|
||||
case _DNS_TYPE_INVALID: /* unparseable */
|
||||
case _DNS_TYPE_INVALID: /* unparsable */
|
||||
default:
|
||||
|
||||
r = dns_packet_append_blob(p, rr->generic.data, rr->generic.data_size, NULL);
|
||||
|
@ -1815,8 +1815,8 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
|
|||
break;
|
||||
} else {
|
||||
dns_packet_rewind(p, pos);
|
||||
rr->unparseable = true;
|
||||
goto unparseable;
|
||||
rr->unparsable = true;
|
||||
goto unparsable;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2059,7 +2059,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
|
|||
case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
|
||||
case DNS_TYPE_OPENPGPKEY:
|
||||
default:
|
||||
unparseable:
|
||||
unparsable:
|
||||
r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);
|
||||
|
||||
break;
|
||||
|
|
|
@ -474,11 +474,11 @@ static DnsResourceRecord* dns_resource_record_free(DnsResourceRecord *rr) {
|
|||
|
||||
case DNS_TYPE_OPENPGPKEY:
|
||||
default:
|
||||
if (!rr->unparseable)
|
||||
if (!rr->unparsable)
|
||||
free(rr->generic.data);
|
||||
}
|
||||
|
||||
if (rr->unparseable)
|
||||
if (rr->unparsable)
|
||||
free(rr->generic.data);
|
||||
|
||||
free(rr->wire_format);
|
||||
|
@ -563,10 +563,10 @@ int dns_resource_record_payload_equal(const DnsResourceRecord *a, const DnsResou
|
|||
|
||||
/* Check if a and b are the same, but don't look at their keys */
|
||||
|
||||
if (a->unparseable != b->unparseable)
|
||||
if (a->unparsable != b->unparsable)
|
||||
return 0;
|
||||
|
||||
switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
|
||||
switch (a->unparsable ? _DNS_TYPE_INVALID : a->key->type) {
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
r = dns_name_equal(a->srv.name, b->srv.name);
|
||||
|
@ -828,7 +828,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
|
|||
|
||||
dns_resource_key_to_string(rr->key, k, sizeof(k));
|
||||
|
||||
switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
r = asprintf(&s, "%s %u %u %u %s",
|
||||
|
@ -1175,7 +1175,7 @@ ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
|
|||
assert(rr);
|
||||
assert(out);
|
||||
|
||||
switch(rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
switch(rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
case DNS_TYPE_SRV:
|
||||
case DNS_TYPE_PTR:
|
||||
case DNS_TYPE_NS:
|
||||
|
@ -1343,7 +1343,7 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
|||
|
||||
dns_resource_key_hash_func(rr->key, state);
|
||||
|
||||
switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
siphash24_compress(&rr->srv.priority, sizeof(rr->srv.priority), state);
|
||||
|
@ -1510,9 +1510,9 @@ DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr) {
|
|||
copy->expiry = rr->expiry;
|
||||
copy->n_skip_labels_signer = rr->n_skip_labels_signer;
|
||||
copy->n_skip_labels_source = rr->n_skip_labels_source;
|
||||
copy->unparseable = rr->unparseable;
|
||||
copy->unparsable = rr->unparsable;
|
||||
|
||||
switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
|
||||
|
||||
case DNS_TYPE_SRV:
|
||||
copy->srv.priority = rr->srv.priority;
|
||||
|
|
|
@ -102,7 +102,7 @@ struct DnsResourceRecord {
|
|||
/* How many labels to strip to determine "synthesizing source" of this RR, i.e. the wildcard's immediate parent. -1 if not signed. */
|
||||
unsigned n_skip_labels_source;
|
||||
|
||||
bool unparseable:1;
|
||||
bool unparsable:1;
|
||||
|
||||
bool wire_format_canonical:1;
|
||||
void *wire_format;
|
||||
|
|
|
@ -190,7 +190,7 @@ static int dns_stream_identify(DnsStream *s) {
|
|||
s->ifindex = manager_find_ifindex(s->manager, s->local.sa.sa_family, s->local.sa.sa_family == AF_INET ? (union in_addr_union*) &s->local.in.sin_addr : (union in_addr_union*) &s->local.in6.sin6_addr);
|
||||
|
||||
if (s->protocol == DNS_PROTOCOL_LLMNR && s->ifindex > 0) {
|
||||
uint32_t ifindex = htobe32(s->ifindex);
|
||||
be32_t ifindex = htobe32(s->ifindex);
|
||||
|
||||
/* Make sure all packets for this connection are sent on the same interface */
|
||||
if (s->local.sa.sa_family == AF_INET) {
|
||||
|
|
|
@ -387,7 +387,7 @@ DEFINE_TRIVIAL_REF_UNREF_FUNC(Varlink, varlink, varlink_destroy);
|
|||
static int varlink_test_disconnect(Varlink *v) {
|
||||
assert(v);
|
||||
|
||||
/* Tests whether we the the connection has been terminated. We are careful to not stop processing it
|
||||
/* Tests whether we the connection has been terminated. We are careful to not stop processing it
|
||||
* prematurely, since we want to handle half-open connections as well as possible and want to flush
|
||||
* out and read data before we close down if we can. */
|
||||
|
||||
|
|
|
@ -38,6 +38,16 @@ MTUBytes=
|
|||
Multicast=
|
||||
MACAddress=
|
||||
Group=
|
||||
[SR-IOV]
|
||||
VirtualFunction=
|
||||
MACSpoofCheck=
|
||||
VLANId=
|
||||
VLANProtocol=
|
||||
QualityOfService=
|
||||
QueryReceiveSideScaling=
|
||||
Trust=
|
||||
LinkState=
|
||||
MACAddress=
|
||||
[BridgeFDB]
|
||||
VLANId=
|
||||
MACAddress=
|
||||
|
@ -322,7 +332,9 @@ PacketLimit=
|
|||
Parent=
|
||||
Handle=
|
||||
Rate=
|
||||
BurstBytes=
|
||||
Burst=
|
||||
LimitBytes=
|
||||
LimitSize=
|
||||
MTUBytes=
|
||||
MPUBytes=
|
||||
|
@ -336,8 +348,10 @@ PerturbPeriodSec=
|
|||
Parent=
|
||||
Handle=
|
||||
PacketLimit=
|
||||
MemoryLimitBytes=
|
||||
MemoryLimit=
|
||||
Flows=
|
||||
QuantumBytes=
|
||||
Quantum=
|
||||
TargetSec=
|
||||
IntervalSec=
|
||||
|
@ -348,7 +362,9 @@ Parent=
|
|||
Handle=
|
||||
PacketLimit=
|
||||
FlowLimit=
|
||||
QuantumBytes=
|
||||
Quantum=
|
||||
InitialQuantumBytes=
|
||||
InitialQuantum=
|
||||
MaximumRate=
|
||||
Buckets=
|
||||
|
@ -367,7 +383,7 @@ ECN=
|
|||
Parent=
|
||||
Handle=
|
||||
Bandwidth=
|
||||
Overhead=
|
||||
OverheadBytes=
|
||||
[TrafficControlQueueingDiscipline]
|
||||
Parent=
|
||||
NetworkEmulatorDelaySec=
|
||||
|
@ -398,7 +414,7 @@ CeilBufferBytes=
|
|||
[BFIFO]
|
||||
Parent=
|
||||
Handle=
|
||||
LimitSize=
|
||||
LimitBytes=
|
||||
[PFIFO]
|
||||
Parent=
|
||||
Handle=
|
||||
|
@ -431,14 +447,14 @@ Handle=
|
|||
Parent=
|
||||
ClassId=
|
||||
Weight=
|
||||
MaxPacketSize=
|
||||
MaxPacketBytes=
|
||||
[DeficitRoundRobinScheduler]
|
||||
Parent=
|
||||
Handle=
|
||||
[DeficitRoundRobinSchedulerClass]
|
||||
Parent=
|
||||
ClassId=
|
||||
Quantum=
|
||||
QuantumBytes=
|
||||
[EnhancedTransmissionSelection]
|
||||
Parent=
|
||||
Handle=
|
||||
|
|
|
@ -8,5 +8,5 @@ Address=10.1.2.3/16
|
|||
[CAKE]
|
||||
Parent=root
|
||||
Handle=3a
|
||||
Overhead=128
|
||||
OverheadBytes=128
|
||||
Bandwidth=500M
|
||||
|
|
|
@ -58,8 +58,8 @@ Parent=2:32
|
|||
Handle=0032
|
||||
PacketLimit=1000
|
||||
FlowLimit=200
|
||||
Quantum=1500
|
||||
InitialQuantum=13000
|
||||
QuantumBytes=1500
|
||||
InitialQuantumBytes=13000
|
||||
MaximumRate=1M
|
||||
Buckets=512
|
||||
OrphanMask=511
|
||||
|
@ -93,11 +93,11 @@ CeilRate=0.5M
|
|||
Parent=2:34
|
||||
Handle=0034
|
||||
PacketLimit=20480
|
||||
MemoryLimit=64M
|
||||
MemoryLimitBytes=64M
|
||||
Flows=2048
|
||||
TargetSec=10ms
|
||||
IntervalSec=200ms
|
||||
Quantum=1400
|
||||
QuantumBytes=1400
|
||||
ECN=yes
|
||||
CEThresholdSec=100ms
|
||||
|
||||
|
@ -112,10 +112,10 @@ CeilRate=0.5M
|
|||
Parent=2:35
|
||||
Handle=0035
|
||||
Rate=1G
|
||||
Burst=5K
|
||||
BurstBytes=5000
|
||||
LatencySec=70msec
|
||||
PeakRate=100G
|
||||
MTUBytes=1M
|
||||
MTUBytes=1000000
|
||||
|
||||
[HierarchyTokenBucketClass]
|
||||
Parent=root
|
||||
|
@ -177,7 +177,7 @@ CeilRate=0.5M
|
|||
[BFIFO]
|
||||
Parent=2:3a
|
||||
Handle=003a
|
||||
LimitSize=1M
|
||||
LimitBytes=1000000
|
||||
|
||||
[HierarchyTokenBucketClass]
|
||||
Parent=root
|
||||
|
|
|
@ -12,4 +12,4 @@ Handle=0002
|
|||
[DeficitRoundRobinSchedulerClass]
|
||||
Parent=root
|
||||
ClassId=0002:0030
|
||||
Quantum=2000
|
||||
QuantumBytes=2000
|
||||
|
|
|
@ -13,10 +13,10 @@ Handle=0002
|
|||
Parent=root
|
||||
ClassId=0002:0030
|
||||
Weight=2
|
||||
MaxPacketSize=16000
|
||||
MaxPacketBytes=16000
|
||||
|
||||
[QuickFairQueueingClass]
|
||||
Parent=root
|
||||
ClassId=0002:0031
|
||||
Weight=10
|
||||
MaxPacketSize=8000
|
||||
MaxPacketBytes=8000
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
[Match]
|
||||
Name=eni99np1
|
||||
|
||||
[Network]
|
||||
Address=192.168.100.100/24
|
||||
|
||||
[SR-IOV]
|
||||
VirtualFunction=0
|
||||
VLANId=5
|
||||
VLANProtocol=802.1ad
|
||||
QualityOfService=1
|
||||
MACSpoofCheck=yes
|
||||
QueryReceiveSideScaling=yes
|
||||
Trust=yes
|
||||
LinkState=yes
|
||||
MACAddress=00:11:22:33:44:55
|
||||
|
||||
[SR-IOV]
|
||||
VirtualFunction=1
|
||||
VLANId=6
|
||||
VLANProtocol=802.1Q
|
||||
QualityOfService=2
|
||||
MACSpoofCheck=no
|
||||
QueryReceiveSideScaling=no
|
||||
Trust=no
|
||||
LinkState=no
|
||||
MACAddress=00:11:22:33:44:56
|
||||
|
||||
[SR-IOV]
|
||||
VirtualFunction=2
|
||||
VLANId=7
|
||||
QualityOfService=3
|
||||
MACSpoofCheck=no
|
||||
QueryReceiveSideScaling=no
|
||||
Trust=no
|
||||
LinkState=auto
|
||||
MACAddress=00:11:22:33:44:57
|
|
@ -158,6 +158,33 @@ def expectedFailureIfAlternativeNameIsNotAvailable():
|
|||
|
||||
return f
|
||||
|
||||
def expectedFailureIfNetdevsimWithSRIOVIsNotAvailable():
|
||||
def f(func):
|
||||
call('rmmod netdevsim', stderr=subprocess.DEVNULL)
|
||||
rc = call('modprobe netdevsim', stderr=subprocess.DEVNULL)
|
||||
if rc != 0:
|
||||
return unittest.expectedFailure(func)
|
||||
|
||||
try:
|
||||
with open('/sys/bus/netdevsim/new_device', mode='w') as f:
|
||||
f.write('99 1')
|
||||
except Exception as error:
|
||||
return unittest.expectedFailure(func)
|
||||
|
||||
call('udevadm settle')
|
||||
call('udevadm info -w10s /sys/devices/netdevsim99/net/eni99np1', stderr=subprocess.DEVNULL)
|
||||
try:
|
||||
with open('/sys/class/net/eni99np1/device/sriov_numvfs', mode='w') as f:
|
||||
f.write('3')
|
||||
except Exception as error:
|
||||
call('rmmod netdevsim', stderr=subprocess.DEVNULL)
|
||||
return unittest.expectedFailure(func)
|
||||
|
||||
call('rmmod netdevsim', stderr=subprocess.DEVNULL)
|
||||
return func
|
||||
|
||||
return f
|
||||
|
||||
def expectedFailureIfCAKEIsNotAvailable():
|
||||
def f(func):
|
||||
call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
|
||||
|
@ -1695,6 +1722,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
'25-route-vrf.network',
|
||||
'25-gateway-static.network',
|
||||
'25-gateway-next-static.network',
|
||||
'25-sriov.network',
|
||||
'25-sysctl-disable-ipv6.network',
|
||||
'25-sysctl.network',
|
||||
'25-test1.network',
|
||||
|
@ -2237,7 +2265,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'inet6 .* scope link')
|
||||
output = check_output('ip -4 route show dev dummy98')
|
||||
print(output)
|
||||
self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
|
||||
self.assertRegex(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
|
||||
output = check_output('ip -6 route show dev dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
|
||||
|
@ -2260,7 +2288,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'inet6 .* scope link')
|
||||
output = check_output('ip -4 route show dev dummy98')
|
||||
print(output)
|
||||
self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
|
||||
self.assertRegex(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
|
||||
output = check_output('ip -6 route show dev dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
|
||||
|
@ -2508,6 +2536,32 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'quanta 1 2 3 4 5')
|
||||
self.assertRegex(output, 'priomap 3 4 5 6 7')
|
||||
|
||||
@expectedFailureIfNetdevsimWithSRIOVIsNotAvailable()
|
||||
def test_sriov(self):
|
||||
call('rmmod netdevsim', stderr=subprocess.DEVNULL)
|
||||
call('modprobe netdevsim', stderr=subprocess.DEVNULL)
|
||||
with open('/sys/bus/netdevsim/new_device', mode='w') as f:
|
||||
f.write('99 1')
|
||||
|
||||
call('udevadm settle')
|
||||
call('udevadm info -w10s /sys/devices/netdevsim99/net/eni99np1', stderr=subprocess.DEVNULL)
|
||||
with open('/sys/class/net/eni99np1/device/sriov_numvfs', mode='w') as f:
|
||||
f.write('3')
|
||||
|
||||
copy_unit_to_networkd_unit_path('25-sriov.network')
|
||||
start_networkd()
|
||||
self.wait_online(['eni99np1:routable'])
|
||||
|
||||
output = check_output('ip link show dev eni99np1')
|
||||
print(output)
|
||||
self.assertRegex(output,
|
||||
'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
|
||||
'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
|
||||
'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off'
|
||||
)
|
||||
|
||||
call('rmmod netdevsim', stderr=subprocess.DEVNULL)
|
||||
|
||||
class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
||||
links = [
|
||||
'dummy98',
|
||||
|
|
Loading…
Reference in New Issue