Commit graph

945 commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 717e8eda77
Merge pull request #12475 from yuwata/network-fix-12452
network: add network_ref/_unref() and make Link object take a reference of Network object
2019-05-07 20:03:22 +02:00
Susant Sahani 715cedfbf0 networkd: Allow DHCP4 client to set the number to attempt to reconfigure.
Otherwise current value is 6 and after 6 it will give up.
2019-05-07 17:12:04 +02:00
Yu Watanabe 62bbbedf73 sd-radv: fix memleak
Fixes one memleak found in #12452.
2019-05-07 16:55:19 +02:00
Yu Watanabe 11793fcd63 sd-dhcp: store number of trial in sd_dhcp_client::attempt
Calling 2^n as attempt is misleading.
2019-05-07 04:08:33 +02:00
Susant Sahani 8bc17bb3f7 networkd: Option to use LinkLocalAddressing only when DHCP fails
When LinkLocalAddressing=fallback or LinkLocalAddressing=ipv4-fallback
then IPv4LL will be started only when DHCP fails.

Closes #9648.
2019-05-04 16:45:57 +02:00
Lennart Poettering 0892f3f999
Merge pull request #12420 from mrc0mmand/coccinelle-tweaks
Coccinelle improvements
2019-04-30 11:37:19 +02:00
Ben Boeckel 5238e95759 codespell: fix spelling errors 2019-04-29 16:47:18 +02:00
Frantisek Sumsal 4e361acc06 tree-wide: replace explicit NULL checks with their shorter variants
Done by coccinelle/equals-null.cocci
2019-04-28 14:28:49 +02:00
Yu Watanabe ae695a9eda arp-util: use net/ethernet.h instead of netinet/if_ether.h
The header net/ethernet.h is used at all other places where
'struct ether_addr' is required.
2019-04-13 17:51:59 +09:00
Zbigniew Jędrzejewski-Szmek 41f6e627d7 Make fopen_temporary and fopen_temporary_label unlocked
This is partially a refactoring, but also makes many more places use
unlocked operations implicitly, i.e. all users of fopen_temporary().
AFAICT, the uses are always for short-lived files which are not shared
externally, and are just used within the same context. Locking is not
necessary.
2019-04-12 11:44:56 +02:00
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