Otherwise, if the same kind of tclass is already assigned, parameters
configured in .network file will not be used. So, let's first copy the
tclass and put it on Request, then on success generate a new copy based
on the netlink notification and store it to Link.
This is the same as 0a0c2672db,
65f5f58156, and friends, but for tclass.
Otherwise, if the same kind of qdisc is already assigned, parameters
configured in .network file will not be used. So, let's first copy the
qdisc and put it on Request, then on success generate a new copy based
on the netlink notification and store it to Link.
This is the same as 0a0c2672db,
65f5f58156, and friends, but for qdisc.
Preparation for fixing #31226.
With the current algorithm, we can end up removing entries from the
qdisc/tclass sets while having multiple open iterators over the sets at
various positions which leads to assertion failures in the hashmap logic
as it's only safe to remove the "current" entry.
To avoid the problem, let's split up marking and dropping of tclasses
and qdiscs. First, we recursively iterate tclasses/qdiscs and mark all
that need to be removed. Next, we iterate once over tclasses and qdiscs
and remove all marked entries.
Fixes 632d321050
Some qdiscs (e.g. tbf) implicitly create class(es) on create.
Previously, we could not create any child qdisc under the class, as the
implicit class is tagged as foreign.
Some kind of qdisc implicitly creates a class for the qdisc, but the
created class is not notified by the kernel. So, we need to explicitly
enumerate classes after a qdisc is created.
When a node of traffic control tree is removed, all child nodes are also
removed but their removal are not notified by the kernel.
So, previously, removed TC classes or qdiscs under the removed node were
kept in the memory of networkd, and may cause failure on reconfigure.
This makes Request object takes hash, compare, free, and process functions.
With this change, the logic in networkd-queue.c can be mostly
independent of the type of the request or the object (e.g. Address) assigned
to the request, and it becomes simpler.
In most netlink handlers, we do the following,
1. decrease the message counter,
2. check the link state,
3. error handling,
4. update link state via e.g. link_check_ready().
The first two steps are mostly common, hence let's extract it.
Moreover, this is not only extracting the common logic, but provide a
strong advantage; `request_call_netlink_async()` assigns the relevant
Request object to the userdata of the netlink slot, and the request object
has full information about the message we sent. Hence, in the future,
netlink handler can print more detailed error message. E.g. when
an address is failed to configure, then currently we only show an
address is failed to configure, but with this commit, potentially we can
show which address is failed explicitly.
This does not change such error handling yet. But let's do that later.
This also renames e.g. request_process_address() -> address_process_request().
Also, this drops type checks such as `assert(req->type == REQUEST_TYPE_ADDRESS)`,
as in the later commits, the function of processing request, e.g.
`address_process_request()`, will be assigned to the Request object when
it is created. And the request type will be used to distinguish and to
avoid deduplicating requests which do not have any assigned objects,
like REQUEST_TYPE_DHCP4_CLIENT. Hence, the type checks in process functions
are mostly not necessary and redundant.
This is mostly cleanups and preparation for later commits, and should
not change any behavior.
This should not change any behavior, as req->netlink_handler is always
qdisc_handler or tclass_handler.
This is just a preparation for a later commit which introduces
request_call_netlink_async().
Structured initialization is used a bit more.
There were two kinds of log messages: about failed size calculations and
about failed appends to the message. I "downgraded" the first type to log_debug,
and moved the latter to the caller. This way there should be at most one high-priority
message.
I also changed sizeof(<type>) to sizeof(var) — there is less chance of select-and-paste
error in the second form.