To me this is the last major basic functionality that couldn't be
configured via credentials: the network.
We do not invent any new format for this, but simply copy relevant creds
1:1 into /run/systemd/network/ to open up the full functionality of
networkd to VM hosts.
Otherwise, e.g. when we enumerate a bridge port first, then the bridge
main interface, then the port cannot be managed by the main interface.
Fixes#30682.
The passed attribute type will be used later.
This also
- rename conf parsers,
- sort gperf entries by the attr type.
No functional change, just refactoring and preparation for later commits.
This also split config_parse_route_boolean() into two:
for GatewayOnline= and boolean route metrics.
No functional change, just refactoring and preparation for later commits.
This patch adds a new parameter to parse_ip_port_range, giving callers
the option to allow ranges to have their min be 0 instead of 1.
This is then used by parse_ip_ports_token, intern used by
parse_socket_bind_item to allow port 0 when restricting bind system
calls with SocketBindDeny / SocketBindAllow.
With this, users running server software written using the golang
standard library will be able to effectively sandbox their software,
albeit with a small loss in security protections by allowing the
process to bind on a random port in the
/proc/sys/net/ipv4/ip_local_port_range.
If we want to allow method replies to be extended without this breaking
compat, then we should set this flag. Do so at various method call
replies hence.
Also do it when parsing user/group records, which are expressly
documented to be extensible, as well as the hibernate JSON record.
Follow-up for b732606950 and
6706ce2fd2.
If Network.ignore_carrier_loss_set flag is set, then the timeout value
is always used, hence the logic implemented by
b732606950 never worked.
Otherwise, log_netdev_xyz() does not provide netdev name if it is called
in done(). It is hard to debug.
This should not change any effective behavior, at least with the current
implementation of done() per netdev kind.
When KeepCarrier is set, networkd doesn't close tun/tap file descriptor
preserving the active interface state, but doesn't disable its queue
which makes kernel to think that it's still active and send packets to
it.
This patch disables the created queue right after tun/tap interface
creation.
Here is the steps to reproduce the bug:
Having:
systemd/network/10-tun-test.netdev:
[NetDev]
Name=tun-test
Kind=tun
[Tun]
MultiQueue=yes
KeepCarrier=yes
systemd/network/10-tun-test.network:
[Match]
Name=tun-test
[Network]
DHCP=no
IPv6AcceptRA=false
LLMNR=false
MulticastDNS=false
Address=172.31.0.1/24
app.c:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <linux/if.h>
#include <sys/ioctl.h>
#include <linux/if_tun.h>
int main() {
int fd;
struct ifreq ifr;
memset(&ifr, 0, sizeof ifr);
strcpy(ifr.ifr_name, "tun-test");
ifr.ifr_flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE;
if((fd = open("/dev/net/tun", O_RDWR)) < 0) {
perror("Open error");
return 1;
}
if(ioctl(fd, TUNSETIFF, &ifr)) {
perror("Configure error");
return 1;
}
puts("Ready.");
char buf[1500];
while(1) {
int size = read(fd, buf, sizeof buf);
if(size < 0) {
perror("Read error");
return 1;
}
printf("Read %d bytes.\n", size);
}
return 0;
}
Run:
* gcc -o app app.c && ./app
* ping -I tun-test 172.31.0.2
Before the patch the app shows no pings, but after it works properly.
Currently, link_queue_request_safe(), which is a wrapper of
request_new(), is called with a free function at
- link_request_stacked_netdev() at netdev/netdev.c,
- link_request_address() at networkd-address.c,
- link_request_nexthop() at networkd-nexthop.c,
- link_request_neighbor() at networkd-networkd.c.
For the netdev case, the reference counter of the passed object is increased
only when the function returns 1. So, on failure (with -ENOMEM)
previously we unexpectedly dropped the reference of the NetDev object.
Similarly, for Address and friends, the ownership of the object is moved to the
Request object only when the function returns 1. And on failure, previously
the object was freed twice.
Also, netdev_queue_request(), which is another wrapper of request_new()
potentially leaks memory when the same NetDev object is queued twice.
Fortunately, that should not happen as the function is called only once
per object.
This fixes the above issue, and now the ownership or the reference
counter of the object is changed only when it is succeeded with 1.
Then, replace address_remove_and_drop() with it.
If an address is requested, and the request is already called,
we may not received its reply and notification from the kernel, and
the corresponding address object may not be remmbered. Even in such
case, we need to remove the address, otherwise the address will come
later after the function called.
Previously, we checked if the address is ready only when it is an IPv6
address. But, IPv4 address never enter tentative state, hence the check
for an IPv4 address is effectively equivalent to the one for IPv6.
So, let's unify the check. This does not change any effective behavior.