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.
Since sd_dhcp_lease_get_routes() returns the list of all routes,
the caller may need to differenciate whether the route was option
33 (static-routes) or 121 (classless-static-route).
Add an accessor for the internal field.
config_parse_iaid(), dhcp_identifier_set_iaid() and sd_dhcp6_client_set_iaid() all
allow for the IAID to be zero. Also, RFC 3315 makes no mention that zero
would be invalid.
However, client_ensure_iaid() would take an IAID of zero as a sign that
the values was unset. Fix that by keeping track whether IAID is
initialized.
Ideally, coccinelle would strip unnecessary braces too. But I do not see any
option in coccinelle for this, so instead, I edited the patch text using
search&replace to remove the braces. Unfortunately this is not fully automatic,
in particular it didn't deal well with if-else-if-else blocks and ifdefs, so
there is an increased likelikehood be some bugs in such spots.
I also removed part of the patch that coccinelle generated for udev, where we
returns -1 for failure. This should be fixed independently.
In certain cases the timeouts may not have been unref'ed before they
need to be re-added. Add the appropriate unref calls to ensure we don't
register the timeout multiple times.
This fixes possible cases where timeouts are triggered multiple times
and even on destroyed DHCPv6 clients.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/73Fixes#10749.
Now that we don't (mis-)use the env file parser to parse kernel command
lines there's no need anymore to override the used newline character
set. Let's hence drop the argument and just "\n\r" always. This nicely
simplifies our code.
The previous code did htole64() followed by unaligned_write_be32() (the
XOR and shift in between is endianness agnostic). That means, on every
architeture there is always exactly one byte swap and the iaid is
dependent on endianness.
Since dhcp_identifier_set_iaid() is part of the DUID generation
algorithm, this cannot be fixed without changing the client-id.
In particular, as the client-id already depends on the machine-id (and
is thus inherrently host-specific), it is better to stick to the current
behavior.
However, add a parameter to switch between old and new behaviour.
Since the new behavior is unused, the only real purpose of this
change is to self-document the oddity of the function.
Fixes: 933f9caeeb
This doesn't change anything in the generated source, but I think makes
semantically more sense, as these structures have undefined size, and we
only want to know the size up to the data field in these cases.
All over the place we define local variables for the various sockopts
that take a bool-like "int" value. Sometimes they are const, sometimes
static, sometimes both, sometimes neither.
Let's clean this up, introduce a common const variable "const_int_one"
(as well as one matching "const_int_zero") and use it everywhere, all
acorss the codebase.
Arguably, libsystemd-network is (still) entirely internal API.
However there is the aim of maybe exposing it as public API.
For that reason, it cannot include internal headers from
"src/basic/".
Note how files "src/systemd/sd-*.h" don't include any systemd
headers which don't themself have an "sd-" prefix.
Fixes: d89a400ed6
According to our CODING_STYLE our library code should generally not log
beyond LOG_DEBUG. Let's hence get rid of log_radv_warning_errno() and
just use log_radv_errno() instead.
The code handling the errors was originally part of ndisc_recv, which,
being an event handler, would be simply turned off if it returned a negative
error code. It's no longer necessary. Plus, it helps avoid passing
an uninitialized value to radv_send.
Closes https://github.com/systemd/systemd/issues/10223.
Since we now have the possibility to request prefixes to be delegated
without corresponding IPv6 addresses, it does not make sense to store
lease T1 and T2 timeouts in the otherwise unused IA_NA structure.
Therefore lease timeouts T1 and T2 are moved to the DHCPv6 client
structure, as there will be only one set of stateful timeouts required
by RFC 7550, Section 4.3.
Select T1 and T2 timeouts based on whether addresses or prefixes were
requested and what the server offered. The address and prefix timeouts
values have been computed earlier when the relevant DHCPv6 options were
parsed.
Add function to fetch the IAID for the delegated IA_PD prefix. In
order to keep things simple in the implemntation, the same IAID
is used with IA_NA addresses and IA_PD prefixes. But the DHCPv6
server can choose to return only IA_PD prefixes, and the client
can nowadays omit requesting of IA_NA addresses. Since the function
fetching said IAID from the lease looks only for IA_NA ones, it
will return an empty IAID, which of course does not match the one
set for prefixes.
Fix this by adding a function returning the IAID for the prefix.
Add function to enable/disable IA_NA address requests. Internally
handle the request as a bit mask and add IA_PD prefix delegation
to the same bit mask instead of having a separate boolean. Thus
the calling code can set requests for prefix and address delegation
separately. This is handy when supporting RFC 7084.
Add a check in the code that at least something is requested from
the server in Managed mode. By default request IA_NA addresses from
the DHCPv6 server. Although a value has been defined for IA_TA,
temporay IA_TA addresses are not yet requested.
Add helper function for fetching enabled/disabled state of Prefix
Delegation for a DHCPv6 client. Update function setting prefix
delegation to use an int instead of a boolean.
Several functions are shared by qsort and hash_ops or Prioq.
This makes these functions explicitly specify argument type,
and cast to __compar_fn_t where necessary.
An assertion in dhcp_network_bind_raw_socket() is triggered when
starting an sd_dhcp_client without setting a MAC address first.
- sd_dhcp_client_start()
- client_start()
- client_start_delayed()
- dhcp_network_bind_raw_socket()
In that case, the arp-type and MAC address is still unset. Note that
dhcp_network_bind_raw_socket() already checks for a valid arp-type
and MAC address below, so we should just gracefully return -EINVAL.
Maybe sd_dhcp_client_start() should fail earlier when starting without
MAC address. But the failure here will be correctly propagated and
the start aborted.
Fixes: 76253e73f9
Looked for definitions of functions using the *_compare_func() suffix.
Tested:
- Unit tests passed (ninja -C build/ test)
- Installed this build and booted with it.
Prior to this commit, a .link file with a [Match] section containing
MACAddress= would match any device without a MAC. This restores the
matching logic prior to e90d037.
These lines are generally out-of-date, incomplete and unnecessary. With
SPDX and git repository much more accurate and fine grained information
about licensing and authorship is available, hence let's drop the
per-file copyright notice. Of course, removing copyright lines of others
is problematic, hence this commit only removes my own lines and leaves
all others untouched. It might be nicer if sooner or later those could
go away too, making git the only and accurate source of authorship
information.
This part of the copyright blurb stems from the GPL use recommendations:
https://www.gnu.org/licenses/gpl-howto.en.html
The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.
hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
Let's add "const" where we don't change structures passed.
Also, we generally use "unsigned char" for IP prefix length values, do
so here too. Previously different parts of the sd-radv.h API used
different types for this.
sd_radv_stop is called from two places. if sd_radv_stop is alrady
success then just don't try to close it .
```
systemd-networkd[604]: RADV: Stopping IPv6 Router Advertisement daemon
systemd-networkd[604]: RADV: Unable to send last Router Advertisement with router lifetime set to zero: Bad file descriptor <==================HERE
systemd-networkd[604]: RADV: Updated prefix 2a0a:*:*:fc::/64 preferred 1h valid 2h
systemd-networkd[604]: RADV: Started IPv6 Router Advertisement daemon
```
Closes one of the issue #8960
Most our other parsing functions do this, let's do this here too,
internally we accept that anyway. Also, the closely related
load_env_file() and load_env_file_pairs() also do this, so let's be
systematic.
This makes most header files easier to look at. Also Emacs gets really
slow when browsing through large sections of overly long prototypes,
which is much improved by this macro.
We should probably not do something similar with too many other cases,
as macros like this might help readability for some, but make it worse
for others. But I think given the complexity of this specific prototype
and how often we use it, it's worth doing.
Configuration through environment variable is inconvenient with meson, because
they cannot be convieniently changed and/or are not preserved during
reconfiguration (https://github.com/mesonbuild/meson/issues/1503).
This adds -Dvalgrind=true/false, which has the advantage that it can be set
at any time with meson configure -Dvalgrind=... and ninja will rebuild targets
as necessary. Additional minor advantages are better consistency with the
options for hashmap debugging, and typo avoidance with '#if' instead of '#ifdef'.
This patch add support to enables to send User Class option code 77
RFC 3004.
This option MAY carry multiple User Classes.
The format of this option is as follows:
Code Len Value
+-----+-----+--------------------- . . . --+
| 77 | N | User Class Data ('Len' octets) |
+-----+-----+--------------------- . . . --+
where Value consists of one or more instances of User Class Data.
Each instance of User Class Data is formatted as follows:
UC_Len_i User_Class_Data_i
+--------+------------------------ . . . --+
| L_i | Opaque-Data ('UC_Len_i' octets) |
+--------+------------------------ . . . --+
UserClass=
A DHCPv4 client can use UserClass option to identify the type or category of user or applications
it represents. The information contained in this option is an string that represents the user class
of which the client is a member. Each class sets an identifying string of information to be used by the DHCP service to classify clients. Takes a whitespace-separated list.
UserClass= hello world how are you
Closes: RFC: #5134
Previously we were a bit sloppy with the index and size types of arrays,
we'd regularly use unsigned. While I don't think this ever resulted in
real issues I think we should be more careful there and follow a
stricter regime: unless there's a strong reason not to use size_t for
array sizes and indexes, size_t it should be. Any allocations we do
ultimately will use size_t anyway, and converting forth and back between
unsigned and size_t will always be a source of problems.
Note that on 32bit machines "unsigned" and "size_t" are equivalent, and
on 64bit machines our arrays shouldn't grow that large anyway, and if
they do we have a problem, however that kind of overly large allocation
we have protections for usually, but for overflows we do not have that
so much, hence let's add it.
So yeah, it's a story of the current code being already "good enough",
but I think some extra type hygiene is better.
This patch tries to be comprehensive, but it probably isn't and I missed
a few cases. But I guess we can cover that later as we notice it. Among
smaller fixes, this changes:
1. strv_length()' return type becomes size_t
2. the unit file changes array size becomes size_t
3. DNS answer and query array sizes become size_t
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=76745
This drops a good number of type-specific _cleanup_ macros, and patches
all users to just use the generic ones.
In most recent code we abstained from defining type-specific macros, and
this basically removes all those added already, with the exception of
the really low-level ones.
Having explicit macros for this is not too useful, as the expression
without the extra macro is generally just 2ch wider. We should generally
emphesize generic code, unless there are really good reasons for
specific code, hence let's follow this in this case too.
Note that _cleanup_free_ and similar really low-level, libc'ish, Linux
API'ish macros continue to be defined, only the really high-level OO
ones are dropped. From now on this should really be the rule: for really
low-level stuff, such as memory allocation, fd handling and so one, go
ahead and define explicit per-type macros, but for high-level, specific
program code, just use the generic _cleanup_() macro directly, in order
to keep things simple and as readable as possible for the uninitiated.
Note that before this patch some of the APIs (notable libudev ones) were
already used with the high-level macros at some places and with the
generic _cleanup_ macro at others. With this patch we hence unify on the
latter.
Double newlines (i.e. one empty lines) are great to structure code. But
let's avoid triple newlines (i.e. two empty lines), quadruple newlines,
quintuple newlines, …, that's just spurious whitespace.
It's an easy way to drop 121 lines of code, and keeps the coding style
of our sources a bit tigther.
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.
I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
This is similar to TAKE_PTR() but operates on file descriptors, and thus
assigns -1 to the fd parameter after returning it.
Removes 60 lines from our codebase. Pretty good too I think.
This macro will read a pointer of any type, return it, and set the
pointer to NULL. This is useful as an explicit concept of passing
ownership of a memory area between pointers.
This takes inspiration from Rust:
https://doc.rust-lang.org/std/option/enum.Option.html#method.take
and was suggested by Alan Jenkins (@sourcejedi).
It drops ~160 lines of code from our codebase, which makes me like it.
Also, I think it clarifies passing of ownership, and thus helps
readability a bit (at least for the initiated who know the new macro)
If we can't send a message this is no reason to completely abort the
event handler.
Issue identified by Nandor Han <nandor.han@ge.com>, Sebastian Reichel
<sebastian.reichel@collabora.co.uk>.
Replaces: #8525
The type is "ssize_t", not "int", let's be accurate about that, as these
types are different on some archs.
Given that we don't actually care about the return value reall, drop
the whole assignment, just check if negative.
This makes users can configure DHCPv4 client with ClientIdentifier=duid-only.
If set so, then DHCP client sends only DUID as the client identifier.
This may not be RFC compliant, but some setups require this.
Closes#7828.
Commit f11cba7479 ("libsystemd-network: fix unaligned loads (issue #7654)")
changed the way in which the MAC address is read to use native endiannes:
htobe32(*((uint32_t *)x) -> unaligned_read_ne32(x)
This is wrong because loads done with BPF_LD + BPF_ABS are big-endian, as it
can be seen for the ethertype and arp-operation loads above in the
filter. Also, the same commit changed:
htobe32(*((unsigned int *)x) -> unaligned_read_be32(x)
in _bind_raw_socket(), which is the correct form.
The commit broke IPv4LL in presence of loops, as the sender now considers its
own packets as conflicting.
Fixes: f11cba7479
Ever since the initial implementation in 631bbe7129,
client_parse_message() was supposed to check that the message contains exactly
one serverid. The check that no more than one is given was implemented
correctly, but the check that at least one is given was not. Simplify the whole
thing by making dhcp6_lease_get_serverid() return an error if the id is not
set, and do not require the arguments to be present if the contents of the id
are not needed.
Technically, `data` is a sequence of bytes without a trailing zero,
so the use of `memcmp` seems to be logical here. Besides, this helps get
around a bug that makes `asan` report the false positive mentioned in
#8052.
Closes#8052.
The DHCPv6 client will set its state to DHCP6_STATE_STOPPED if
an error occurs or when receiving an Information Reply DHCPv6
message. Once in DHCP6_STATE_STOPPED, the DHCPv6 client needs
to be restarted by calling sd_dhcp6_client_start().
As of pull request #7796 client_reset() no longer closes the
network socket, thus a call to sd_dhcp6_client_start() needs to
check whether the file descriptor already exists in order not to
create a new one. Likewise, a call to sd_dhcp6_client_unref()
must now close the network socket as client_reset() is not
closing it.
Reported by asavah and Yu Watanabe.
The DHCPv6 client can obtain configuration parameters from a
DHCPv6 server through a rapid two-message exchange solicit and reply).
When the rapid commit option is enabled by both the DHCPv6 client and
the DHCPv6 server, the two-message exchange is used, rather than the default
four-method exchange (solicit, advertise, request, and reply). The two-message
exchange provides faster client configuration and is beneficial in environments
in which networks are under a heavy load.
Closes#5845
When the DHCP server returns both a Classless Static Routes
option and a Static Routes option, the DHCP client MUST ignore the
Static Routes option.
Closes#7792
This fixes the following warnings:
```
[194/1521] Compiling C object 'src/libsystemd-network/systemd-network@sta/dhcp6-option.c.o'.
../../git/systemd/src/libsystemd-network/dhcp6-option.c:110:25: warning: taking address of packed member 'id' of class or structure 'ia_na' may result in an unaligned pointer value [-Waddress-of-packed-member]
iaid = &ia->ia_na.id;
^~~~~~~~~~~~
../../git/systemd/src/libsystemd-network/dhcp6-option.c:115:25: warning: taking address of packed member 'id' of class or structure 'ia_ta' may result in an unaligned pointer value [-Waddress-of-packed-member]
iaid = &ia->ia_ta.id;
^~~~~~~~~~~~
2 warnings generated.
```
The slightly modified review comments say that "...in theory
offsetof(DHCP6Option, data) is nicer than sizeof(DHCP6Option)
because the former removes alignment artifacts. In this
specific case there are no alignment whitespaces hence it's
fine, but out of a matter of principle offsetof() is preferred
over sizeof() in cases like this..."
Calling dhcp6_option_parse_address() will always return a value
< 0 on error even though lt_valid remains unset. This is more
than valgrind can safely detect, but let's fix the valgrind
nitpick anyway.
While fixing, use UINT32_MAX instead of ~0 on the same line.
log.h really should only include the bare minimum of other headers, as
it is really pulled into pretty much everything else and already in
itself one of the most basic pieces of code we have.
Let's hence drop inclusion of:
1. sd-id128.h because it's entirely unneeded in current log.h
2. errno.h, dito.
3. sys/signalfd.h which we can replace by a simple struct forward
declaration
4. process-util.h which was needed for getpid_cached() which we now hide
in a funciton log_emergency_level() instead, which nicely abstracts
the details away.
5. sys/socket.h which was needed for struct iovec, but a simple struct
forward declaration suffices for that too.
Ultimately this actually makes our source tree larger (since users of
the functionality above must now include it themselves, log.h won't do
that for them), but I think it helps to untangle our web of includes a
tiny bit.
(Background: I'd like to isolate the generic bits of src/basic/ enough
so that we can do a git submodule import into casync for it)
Both netinet/icmp6.h and linux/in6.h will define struct in6_addr, and in
user space we want to use the netinet/icmp6.h variant.
Fixes build problem:
In file included from src/libsystemd-network/sd-radv.c:23:0:
/home/hegtvedt/work/os/product/sunrise/root/_build/v2/include/linux/in6.h:30:8:
error: redefinition of 'struct in6_addr'
As DHCPv6 leases may expire at some point, the delegated prefixes
have to be removed. Add a prefix removal function to the Router
Advertisement handling code.
Add a boolean that indicates whether the prefixes will always exist
or if they will time out after the assigned valid lifetime. In the
latter case calculate the expiry times for both preferred and valid
lifetimes for the prefixes, and decrease the remaining lifetimes
each time when a Router Advertisement is sent.
Should the prefix be updated, re-calculate the prefix lifetime. When
updating, update the existing entry, if any, with the lifetimes of
the added entry as the existing entry has its lifetimes set
according to its previously calculated expiry times.
Compute one set of minimum lifetimes for T1 and T2, i.e. the smaller
ones assigned to IA NA and IA PD. The lifetimes should be the same,
see RFC 7550 for details.
Parse IA PD options and the prefixes in one or more PD Prefix
options. As the PD option contains identical data as the IA NA
option, re-use the same general data structures and sub-option
parsing logic. Similar to IA NA addresses, PD and associated
prefixes are stored in the address list of the IA PD lease.
An IA sub-option Status code will affect the IA NA and IA PD
option in question and cause those options to be ignored. A
Status code option in an IA Address or IA PD Prefix option
affects only that IA Address or Prefix.
Factor out IA Address option parsing and fix it so that all conditions
are checked before a new address is allocated and added to the address
list. Note also that the IA Address option can contain a nested Status
option. If the status in anything else than zero, the DHCPv6 server is
communicating an error condition and the address cannot be used.
Status option nesting is clarified in RFC 7550, Section 4.1.
The IA Address option is included as a typedef so that the lifetimes
can be inspected before allocating a new address and the option length
needed is easily available.
Sanitize code for parsing DHCPv6 IA NA and TA options and their
nested Status options so that the options can be fully and
properly ignored should they not be conformant to the specification.
Do this by defining a proper DHCP6Option structure and sending that
structure to the parsing function. The parsing function will then
not manipulate either any option data pointers or their lengths in
order to iterate over the current option. Needless to say, this
affects a few files including the test program.
Close DHCPv6 client socket file descriptor when
sd_dhcp6_client_stop() is called and not when client_reset() is
called. If left in client_reset(), any internal temporary stopping
of the DHCPv6 client with client_stop() will call client_reset()
after which the DHCPv6 client will not be able to receive any further
DHCPv6 messages.
Similarly, client_start() needs to enable events for the DHCPv6
socket file descriptor since a call to client_stop() will call
client_reset() which will remove it from the main loop. Events should
be turned off when no DHCPv6 messages are expected.
This adds a simple condition/assert/match to the service manager, to
udev's .link handling and to networkd, for matching the kernel version
string.
In this version we only do fnmatch() based globbing, but we might want
to extend that to version comparisons later on, if we like, by slightly
extending the syntax with ">=", "<=", ">", "<" and "==" expressions.
Let's replace usage of fputc_unlocked() and friends by __fsetlocking(f,
FSETLOCKING_BYCALLER). This turns off locking for the entire FILE*,
instead of doing individual per-call decision whether to use normal
calls or _unlocked() calls.
This has various benefits:
1. It's easier to read and easier not to forget
2. It's more comprehensive, as fprintf() and friends are covered too
(as these functions have no _unlocked() counterpart)
3. Philosophically, it's a bit more correct, because it's more a
property of the file handle really whether we ever pass it on to another
thread, not of the operations we then apply to it.
This patch reworks all pieces of codes that so far used fxyz_unlocked()
calls to use __fsetlocking() instead. It also reworks all places that
use open_memstream(), i.e. use stdio FILE* for string manipulations.
Note that this in some way a revert of 4b61c87511.
Using strlen() to declare a buffer results in a variable-length array,
even if the compiler likely optimizes it to be a compile time constant.
When building with -Wvla, certain versions of gcc complain about such
buffers. Compiling with -Wvla has the advantage of preventing variably
length array, which defeat static asserts that are implemented by
declaring an array of negative length.
So far I avoided adding license headers to meson files, but they are pretty
big and important and should carry license headers like everything else.
I added my own copyright, even though other people modified those files too.
But this is mostly symbolic, so I hope that's OK.
Implement DHCPv6 option to exchange information about the Fully
Qualified Domain Name (FQDN) according to RFC 4704.
The RFC 4704 describes two models of operations in section 3,
currently only the second model is supported (DHCPv6 server
updates both the AAAA and the PTR RRs).
The existing DHCP Section Options SendHostname and Hostname are
sent as FQDN to the server. According to section 4.2 sending
only parts of its FQDN is allowed.
Fixes#4682.
Technically DNS allows any ASCII character to be used in the
domain name. Also the DHCP specification for the FQDN option
(RFC 4702) does not put restriction on labels.
However, hostnames do have stricter requirements and typically
should only use characters from a-z (case insensitve), 0-9 and
minus.
Currently we require hostname/FQDN to be either a hostname or
a valid DNS name. Since dns_name_is_valid() allows any ASCII
characters this allows to specify hostnames which are typically
not valid.
Check hostname/FQDN more strictly and require them to pass both
tests. Specifically this requires the entire FQDN to be below 63.
When EmitDNS or EmitDomains is set, automatically look up values
for Router Advertisement DNS and DNS search domain options starting
with the values in the IPv6PrefixDelegationsection, if any. If none
are found, use the values set for the network, and as a last resort
try with the preferred upstream network.
The default DNS lifetime and therefore Router Advertisement interval
is added to the public sd_radv.h header as the DNS lifetime depends
on the maximum advertisement interval.
Let's rename all our functions that process IPv4 in_addr structures
in4_addr_xyz(), following the already establishing naming logic for
this.
Leave the in_addr_xyz() prefix for functions that process the IPv4/IPv6
in_addr_union union instead.
Add Router Advertisement DNS Search List option as specified
in RFC 8106. The search list option uses and identical option
header as the RDNSS option and therefore the option header
structure can be reused.
If systemd is compiled with IDNA support, internationalization
of the provided search domain is applied, after which the search
list is written in wire format into the DNSSL option.
An infiniband hardware address is 20 bytes, but sockaddr_ll.sll_addr is only 8
bytes. Explicitly ensure that sockaddr_union has enough space for infiniband
addresses, even if they run over sockaddr_ll and add a macro to compute the
proper size to pass to kernel.
As a follow-up for db3f45e2d2 let's do the
same for all other cases where we create a FILE* with local scope and
know that no other threads hence can have access to it.
For most cases this shouldn't change much really, but this should speed
dbus introspection and calender time formatting up a bit.
In normal operation this would trigger an assertion
when a DHCP server is configured every time the link goes up.
This change makes sd_dhcp_server_configure_pool idempotent
and stops the DHCP server when the link loses carrier.
In addition to this stopping the assertion being triggered,
this has the useful side-effect of allowing the link to be taken down
and then brought back up as a way to have it use DNS from an "upstream"
interface that got its DNS configuration via DHCP
after the downstream link was configured.
Test ICMPv6 Router Solicitation exponential backoff timer by
computing the minimum and maximum values according to RFC 7559,
Section 2 and the algorithm itself described in RFC 3315, Section
14. Reset the sd_ndisc timer to trigger after a zero second delay,
which causes the ndisc timeout to be triggered immediately once
the caller of the "sending" function returns to the main loop.
Move ICMPv6 Router Solicitation sending after timer computation so
that timers are already set up when the packet is being sent. This
makes it possible to create a test that inspects Router
Solicitation timer values when the Router Solicitation is sent out
on the network.
Instead of sending a fixed amount of Router Solicitiations, implement
the backoff algorithm proposed in RFC 7559. The backoff algorithm is
the same as used by DHCPv6.
Time out after 12s as specified in RFC 4861 in order not to delay
setting up a link for too long while sending Router Solicitations
in the background. Notice that after this change the callback will
receive a SD_NDISC_EVENT_TIMEOUT timeout event, and at a later point
when a router appears, a received Router Advertisment will cause the
callback to be called again with the SD_NDISC_EVENT_ROUTER event.
Let's downgrade the warning introduced by
955d99edc7 to debug, as we really
shouldn't log at more than debug level from library code.
(And while we are at it, print the MTU as the right (unsigned) type in
the format string.)
All those uses were correct, but I think it's better to be explicit.
Using implicit errno is too error prone, and with this change we can require
(in the sense of a style guideline) that the code is always specified.
Helpful query: git grep -n -P 'log_[^s][a-z]+\(.*%m'
Add tests for prefix creation, router variable setting and finally
verify that a Router Advertisement is properly formatted when sending.
Also check that there is a Router Advertisment with zero lifetime
when Router Advertisement sending is stopped.
Receive Router Solicitations and send a unicast Router Advertisment
in response. Refactor ICMPv6 packet handling code so that the common
ICMPv6 validation parts are reused between the existing router
discovery and the new functionality adding reception of Router
Solicitation messages.
Create and remove the ICMPv6 Router Advertisement socket file
descriptor and implement Router Advertisment sending. As not
all options are mandatory, use IO vectors to point to the included
options and the prefix information.
Reuse and refactor the functionality already present for Router
Solicitations in order to create a socket for sending Router
Advertisements. Anticipate reception of incoming Router
Solicitations by setting the ICMPv6 filter accordingly. Also set
the unicast hop limit to 255 for ICMPv6 sockets as unicast Router
Advertisments are to be sent in response to Router Solicitations.
Update the Router Solicitation test case code with a function
definition in order to keep the test case working.
Router Advertisements are sent uniformly distributed between a
minimum and maximum time according to RFC 4861, Section 6.2.4.
Default values from RFC 4861 are for now used as minimum and
maximum Router Advertisement timeouts.
When stopping, a Router Advertisement with a router lifetime set
to zero is sent in order to inform any nodes that the interface
on this host no longer is a router.
Define Router Advertisement prefix structure. Add the Prefix
Information ICMPv6 option defined in RFC 4861 to the prefix
information structure, as it will simplify sending a Prefix
Information option later on. In order to handle endianness
correctly, the structure is redefined here instead of using
the one in netinet/icmp6.h.
Add functions to create and modify prefix information and set
default values as defined in RFC 4861, Section 6.2.1.
This adds a modified version of dhcp6_option_parse_domainname() that is
able to parse compressed domain names, borrowing the idea from
dns_packet_read_name(). It also adds pieces in networkd-link and
networkd-manager to properly save/load the added option field.
Resolves#2710.
Reset also the counter for number of Router Solicitations sent when
the associated file descriptor is closed and the event source
unreferenced. With this change the router discovery can now be
stopped and restarted arbitrary many times.
The indentation for emacs'es meson-mode is added .dir-locals.
All files are reindented automatically, using the lasest meson-mode from git.
Indentation should now be fairly consistent.