Commit Graph

935 Commits

Author SHA1 Message Date
Yu Watanabe 52cf2b13a0 ipv4ll: do not reset seed generation counter on restart
Fixes #12145.
2019-04-02 10:27:30 +02:00
Zbigniew Jędrzejewski-Szmek ca78ad1de9 headers: remove unneeded includes from util.h
This means we need to include many more headers in various files that simply
included util.h before, but it seems cleaner to do it this way.
2019-03-27 11:53:12 +01:00
Yu Watanabe c4f58deab5 network,udev: split static condition tests from net_match_config() 2019-03-21 23:37:39 +09:00
Yu Watanabe 2bd0da7a05 network: drop unnecessary strdup() 2019-03-21 23:37:39 +09:00
Lennart Poettering 953a02d11b tree-wide: port various users over to socket_bind_to_ifindex() 2019-03-18 12:02:32 +01:00
Lennart Poettering 760877e90c util: split out sorting related calls to new sort-util.[ch] 2019-03-13 12:16:43 +01:00
Lennart Poettering 0a9707187b util: split out memcmp()/memset() related calls into memory-util.[ch]
Just some source rearranging.
2019-03-13 12:16:43 +01:00
Yu Watanabe 23041689ca dhcp: refuse to configure DHCP IAID if the interface is under renaming
systemd-networkd itself does not start dhcp client, but the code
may be used in other projects. So, check that the interface is under
renaming or not.
2019-03-05 12:48:26 +09:00
Zbigniew Jędrzejewski-Szmek f68a26221c tests: use the test helpers in more places
This is mostly cosmetic. It makes those test binaries support SYSTEMD_LOG_*
environment variables.
2019-03-04 14:15:38 +01:00
Beniamino Galvani 22a3fd2da9 dhcp: don't stop receiving packets when the link goes down
When the link goes down, DHCP client_receive_message*() functions return an
error and the related I/O source is removed from the main loop. With the
current implementation of systemd-networkd this doesn't matter because the DHCP
client is always stopped on carrier down and restarted on carrier up. However
it seems wrong to have the DHCP client crippled (because no packet can be
received anymore) once the link goes temporarily down.

Change the receive functions to ignore a ENETDOWN event so that the client will
be able to receive packets again after the link comes back.
2019-02-19 20:19:36 +09:00
Lennart Poettering bde06abd4f
Merge pull request #10408 from keszybz/analyze-cat-presets
systemd-analyze cat-presets
2019-02-18 16:02:45 +01:00
Lennart Poettering 9c5675af76
Merge pull request #11729 from yuwata/fix-11721
sd-device: also store properties read from udev database to sd_device::properties_db
2019-02-18 16:02:26 +01:00
Thomas Haller 189255d2b5 network: avoid inet_ntoa() in favor of inet_ntop()
inet_ntop() is not documented to be thread-safe, so it should not
be used in the DHCP library. Arguably, glibc uses a thread local
buffer, so indeed there is no problem with a suitable libc. Anyway,
just avoid it.
2019-02-18 13:34:22 +01:00
Thomas Haller 072320eab0 dhcp: move filtering of bogus DNS/NTP addresses out of DHCP client
The DHCP client should not pre-filter addresses beyond what RFC
requires. If a client's user (like networkd) wishes to skip/filter
certain addresses, it's their responsibility.

The point of this is that the DHCP library does not hide/abstract
information that might be relevant for certain users. For example,
NetworkManager exposes DHCP options in its API. When doing that, the
options should be close to the actual lease.

This is related to commit d9ec2e632d
(dhcp4: filter bogus DNS/NTP server addresses silently).
2019-02-18 13:34:22 +01:00
Thomas Haller f8862395e8 dhcp: handle multiple addresses for "Router" (option 3) in DHCP library
The Router DHCP option may contain a list of one or more
routers ([1]). Extend the API of sd_dhcp_lease to return a
list instead of only the first.

Note that networkd still only uses the first router (if present).
Aside from extending the internal API of the DHCP client, there
is almost no change in behavior. The only visible difference in
behavior is that the "ROUTER" variable in the lease file is now a
list of addresses.

Note how RFC 2132 does not define certain IP addresses as invalid for the
router option. Still, previously sd_dhcp_lease_get_router() would never
return a "0.0.0.0" address. In fact, the previous API could not
differenciate whether no router option was present, whether it
was invalid, or whether its first router was "0.0.0.0". No longer let
the DHCP client library impose additional restrictions that are not
part of RFC. Instead, the caller should handle this. The patch does
that, and networkd only consideres the first router entry if it is not
"0.0.0.0".

[1] https://tools.ietf.org/html/rfc2132#section-3.5
2019-02-18 13:34:22 +01:00
Thomas Haller c24b682162 network: don't return allocated buffer of zero length from deserialize_in_addrs()
deserialize_in_addrs() allocates the buffer before trying to parse
the IP address. Since a parsing error is silently ignored, the returned
size might be zero. In such a case we shouldn't return any buffer.

Anyway, there was no leak, because there are only two callers like

    r = deserialize_in_addrs(&lease->dns, dns);

which both keep the unused buffer and later release it.

Note that deserialize_in_addrs() doesn't free the pointer before
reassigning the new output. The caller must take care to to pass
"ret" with an allocated buffer that would be leaked when returning
the result.
2019-02-18 13:32:06 +01:00
Zbigniew Jędrzejewski-Szmek dc0d407851 udev,network: use standard paths for .network and .link files
This centralizes the configuration to one header file.
/usr/local/lib is now included in the search list, and documentation is
updated accordingly.
2019-02-18 10:29:33 +01:00
Yu Watanabe 4f4daf418f udev,network: drop unused parent_driver argument from net_match_config()
The argument has never been used.
2019-02-17 00:47:49 +09:00
Thomas Haller 13f1fd0376 dhcp: ignore padding of 'chaddr' in DHCP server response
The "chaddr" field is 16 bytes long, with "hlen" being the
length of the address.

https://tools.ietf.org/html/rfc2131#section-4.3.1 says:

    The server MUST return to the client:

    ...

    o Any parameters specific to this client (as identified by
      the contents of 'chaddr' or 'client identifier' in the DHCPDISCOVER
      or DHCPREQUEST message), e.g., as configured by the network
      administrator,

It's not clear, whether only the first 'hlen' bytes of 'chaddr'
must correspond or all 16 bytes.

Note that https://tools.ietf.org/html/rfc4390#section-2.1 says for IPoIB

    "chaddr" (client hardware address) field MUST be zeroed.

with having "hlen" zero. This indicates that at least in this case, the
bytes after "hlen" would matter.

As the DHCP client always sets the trailing bytes to zero, we would expect
that the server also replies as such and we could just compare all 16 bytes.
However, let's be liberal and accept any padding here.

This in practice only changes behavior for infiniband, where we
previously would enforce that the first ETH_ALEN bytes are zero.
That seems arbitrary for IPoIB. We should either check all bytes or
none of them. Let's do the latter and don't enforce RFC 4390 in this
regard.
2019-02-15 11:41:06 +01:00
Lennart Poettering e5d21c24a0
Merge pull request #11382 from keszybz/udev-predictable-macs
Allow MACAddressPolicy=persistent for all virtual devices
2019-02-15 11:31:25 +01:00
Lennart Poettering eb7e351496
Merge pull request #11578 from keszybz/gcc-9-fixes
Packed struct alignment workarounds for gcc-9
2019-02-07 15:25:05 +01:00
Zbigniew Jędrzejewski-Szmek e27b9aba30 libsystemd-network: remove _packed_ attribute to appease the compiler
gcc-9 warns whenever the elements of a structure defined with _packed_ are used:

../src/network/networkd-dhcp6.c: In function ‘dhcp6_pd_prefix_assign’:
../src/network/networkd-dhcp6.c:92:53: warning: taking address of packed member of ‘struct <anonymous>’ may result in an unaligned pointer value [-Waddress-of-packed-member]
   92 |         r = manager_dhcp6_prefix_add(link->manager, &p->opt.in6_addr, link);
      |                                                     ^~~~~~~~~~~~~~~~

And the compiler is right, because in principle the alignment could be wrong.
In this particular case it is not, because the structure is carefully defined
not to have holes. Let's remove _packed_ and use compile-time asserts to verify
that the offsets are not changed.
2019-02-04 20:32:44 +01:00
Lennart Poettering 6e9417f5b4 tree-wide: use newa() instead of alloca() wherever we can
Typesafety is nice. And this way we can take benefit of the new size
assert() the previous commit added.
2019-01-26 16:17:04 +01:00
Thomas Haller 01dab40ba5 dhcp/trivial: fix spelling error in comment 2019-01-25 20:29:39 +09:00
Zbigniew Jędrzejewski-Szmek 6d36464065 udev,networkd: use the interface name as fallback basis for MAC and IPv4LL seed
Fixes #3374. The problem is that we set MACPolicy=persistent (i.e. we would
like to generate persistent MAC addresses for interfaces which don't have a
fixed MAC address), but various virtual interfaces including bridges, tun/tap,
bonds, etc., do not not have the necessary ID_NET_NAME_* attributes and udev
would not assing the address and warn:
  Could not generate persistent MAC address for $name: No such file or directory

Basic requirements which I think a solution for this needs to satisfy:

1. No changes to MAC address generation for those cases which are currently
  handled successfully. This means that net_get_unique_predictable_data() must
  keep returning the same answer, which in turn means net_get_name() must keep
  returning the same answer. We can only add more things we look at with lower
  priority so that we start to cover cases which were not covered before.

2. Like 1, but for IPvLL seed and DHCP IAD. This is less important, but "nice
  to have".

3. Keep MACPolicy=persistent. If people don't want it, they can always apply
  local configuration, but in general stable MACs are a good thing. I have never
  seen anyone complain about that.

== Various approaches that have been proposed

=== https://github.com/systemd/systemd/issues/3374#issuecomment-223753264 (tomty89)
if !ID_BUS and INTERFACE, use INTERFACE

I think this almost does the good thing, but I don't see the reason to reject ID_BUS
(i.e. physical hardware). Stable MACs are very useful for physical hardware that has
no physical MAC.

=== https://github.com/systemd/systemd/issues/3374#issuecomment-224733069 (teg)
if (should_rename(device, true))

This means looking at name_assign_type. In particular for
NET_NAME_USER should_rename(..., true) returns true. It only returns false
for NET_NAME_PREDICTABLE. So this would cover stuff like br0, bond0, etc,
but would not cover lo and other devices with predictable names. That doesn't
make much sense.

But did teg mean should_rename() or !should_rename()?

=== https://github.com/systemd/systemd/issues/3374#issuecomment-234628502 (tomty89):
+ if (!should_rename(device, true))
+        return udev_device_get_sysname(device)

This covers only devices with NET_NAME_PREDICTABLE. Since the problem applies as
much to bridges and such, this isn't neough.

=== https://github.com/systemd/systemd/issues/3374#issuecomment-281745967  (grafi-tt)
+        /* if the machine doesn't provide data about the device, use the ifname specified by userspace
+        * (this is the case when the device is virtual, e.g., bridge or bond) */
+        s = udev_device_get_sysattr_value(device, "name_assign_type");
+        if (s && safe_atou(s, &type) >= 0 && type == NET_NAME_USER)
+                return udev_device_get_sysname(device);

This does not cover bond0, vnet0, tun/tap and similar.
grafi-tt also proposes patching the kernel, but *not* setting name_assign_type
seems intentional in those cases, because the device name is a result of
enumeration, not set by the userspace.

=== https://github.com/systemd/systemd/issues/3374#issuecomment-288882355 (tomty89)
(also PR #11372)
- MACAddressPolicy=persistent

This break requirement 3. above. It would solve the immediate problem, but I
think the disruption is too big.

=== This patch

This patch means that we will set a "stable" MAC for pretty much any virtual
device by default, where "stable" means keyed off the machine-id and interface
name.

It seems like a big change, but we already did this for most physical devices.
Doing it also for virtual devices doesn't seem like a big issue. It will make
the setup and monitoring of virtualized networks slightly nicer. I don't think
anyone is depending on having the MAC address changed when those devices are
destoryed and recreated. If they do, they'd have to change MACAddressPolicy=.

== Implementation
net_get_name() is called from dhcp_ident_set_iaid() so I didn't change
net_get_name() like in grafi-tt's patch, but net_get_unique_predictable_data().

net_get_unique_predictable_data() is called from get_mac() in link-config.c
and sd_ipv4ll_set_address_seed(), so both of those code paths are affected
and will now get data in some cases where they errored out previously.

The return code is changed to -ENODATA since that gives a nicer error string.
2019-01-21 17:33:09 +01:00
Zbigniew Jędrzejewski-Szmek 29cf0ff823 libsystemd-network: use xsprintf in one more place
DECIMAL_STR_MAX includes space for NUL, so we don't need 2 here.
2019-01-16 13:34:31 +01:00
Topi Miettinen 7ae3561a5a Delete duplicate lines
Found by inspecting results of running this small program:

int main(int argc, const char **argv) {
	for (int i = 1; i < argc; i++) {
		FILE *f;
		char line[1024], prev[1024], *r;
		int lineno;

		prev[0] = '\0';
		lineno = 1;
		f = fopen(argv[i], "r");
		if (!f)
			exit(1);
		do {
			r = fgets(line, sizeof(line), f);
			if (!r)
				break;
			if (strcmp(line, prev) == 0)
				printf("%s:%d: error: dup %s", argv[i], lineno, line);
			lineno++;
			strcpy(prev, line);
		} while (!feof(f));
		fclose(f);
	}
}
2019-01-12 16:02:26 +01:00
Lennart Poettering 5f99550afe
Merge pull request #11241 from bengal/lldp-802-3-subtypes
lldp: add 802.3 OUI subtype definitions
2019-01-06 18:15:51 +01:00
Zbigniew Jędrzejewski-Szmek 4199f6896a Use c99 static array size declarations in exported functions too
It seems quite useful to provide this additional information in public exported
functions.

This is a c99 feature, not supported in C++. Without the check in _sd-common.h:
FAILED: test-bus-vtable-cc@exe/src_libsystemd_sd-bus_test-bus-vtable-cc.cc.o
...
In file included from ../src/libsystemd/sd-bus/test-bus-vtable-cc.cc:9:
In file included from ../src/systemd/sd-bus-vtable.h:26:
In file included from ../src/systemd/sd-bus.h:26:
../src/systemd/sd-id128.h:38:47: error: static array size is a C99 feature, not permitted in C++
char *sd_id128_to_string(sd_id128_t id, char s[static SD_ID128_STRING_MAX]);
                                              ^

In .c files, I opted to use the define for consistency, even though we don't support
compilation with a C++ compiler, so the unconditional keyword would work too.
2019-01-04 12:37:25 +01:00
Yu Watanabe e4a0fe6343 dhcp: drop unnecessary brackets 2018-12-23 08:00:59 +09:00
Yu Watanabe da3c49e9a8 dhcp: use cast-to-bool for pointers 2018-12-23 08:00:59 +09:00
Yu Watanabe 759248856c dhcp: fix indentation 2018-12-23 08:00:59 +09:00
Beniamino Galvani dc8dc0cf8a lldp: add 802.3 OUI subtype definitions 2018-12-21 17:30:01 +01:00
Thomas Haller ab4a88bc29 dhcp6: don't enforce DUID content for sd_dhcp6_client_set_duid()
There are various functions to set the DUID of a DHCPv6 client.
However, none of them allows to set arbitrary data. The closest is
sd_dhcp6_client_set_duid(), which would still do validation of the
DUID's content via dhcp_validate_duid_len().

Relax the validation and only log a debug message if the DUID
does not validate.

Note that dhcp_validate_duid_len() already is not very strict. For example
with DUID_TYPE_LLT it only ensures that the length is suitable to contain
hwtype and time. It does not further check that the length of hwaddr is non-zero
or suitable for hwtype. Also, non-well-known DUID types are accepted for
extensibility. Why reject certain DUIDs but allowing clearly wrong formats
otherwise?

The validation and failure should happen earlier, when accepting the
unsuitable DUID. At that point, there is more context of what is wrong,
and a better failure reason (or warning) can be reported to the user. Rejecting
the DUID when setting up the DHCPv6 client seems not optimal, in particular
because the DHCPv6 client does not care about actual content of the
DUID and treats it as opaque blob.

Also, NetworkManager (which uses this code) allows to configure the entire
binary DUID in binary. It intentionally does not validate the binary
content any further. Hence, it needs to be able to set _invalid_ DUIDs,
provided that some basic constraints are satisfied (like the maximum length).

sd_dhcp6_client_set_duid() has two callers: both set the DUID obtained
from link_get_duid(), which comes from configuration.
`man networkd.conf` says: "The configured DHCP DUID should conform to
the specification in RFC 3315, RFC 6355.". It does not not state that
it MUST conform.

Note that dhcp_validate_duid_len() has another caller: DHCPv4's
dhcp_client_set_iaid_duid_internal(). In this case, continue with
strict validation, as the callers are more controlled. Also, there is
already sd_dhcp_client_set_client_id() which can be used to bypass
this check and set arbitrary client identifiers.
2018-12-20 13:40:39 +01:00
Thomas Haller bfda0d0f09 dhcp: don't enforce hardware address length for sd_dhcp_client_set_client_id()
sd_dhcp_client_set_client_id() is the only API for setting a raw client-id.
All other setters are more restricted and only allow to set a type 255 DUID.

Also, dhcp4_set_client_identifier() is the only caller, which already
does:

                r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                 ARPHRD_ETHER,
                                                 (const uint8_t *) &link->mac,
                                                 sizeof(link->mac));

and hence ensures that the data length is indeed ETH_ALEN.

Drop additional input validation from sd_dhcp_client_set_client_id(). The client-id
is an opaque blob, and if a caller wishes to set type 1 (ethernet) or type 32
(infiniband) with unexpected address length, it should be allowed. The actual
client-id is not relevant to the DHCP client, and it's the responsibility of the
caller to generate a suitable client-id.

For example, in NetworkManager you can configure all the bytes of the
client-id, including such _invalid_ settings. I think it makes sense,
to allow the user to fully configure the identifier. Even if such configuration
would be rejected, it would be the responsibility of the higher layers (including
a sensible error message to the user) and not fail later during
sd_dhcp_client_set_client_id().

Still log a debug message if the length is unexpected.
2018-12-20 13:31:48 +01:00
Thomas Haller b9d8071458 dhcp: fix sd_dhcp_client_set_client_id() for infiniband addresses
Infiniband addresses are 20 bytes (INFINIBAND_ALEN), but only the last
8 bytes are suitable for putting into the client-id.

This bug had no effect for networkd, because sd_dhcp_client_set_client_id()
has only one caller which always uses ARPHRD_ETHER type.

I was unable to find good references for why this is correct ([1]). Fedora/RHEL
has patches for ISC dhclient that also only use the last 8 bytes ([2], [3]).
RFC 4390 (Dynamic Host Configuration Protocol (DHCP) over InfiniBand) [4] does
not discuss the content of the client-id either.

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1658057#c29
[2] https://bugzilla.redhat.com/show_bug.cgi?id=660681
[3] 3ccf3c8d81/f/dhcp-lpf-ib.patch
[4] https://tools.ietf.org/html/rfc4390
2018-12-20 13:15:49 +01:00
Filipe Brandenburger 7f09920585 lldp: add test coverage for sd_lldp_get_neighbors() with multiple neighbors
In particular, check that the order of the results is consistent.

This test coverage will be useful in order to refactor the compare_func
used while sorting the results.

When introduced, this test also uncovered a memory leak in sd_lldp_stop(),
which was then fixed by a separate commit using a specialized function
as destructor of the LLDP Hashmap.

Tested:
  $ ninja -C build/ test
  $ valgrind --leak-check=full build/test-lldp
2018-12-18 11:28:10 +01:00
Lennart Poettering 8ae1a821b3 sd-lldp: accept if a neighbor is already removed from the hashtable 2018-12-18 11:28:10 +01:00
Filipe Brandenburger fc833520e4 Revert "lldp: add test coverage for sd_lldp_get_neighbors() with multiple neighbors"
This reverts commit dd102e4d0c.

That test case exposed a memory leak and breaks CI, so let's revert it until
the original issue is fixed, to prevent disruption of automated testing.
2018-12-15 20:58:39 +03:00
Filipe Brandenburger dc6bf94d68 lldp: simplify compare_func, using ?: to chain comparisons
The ?: operator is very useful for chaining comparison functions
(strcmp, memcmp, CMP), since its behavior is to return the result
of the comparison function call if non-zero, or continue evaluating
the chain of comparison functions.

This simplifies the code in that using a temporary `r` variable
to store the function results is no longer necessary and the checks
for non-zero to return are no longer needed either, resulting in a
typical three-fold reduction to the number of lines in the code.

Introduce a new memcmp_nn() to compare two memory buffers in
lexicographic order, taking length in consideration.

Tested: $ ninja -C build/ test

All test cases pass. In particular, test_multiple_neighbors_sorted()
in test-lldp would catch regressions introduced by this commit.
2018-12-14 09:18:42 -08:00
Filipe Brandenburger dd102e4d0c lldp: add test coverage for sd_lldp_get_neighbors() with multiple neighbors
In particular, check that the order of the results is consistent.

This test coverage will be useful in order to refactor the compare_func
used while sorting the results.

Tested: ninja -C build/ test
2018-12-14 09:18:01 -08:00
Thomas Haller 8217ed5ec3 network: fix handling of uninitialized and zero IAID setting
An earlier commit 0e408b82b (dhcp6-client: handle IAID with value zero)
introduced a flag to sd_dhcp6_client to distinguish between an unset
IAID and a value set to zero.

However, that was not sufficient and broke leaving the setting
uninitialized in networkd configuration. The configuration parsing
also must distinguish between the default, unset value and an
explict zero configuration.

Fixes: 0e408b82b8
2018-12-10 14:25:28 +01:00
Lennart Poettering ec68d13789
Merge pull request #10897 from keszybz/etc-fstab-parsing
Forbid dashes in hostnames and /etc/fstab parsing improvements
2018-12-10 12:31:30 +01:00
Zbigniew Jędrzejewski-Szmek 7470cc4c73 resolve: reject host names with leading or trailing dashes in /etc/hosts
https://tools.ietf.org/html/rfc1035#section-2.3.1 says (approximately)
that only letters, numbers, and non-leading non-trailing dashes are allowed
(for entries with A/AAAA records). We set no restrictions.

hosts(5) says:
> Host names may contain only alphanumeric characters, minus signs ("-"), and
> periods (".").  They must begin with an alphabetic character and end with an
> alphanumeric character.

nss-files follows those rules, and will ignore names in /etc/hosts that do not
follow this rule.

Let's follow the documented rules for /etc/hosts. In particular, this makes us
consitent with nss-files, reducing surprises for the user.

I'm pretty sure we should apply stricter filtering to names received over DNS
and LLMNR and MDNS, but it's a bigger project, because the rules differ
depepending on which level the label appears (rules for top-level names are
stricter), and this patch takes the minimalistic approach and only changes
behaviour for /etc/hosts.

Escape syntax is also disallowed in /etc/hosts, even if the resulting character
would be allowed. Other tools that parse /etc/hosts do not support this, and
there is no need to use it because no allowed characters benefit from escaping.
2018-12-10 09:56:56 +01:00
Yu Watanabe ef118d00eb util: drop missing.h from socket-util.h 2018-12-06 13:31:16 +01:00
Yu Watanabe 36dd5ffd5d util: drop missing.h from util.h 2018-12-04 10:00:34 +01:00
Lennart Poettering 76b31bbb24
Merge pull request #10920 from yuwata/hashmap-destructor
hashmap: make hashmap_free() call destructors of key or value
2018-12-03 17:59:44 +01:00
Lennart Poettering 686d13b9f2 util-lib: split out env file parsing code into env-file.c
It's quite complex, let's split this out.

No code changes, just some file rearranging.
2018-12-02 13:22:29 +01:00
Lennart Poettering e4de72876e util-lib: split out all temporary file related calls into tmpfiles-util.c
This splits out a bunch of functions from fileio.c that have to do with
temporary files. Simply to make the header files a bit shorter, and to
group things more nicely.

No code changes, just some rearranging of source files.
2018-12-02 13:22:29 +01:00
Yu Watanabe 8276855e48 lldp: rename lldp_neighbor_id_hash_ops and set value destructor 2018-12-02 12:18:54 +01:00