Compare commits

..

No commits in common. "097537f07a2fab3cb73aef7bc59f2a66aa93f533" and "6bbeef204252f15382d0b6cad60e37b9f879caa4" have entirely different histories.

27 changed files with 101 additions and 584 deletions

View File

@ -514,13 +514,6 @@ evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoYoga500-14IBD*
EVDEV_ABS_35=117:3952:36
EVDEV_ABS_36=105:1960:26
# Lenovo Thinkpad T490
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*:svnLENOVO:*pvrThinkPadT490:*
EVDEV_ABS_00=::57
EVDEV_ABS_01=::33
EVDEV_ABS_35=::57
EVDEV_ABS_36=::33
#########################################
# Razer
#########################################

View File

@ -835,11 +835,7 @@
container names may have a length up to 64 characters. As this option derives the host-side interface
name from the container name the name is possibly truncated. Thus, care needs to be taken to ensure
that interface names remain unique in this case, or even better container names are generally not
chosen longer than 12 characters, to avoid the truncation. If the name is truncated,
<command>systemd-nspawn</command> will automatically append a 4-digit hash value to the name to
reduce the chance of collisions. However, the hash algorithm is not collision-free. (See
<citerefentry><refentrytitle>systemd.net-naming-scheme</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details on older naming algorithms for this interface). Alternatively, the
chosen longer than 12 characters, to avoid the truncation. Alternatively, the
<option>--network-veth-extra=</option> option may be used, which allows free configuration of the
host-side interface name independently of the container name — but might require a bit more
additional configuration in case bridging in a fashion similar to <option>--network-bridge=</option>

View File

@ -46,11 +46,6 @@
devices based on those properties. See the description of <varname>NamePolicy=</varname> and
<varname>MACAddressPolicy=</varname> in
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para>Note that while the concept of network interface naming schemes is primarily relevant in the
context of <filename>systemd-udevd.service</filename>, the
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>
container manager also takes it into account when naming network interfaces, see below.</para>
</refsect1>
<refsect1>
@ -334,21 +329,7 @@
<para>Previously two-letter interface type prefix was prepended to
<varname>ID_NET_LABEL_ONBOARD=</varname>. This is not done anymore.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>v245</constant></term>
<listitem><para>When
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>
derives the name for the host side of the network interface created with
<option>--network-veth</option> from the container name it previously simply truncated the result
at 15 characters if longer (since that's the maximum length for network interface names). From now
on, for any interface name that would be longer than 15 characters the last 4 characters are set to
a 24bit hash value of the full interface name. This way network interface name collisions between
multiple similarly named containers (who only differ in container name suffix) should be less
likely (but still possible, since the 24bit hash value is very small).</para></listitem>
</varlistentry>
</variablelist>
</variablelist>
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
particular version of systemd.</para>
@ -447,8 +428,7 @@ ID_NET_NAME_PATH=encf5f0</programlisting>
<para>
<citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<ulink url="https://systemd.io/PREDICTABLE_INTERFACE_NAMES">Predictable Network Interface Names</ulink>,
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<ulink url="https://systemd.io/PREDICTABLE_INTERFACE_NAMES">Predictable Network Interface Names</ulink>
</para>
</refsect1>

View File

@ -1378,16 +1378,6 @@
service type to CS6 (network control) or CS4 (Realtime). Defaults to CS6.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MultiPathRoute=<replaceable>address</replaceable>[@<replaceable>name</replaceable>] [<replaceable>weight</replaceable>]</varname></term>
<listitem>
<para>Configures multipath route. Multipath routing is the technique of using multiple
alternative paths through a network. Takes gateway address. Optionally, takes a network
interface name or index separated with <literal>@</literal>, and a weight in 1..256 for
this multipath route separated with whitespace. This setting can be specified multiple
times. If an empty string is assigned, then the all previous assignments are cleared.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -45,16 +45,17 @@ w+ /file/to/append-to - - - - conte
d /directory/to/create-and-cleanup mode user group cleanup-age -
D /directory/to/create-and-remove mode user group cleanup-age -
e /directory/to/cleanup mode user group cleanup-age -
v /subvolume/to/create mode user group - -
v /subvolume-or-directory/to/create mode user group - -
Q /subvolume/to/create mode user group - -
p /fifo/to/create mode user group - -
p+ /fifo/to/[re]create mode user group - -
L /symlink/to/create - - - - symlink/target/path
L+ /symlink/to/[re]create - - - - symlink/target/path
c /dev/char-device-to-create mode user group - major:minor
c+ /dev/char-device-to-[re]create mode user group - major:minor
b /dev/block-device-to-create mode user group - major:minor
b+ /dev/block-device-to-[re]create mode user group - major:minor
c /dev/char-device-to-create mode user group - -
c+ /dev/char-device-to-[re]create mode user group - -
b /dev/block-device-to-create mode user group - -
b+ /dev/block-device-to-[re]create mode user group - -
C /target/to/create - - - - /source/to/copy
x /path-or-glob/to/ignore - - - - -
X /path-or-glob/to/ignore/recursively - - - - -

View File

@ -383,62 +383,25 @@ JobType job_type_lookup_merge(JobType a, JobType b) {
return job_merging_table[(a - 1) * a / 2 + b];
}
bool job_later_link_matters(Job *j, JobType type, unsigned generation) {
JobDependency *l;
assert(j);
j->generation = generation;
LIST_FOREACH(subject, l, j->subject_list) {
UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
/* Have we seen this before? */
if (l->object->generation == generation)
continue;
state = unit_active_state(l->object->unit);
switch (type) {
case JOB_START:
return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) ||
job_later_link_matters(l->object, type, generation);
case JOB_STOP:
return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) ||
job_later_link_matters(l->object, type, generation);
default:
assert_not_reached("Invalid job type");
}
}
return false;
}
bool job_is_redundant(Job *j, unsigned generation) {
assert(j);
UnitActiveState state = unit_active_state(j->unit);
switch (j->type) {
bool job_type_is_redundant(JobType a, UnitActiveState b) {
switch (a) {
case JOB_START:
return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) && !job_later_link_matters(j, JOB_START, generation);
return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
case JOB_STOP:
return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) && !job_later_link_matters(j, JOB_STOP, generation);
return IN_SET(b, UNIT_INACTIVE, UNIT_FAILED);
case JOB_VERIFY_ACTIVE:
return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING);
return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
case JOB_RELOAD:
return
state == UNIT_RELOADING;
b == UNIT_RELOADING;
case JOB_RESTART:
return
state == UNIT_ACTIVATING;
b == UNIT_ACTIVATING;
case JOB_NOP:
return true;

View File

@ -196,8 +196,7 @@ _pure_ static inline bool job_type_is_superset(JobType a, JobType b) {
return a == job_type_lookup_merge(a, b);
}
bool job_later_link_matters(Job *j, JobType type, unsigned generation);
bool job_is_redundant(Job *j, unsigned generation);
bool job_type_is_redundant(JobType a, UnitActiveState b) _pure_;
/* Collapses a state-dependent job type into a simpler type by observing
* the state of the unit which it is going to be applied to. */

View File

@ -279,7 +279,7 @@ static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
return 0;
}
static void transaction_drop_redundant(Transaction *tr, unsigned generation) {
static void transaction_drop_redundant(Transaction *tr) {
bool again;
/* Goes through the transaction and removes all jobs of the units whose jobs are all noops. If not
@ -299,7 +299,7 @@ static void transaction_drop_redundant(Transaction *tr, unsigned generation) {
LIST_FOREACH(transaction, k, j)
if (tr->anchor_job == k ||
!job_is_redundant(k, generation) ||
!job_type_is_redundant(k->type, unit_active_state(k->unit)) ||
(k->unit->job && job_type_is_conflicting(k->type, k->unit->job->type))) {
keep = true;
break;
@ -730,7 +730,7 @@ int transaction_activate(
transaction_minimize_impact(tr);
/* Third step: Drop redundant jobs */
transaction_drop_redundant(tr, generation++);
transaction_drop_redundant(tr);
for (;;) {
/* Fourth step: Let's remove unneeded jobs that might
@ -772,7 +772,7 @@ int transaction_activate(
}
/* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */
transaction_drop_redundant(tr, generation++);
transaction_drop_redundant(tr);
/* Ninth step: check whether we can actually apply this */
r = transaction_is_destructive(tr, mode, e);

View File

@ -142,9 +142,11 @@ int sd_netlink_message_is_broadcast(const sd_netlink_message *m) {
/* If successful the updated message will be correctly aligned, if
unsuccessful the old message is untouched. */
static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *data, size_t data_length) {
size_t message_length;
uint32_t rta_length;
size_t message_length, padding_length;
struct nlmsghdr *new_hdr;
struct rtattr *rta;
char *padding;
unsigned i;
int offset;
@ -152,10 +154,16 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da
assert(m->hdr);
assert(!m->sealed);
assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
assert(!data || data_length > 0);
assert(!data || data_length);
/* get offset of the new attribute */
offset = m->hdr->nlmsg_len;
/* get the size of the new rta attribute (with padding at the end) */
rta_length = RTA_LENGTH(data_length);
/* get the new message size (with padding at the end) */
message_length = m->hdr->nlmsg_len + RTA_SPACE(data_length);
message_length = offset + RTA_ALIGN(rta_length);
/* buffer should be smaller than both one page or 8K to be accepted by the kernel */
if (message_length > MIN(page_size(), 8192UL))
@ -168,19 +176,33 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da
m->hdr = new_hdr;
/* get pointer to the attribute we are about to add */
rta = (struct rtattr *) ((uint8_t *) m->hdr + m->hdr->nlmsg_len);
rtattr_append_attribute_internal(rta, type, data, data_length);
rta = (struct rtattr *) ((uint8_t *) m->hdr + offset);
/* if we are inside containers, extend them */
for (i = 0; i < m->n_containers; i++)
GET_CONTAINER(m, i)->rta_len += RTA_SPACE(data_length);
GET_CONTAINER(m, i)->rta_len += message_length - offset;
/* fill in the attribute */
rta->rta_type = type;
rta->rta_len = rta_length;
if (data)
/* we don't deal with the case where the user lies about the type
* and gives us too little data (so don't do that)
*/
padding = mempcpy(RTA_DATA(rta), data, data_length);
else
/* if no data was passed, make sure we still initialize the padding
note that we can have data_length > 0 (used by some containers) */
padding = RTA_DATA(rta);
/* make sure also the padding at the end of the message is initialized */
padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
memzero(padding, padding_length);
/* update message size */
offset = m->hdr->nlmsg_len;
m->hdr->nlmsg_len = message_length;
/* return old message size */
return offset;
}

View File

@ -2,7 +2,6 @@
#include "sd-netlink.h"
#include "memory-util.h"
#include "netlink-internal.h"
#include "netlink-util.h"
#include "strv.h"
@ -179,60 +178,3 @@ int rtnl_log_parse_error(int r) {
int rtnl_log_create_error(int r) {
return log_error_errno(r, "Failed to create netlink message: %m");
}
void rtattr_append_attribute_internal(struct rtattr *rta, unsigned short type, const void *data, size_t data_length) {
size_t padding_length;
char *padding;
assert(rta);
assert(!data || data_length > 0);
/* fill in the attribute */
rta->rta_type = type;
rta->rta_len = RTA_LENGTH(data_length);
if (data)
/* we don't deal with the case where the user lies about the type
* and gives us too little data (so don't do that)
*/
padding = mempcpy(RTA_DATA(rta), data, data_length);
else
/* if no data was passed, make sure we still initialize the padding
note that we can have data_length > 0 (used by some containers) */
padding = RTA_DATA(rta);
/* make sure also the padding at the end of the message is initialized */
padding_length = (char *) rta + RTA_SPACE(data_length) - padding;
memzero(padding, padding_length);
}
int rtattr_append_attribute(struct rtattr **rta, unsigned short type, const void *data, size_t data_length) {
struct rtattr *new_rta, *sub_rta;
size_t message_length;
assert(rta);
assert(!data || data_length > 0);
/* get the new message size (with padding at the end) */
message_length = RTA_ALIGN(rta ? (*rta)->rta_len : 0) + RTA_SPACE(data_length);
/* buffer should be smaller than both one page or 8K to be accepted by the kernel */
if (message_length > MIN(page_size(), 8192UL))
return -ENOBUFS;
/* realloc to fit the new attribute */
new_rta = realloc(*rta, message_length);
if (!new_rta)
return -ENOMEM;
*rta = new_rta;
/* get pointer to the attribute we are about to add */
sub_rta = (struct rtattr *) ((uint8_t *) *rta + RTA_ALIGN((*rta)->rta_len));
rtattr_append_attribute_internal(sub_rta, type, data, data_length);
/* update rta_len */
(*rta)->rta_len = message_length;
return 0;
}

View File

@ -77,6 +77,3 @@ int rtnl_log_create_error(int r);
int netlink_message_append_in_addr_union(sd_netlink_message *m, unsigned short type, int family, const union in_addr_union *data);
int netlink_message_append_sockaddr_union(sd_netlink_message *m, unsigned short type, const union sockaddr_union *data);
void rtattr_append_attribute_internal(struct rtattr *rta, unsigned short type, const void *data, size_t data_length);
int rtattr_append_attribute(struct rtattr **rta, unsigned short type, const void *data, size_t data_length);

View File

@ -1040,7 +1040,7 @@ int link_request_set_routes(Link *link) {
for (phase = 0; phase < _PHASE_MAX; phase++)
LIST_FOREACH(routes, rt, link->network->static_routes) {
if ((in_addr_is_null(rt->family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY))
if (in_addr_is_null(rt->family, &rt->gw) != (phase == PHASE_NON_GATEWAY))
continue;
r = route_configure(rt, link, route_handler);

View File

@ -147,7 +147,6 @@ Route.InitialAdvertisedReceiveWindow, config_parse_tcp_window,
Route.QuickAck, config_parse_quickack, 0, 0
Route.FastOpenNoCookie, config_parse_fast_open_no_cookie, 0, 0
Route.TTLPropagate, config_parse_route_ttl_propagate, 0, 0
Route.MultiPathRoute, config_parse_multipath_route, 0, 0
NextHop.Id, config_parse_nexthop_id, 0, 0
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)

View File

@ -144,8 +144,6 @@ void route_free(Route *route) {
set_remove(route->link->routes_foreign, route);
}
ordered_set_free_free(route->multipath_routes);
sd_event_source_unref(route->expire);
free(route);
@ -518,88 +516,6 @@ int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) {
return 1;
}
static int append_nexthop_one(Route *route, MultipathRoute *m, struct rtattr **rta, size_t offset) {
struct rtnexthop *rtnh;
struct rtattr *new_rta;
int r;
assert(route);
assert(m);
assert(rta);
assert(*rta);
new_rta = realloc(*rta, RTA_ALIGN((*rta)->rta_len) + RTA_SPACE(sizeof(struct rtnexthop)));
if (!new_rta)
return -ENOMEM;
*rta = new_rta;
rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset);
*rtnh = (struct rtnexthop) {
.rtnh_len = sizeof(*rtnh),
.rtnh_ifindex = m->ifindex,
.rtnh_hops = m->weight > 0 ? m->weight - 1 : 0,
};
(*rta)->rta_len += sizeof(struct rtnexthop);
if (route->family == m->gateway.family) {
r = rtattr_append_attribute(rta, RTA_GATEWAY, &m->gateway.address, FAMILY_ADDRESS_SIZE(m->gateway.family));
if (r < 0)
goto clear;
rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset);
rtnh->rtnh_len += RTA_SPACE(FAMILY_ADDRESS_SIZE(m->gateway.family));
} else {
r = rtattr_append_attribute(rta, RTA_VIA, &m->gateway, FAMILY_ADDRESS_SIZE(m->gateway.family) + sizeof(m->gateway.family));
if (r < 0)
goto clear;
rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset);
rtnh->rtnh_len += RTA_SPACE(FAMILY_ADDRESS_SIZE(m->gateway.family) + sizeof(m->gateway.family));
}
return 0;
clear:
(*rta)->rta_len -= sizeof(struct rtnexthop);
return r;
}
static int append_nexthops(Route *route, sd_netlink_message *req) {
_cleanup_free_ struct rtattr *rta = NULL;
struct rtnexthop *rtnh;
MultipathRoute *m;
size_t offset;
Iterator i;
int r;
if (ordered_set_isempty(route->multipath_routes))
return 0;
rta = new(struct rtattr, 1);
if (!rta)
return -ENOMEM;
*rta = (struct rtattr) {
.rta_type = RTA_MULTIPATH,
.rta_len = RTA_LENGTH(0),
};
offset = (uint8_t *) RTA_DATA(rta) - (uint8_t *) rta;
ORDERED_SET_FOREACH(m, route->multipath_routes, i) {
r = append_nexthop_one(route, m, &rta, offset);
if (r < 0)
return r;
rtnh = (struct rtnexthop *)((uint8_t *) rta + offset);
offset = (uint8_t *) RTNH_NEXT(rtnh) - (uint8_t *) rta;
}
r = sd_netlink_message_append_data(req, RTA_MULTIPATH, RTA_DATA(rta), RTA_PAYLOAD(rta));
if (r < 0)
return r;
return 0;
}
int route_configure(
Route *route,
Link *link,
@ -783,10 +699,6 @@ int route_configure(
if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
r = append_nexthops(route, req);
if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
link_netlink_destroy_callback, link);
if (r < 0)
@ -1568,113 +1480,6 @@ int config_parse_route_ttl_propagate(
return 0;
}
int config_parse_multipath_route(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
_cleanup_free_ char *word = NULL, *buf = NULL;
_cleanup_free_ MultipathRoute *m = NULL;
Network *network = userdata;
const char *p, *ip, *dev;
union in_addr_union a;
int family, r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = route_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
if (isempty(rvalue)) {
n->multipath_routes = ordered_set_free_free(n->multipath_routes);
return 0;
}
m = new0(MultipathRoute, 1);
if (!m)
return log_oom();
p = rvalue;
r = extract_first_word(&p, &word, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r <= 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid multipath route option, ignoring assignment: %s", rvalue);
return 0;
}
dev = strchr(word, '@');
if (dev) {
buf = strndup(word, dev - word);
if (!buf)
return log_oom();
ip = buf;
dev++;
} else
ip = word;
r = in_addr_from_string_auto(ip, &family, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue);
return 0;
}
m->gateway.address = a;
m->gateway.family = family;
if (dev) {
r = parse_ifindex_or_ifname(dev, &m->ifindex);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid interface name or index, ignoring assignment: %s", dev);
return 0;
}
}
if (!isempty(p)) {
r = safe_atou32(p, &m->weight);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid multipath route weight, ignoring assignment: %s", p);
return 0;
}
if (m->weight == 0 || m->weight > 256) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid multipath route weight, ignoring assignment: %s", p);
return 0;
}
}
r = ordered_set_ensure_allocated(&n->multipath_routes, NULL);
if (r < 0)
return log_oom();
r = ordered_set_put(n->multipath_routes, m);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to store multipath route, ignoring assignment: %m");
return 0;
}
TAKE_PTR(m);
TAKE_PTR(n);
return 0;
}
int route_section_verify(Route *route, Network *network) {
if (section_is_invalid(route->section))
return -EINVAL;

View File

@ -10,17 +10,6 @@ typedef struct NetworkConfigSection NetworkConfigSection;
#include "networkd-network.h"
#include "networkd-util.h"
typedef struct MultipathRouteVia {
uint16_t family;
union in_addr_union address;
} _packed_ MultipathRouteVia;
typedef struct MultipathRoute {
MultipathRouteVia gateway;
int ifindex;
uint32_t weight;
} MultipathRoute;
struct Route {
Network *network;
NetworkConfigSection *section;
@ -53,7 +42,6 @@ struct Route {
union in_addr_union dst;
union in_addr_union src;
union in_addr_union prefsrc;
OrderedSet *multipath_routes;
usec_t lifetime;
sd_event_source *expire;
@ -108,4 +96,3 @@ CONFIG_PARSER_PROTOTYPE(config_parse_quickack);
CONFIG_PARSER_PROTOTYPE(config_parse_fast_open_no_cookie);
CONFIG_PARSER_PROTOTYPE(config_parse_route_ttl_propagate);
CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu);
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);

View File

@ -11,7 +11,6 @@
#include "ether-addr-util.h"
#include "lockfile-util.h"
#include "missing_network.h"
#include "netif-naming-scheme.h"
#include "netlink-util.h"
#include "nspawn-network.h"
#include "parse-util.h"
@ -28,7 +27,6 @@
#define VETH_EXTRA_HOST_HASH_KEY SD_ID128_MAKE(48,c7,f6,b7,ea,9d,4c,9e,b7,28,d4,de,91,d5,bf,66)
#define VETH_EXTRA_CONTAINER_HASH_KEY SD_ID128_MAKE(af,50,17,61,ce,f9,4d,35,84,0d,2b,20,54,be,ce,59)
#define MACVLAN_HASH_KEY SD_ID128_MAKE(00,13,6d,bc,66,83,44,81,bb,0c,f9,51,1f,24,a6,6f)
#define SHORTEN_IFNAME_HASH_KEY SD_ID128_MAKE(e1,90,a4,04,a8,ef,4b,51,8c,cc,c3,3a,9f,11,fc,a2)
static int remove_one_link(sd_netlink *rtnl, const char *name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
@ -171,48 +169,6 @@ static int add_veth(
return 0;
}
/* This is almost base64char(), but not entirely, as it uses the "url and filename safe" alphabet, since we
* don't want "/" appear in interface names (since interfaces appear in sysfs as filenames). See section #5
* of RFC 4648. */
static char urlsafe_base64char(int x) {
static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789-_";
return table[x & 63];
}
static void shorten_ifname(char *ifname) {
char new_ifname[IFNAMSIZ];
assert(ifname);
if (strlen(ifname) < IFNAMSIZ) /* Name is short enough */
return;
if (naming_scheme_has(NAMING_NSPAWN_LONG_HASH)) {
uint64_t h;
/* Calculate 64bit hash value */
h = siphash24(ifname, strlen(ifname), SHORTEN_IFNAME_HASH_KEY.bytes);
/* Set the final four bytes (i.e. 32bit) to the lower 24bit of the hash, encoded in url-safe base64 */
memcpy(new_ifname, ifname, IFNAMSIZ - 5);
new_ifname[IFNAMSIZ - 5] = urlsafe_base64char(h >> 18);
new_ifname[IFNAMSIZ - 4] = urlsafe_base64char(h >> 12);
new_ifname[IFNAMSIZ - 3] = urlsafe_base64char(h >> 6);
new_ifname[IFNAMSIZ - 2] = urlsafe_base64char(h);
} else
/* On old nspawn versions we just truncated the name, provide compatibility */
memcpy(new_ifname, ifname, IFNAMSIZ-1);
new_ifname[IFNAMSIZ - 1] = 0;
/* Log the incident to make it more discoverable */
log_warning("Network interface name '%s' has been changed to '%s' to fit length constraints.", ifname, new_ifname);
strcpy(ifname, new_ifname);
}
int setup_veth(const char *machine_name,
pid_t pid,
char iface_name[IFNAMSIZ],
@ -220,9 +176,7 @@ int setup_veth(const char *machine_name,
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
struct ether_addr mac_host, mac_container;
unsigned u;
char *n;
int r;
int r, i;
assert(machine_name);
assert(pid > 0);
@ -230,8 +184,8 @@ int setup_veth(const char *machine_name,
/* Use two different interface name prefixes depending whether
* we are in bridge mode or not. */
n = strjoina(bridge ? "vb-" : "ve-", machine_name);
shorten_ifname(n);
snprintf(iface_name, IFNAMSIZ - 1, "%s-%s",
bridge ? "vb" : "ve", machine_name);
r = generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
if (r < 0)
@ -245,16 +199,15 @@ int setup_veth(const char *machine_name,
if (r < 0)
return log_error_errno(r, "Failed to connect to netlink: %m");
r = add_veth(rtnl, pid, n, &mac_host, "host0", &mac_container);
r = add_veth(rtnl, pid, iface_name, &mac_host, "host0", &mac_container);
if (r < 0)
return r;
u = if_nametoindex(n);
if (u == 0)
return log_error_errno(errno, "Failed to resolve interface %s: %m", n);
r = parse_ifindex_or_ifname(iface_name, &i);
if (r < 0)
return log_error_errno(r, "Failed to resolve interface %s: %m", iface_name);
strcpy(iface_name, n);
return (int) u;
return i;
}
int setup_veth_extra(
@ -442,50 +395,40 @@ int remove_bridge(const char *bridge_name) {
}
static int parse_interface(const char *name) {
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
int ifi, r;
r = parse_ifindex_or_ifname(name, &ifi);
if (r < 0)
return log_error_errno(r, "Failed to resolve interface %s: %m", name);
if (path_is_read_only_fs("/sys") <= 0) {
char ifi_str[2 + DECIMAL_STR_MAX(int)];
/* udev should be around. */
sprintf(ifi_str, "n%i", ifi);
r = sd_device_new_from_device_id(&d, ifi_str);
if (r < 0)
return log_error_errno(r, "Failed to get device %s: %m", name);
r = sd_device_get_is_initialized(d);
if (r < 0)
return log_error_errno(r, "Failed to determine whether interface %s is initialized: %m", name);
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Network interface %s is not initialized yet.", name);
r = device_is_renaming(d);
if (r < 0)
return log_error_errno(r, "Failed to determine the interface %s is being renamed: %m", name);
if (r > 0)
return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Interface %s is being renamed.", name);
}
return ifi;
}
int test_network_interface_initialized(const char *name) {
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
int ifi, r;
char ifi_str[2 + DECIMAL_STR_MAX(int)];
if (path_is_read_only_fs("/sys"))
return 0;
/* udev should be around. */
ifi = parse_interface(name);
if (ifi < 0)
return ifi;
sprintf(ifi_str, "n%i", ifi);
r = sd_device_new_from_device_id(&d, ifi_str);
if (r < 0)
return log_error_errno(r, "Failed to get device %s: %m", name);
r = sd_device_get_is_initialized(d);
if (r < 0)
return log_error_errno(r, "Failed to determine whether interface %s is initialized: %m", name);
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Network interface %s is not initialized yet.", name);
r = device_is_renaming(d);
if (r < 0)
return log_error_errno(r, "Failed to determine the interface %s is being renamed: %m", name);
if (r > 0)
return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Interface %s is being renamed.", name);
return 0;
}
int move_network_interfaces(int netns_fd, char **ifaces) {
int move_network_interfaces(pid_t pid, char **ifaces) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
char **i;
int r;
@ -509,9 +452,9 @@ int move_network_interfaces(int netns_fd, char **ifaces) {
if (r < 0)
return log_error_errno(r, "Failed to allocate netlink message: %m");
r = sd_netlink_message_append_u32(m, IFLA_NET_NS_FD, netns_fd);
r = sd_netlink_message_append_u32(m, IFLA_NET_NS_PID, pid);
if (r < 0)
return log_error_errno(r, "Failed to append namespace fd to netlink message: %m");
return log_error_errno(r, "Failed to append namespace PID to netlink message: %m");
r = sd_netlink_call(rtnl, m, 0, NULL);
if (r < 0)
@ -560,7 +503,7 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
if (!n)
return log_oom();
shorten_ifname(n);
strshorten(n, IFNAMSIZ-1);
r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
if (r < 0)
@ -635,7 +578,7 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
if (!n)
return log_oom();
shorten_ifname(n);
strshorten(n, IFNAMSIZ-1);
r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
if (r < 0)

View File

@ -5,8 +5,6 @@
#include <stdbool.h>
#include <sys/types.h>
int test_network_interface_initialized(const char *name);
int setup_veth(const char *machine_name, pid_t pid, char iface_name[IFNAMSIZ], bool bridge);
int setup_veth_extra(const char *machine_name, pid_t pid, char **pairs);
@ -16,7 +14,7 @@ int remove_bridge(const char *bridge_name);
int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces);
int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces);
int move_network_interfaces(int netns_fd, char **ifaces);
int move_network_interfaces(pid_t pid, char **ifaces);
int veth_extra_parse(char ***l, const char *p);

View File

@ -848,10 +848,6 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Network interface name not valid: %s", optarg);
r = test_network_interface_initialized(optarg);
if (r < 0)
return r;
if (strv_extend(&arg_network_interfaces, optarg) < 0)
return log_oom();
@ -865,10 +861,6 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"MACVLAN network interface name not valid: %s", optarg);
r = test_network_interface_initialized(optarg);
if (r < 0)
return r;
if (strv_extend(&arg_network_macvlan, optarg) < 0)
return log_oom();
@ -882,10 +874,6 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"IPVLAN network interface name not valid: %s", optarg);
r = test_network_interface_initialized(optarg);
if (r < 0)
return r;
if (strv_extend(&arg_network_ipvlan, optarg) < 0)
return log_oom();
@ -4211,7 +4199,7 @@ static int run_container(
int ifi = 0, r;
ssize_t l;
sigset_t mask_chld;
_cleanup_close_ int child_netns_fd = -1;
_cleanup_close_ int netns_fd = -1;
assert_se(sigemptyset(&mask_chld) == 0);
assert_se(sigaddset(&mask_chld, SIGCHLD) == 0);
@ -4270,11 +4258,11 @@ static int run_container(
return log_error_errno(errno, "Failed to install SIGCHLD handler: %m");
if (arg_network_namespace_path) {
child_netns_fd = open(arg_network_namespace_path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (child_netns_fd < 0)
netns_fd = open(arg_network_namespace_path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (netns_fd < 0)
return log_error_errno(errno, "Cannot open file %s: %m", arg_network_namespace_path);
r = fd_is_network_ns(child_netns_fd);
r = fd_is_network_ns(netns_fd);
if (r == -EUCLEAN)
log_debug_errno(r, "Cannot determine if passed network namespace path '%s' really refers to a network namespace, assuming it does.", arg_network_namespace_path);
else if (r < 0)
@ -4319,7 +4307,7 @@ static int run_container(
master_pty_socket_pair[1],
unified_cgroup_hierarchy_socket_pair[1],
fds,
child_netns_fd);
netns_fd);
if (r < 0)
_exit(EXIT_FAILURE);
@ -4421,15 +4409,7 @@ static int run_container(
return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Child died too early");
}
if (child_netns_fd < 0) {
/* Make sure we have an open file descriptor to the child's network
* namespace so it stays alive even if the child exits. */
r = namespace_open(*pid, NULL, NULL, &child_netns_fd, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to open child network namespace: %m");
}
r = move_network_interfaces(child_netns_fd, arg_network_interfaces);
r = move_network_interfaces(*pid, arg_network_interfaces);
if (r < 0)
return r;
@ -4675,36 +4655,6 @@ static int run_container(
/* Normally redundant, but better safe than sorry */
(void) kill(*pid, SIGKILL);
if (arg_private_network) {
/* Move network interfaces back to the parent network namespace. We use `safe_fork`
* to avoid having to move the parent to the child network namespace. */
r = safe_fork(NULL, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
if (r < 0)
return r;
if (r == 0) {
_cleanup_close_ int parent_netns_fd = -1;
r = namespace_open(getpid(), NULL, NULL, &parent_netns_fd, NULL, NULL);
if (r < 0) {
log_error_errno(r, "Failed to open parent network namespace: %m");
_exit(EXIT_FAILURE);
}
r = namespace_enter(-1, -1, child_netns_fd, -1, -1);
if (r < 0) {
log_error_errno(r, "Failed to enter child network namespace: %m");
_exit(EXIT_FAILURE);
}
r = move_network_interfaces(parent_netns_fd, arg_network_interfaces);
if (r < 0)
log_error_errno(r, "Failed to move network interfaces back to parent network namespace: %m");
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
}
r = wait_for_container(*pid, &container_status);
*pid = 0;

View File

@ -130,8 +130,6 @@ shared_sources = files('''
module-util.h
mount-util.c
mount-util.h
netif-naming-scheme.c
netif-naming-scheme.h
nscd-flush.c
nscd-flush.h
nsflags.c

View File

@ -40,6 +40,8 @@ libudev_core_sources = '''
udev-builtin-usb_id.c
net/link-config.c
net/link-config.h
net/naming-scheme.c
net/naming-scheme.h
'''.split()
if conf.get('HAVE_KMOD') == 1

View File

@ -16,7 +16,7 @@
#include "link-config.h"
#include "log.h"
#include "memory-util.h"
#include "netif-naming-scheme.h"
#include "naming-scheme.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "parse-util.h"

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "alloc-util.h"
#include "netif-naming-scheme.h"
#include "naming-scheme.h"
#include "proc-cmdline.h"
#include "string-util.h"
@ -11,7 +10,6 @@ static const NamingScheme naming_schemes[] = {
{ "v240", NAMING_V240 },
{ "v241", NAMING_V241 },
{ "v243", NAMING_V243 },
{ "v245", NAMING_V245 },
/* … add more schemes here, as the logic to name devices is updated … */
};

View File

@ -30,7 +30,6 @@ typedef enum NamingSchemeFlags {
NAMING_STABLE_VIRTUAL_MACS = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
NAMING_NETDEVSIM = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
NAMING_LABEL_NOPREFIX = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
NAMING_NSPAWN_LONG_HASH = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation */
/* And now the masks that combine the features above */
NAMING_V238 = 0,
@ -38,7 +37,6 @@ typedef enum NamingSchemeFlags {
NAMING_V240 = NAMING_V239 | NAMING_INFINIBAND | NAMING_ZERO_ACPI_INDEX | NAMING_ALLOW_RERENAMES,
NAMING_V241 = NAMING_V240 | NAMING_STABLE_VIRTUAL_MACS,
NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX,
NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH,
_NAMING_SCHEME_FLAGS_INVALID = -1,
} NamingSchemeFlags;

View File

@ -27,7 +27,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "netif-naming-scheme.h"
#include "naming-scheme.h"
#include "parse-util.h"
#include "proc-cmdline.h"
#include "stdio-util.h"

View File

@ -125,7 +125,6 @@ FastOpenNoCookie=
Source=
Metric=
TTLPropagate=
MultiPathRoute=
[Network]
IPv6DuplicateAddressDetection=
IPMasquerade=

View File

@ -12,10 +12,6 @@ IPv4LLRoute=yes
Destination=2001:1234:5:8fff:ff:ff:ff:ff/128
Scope=link
[Route]
Destination=2001:1234:5:9fff:ff:ff:ff:ff/128
Scope=link
[Route]
Destination=::/0
Gateway=2001:1234:5:8fff:ff:ff:ff:ff
@ -66,18 +62,3 @@ Destination=149.10.123.3
[Route]
Type=multicast
Destination=149.10.123.4
[Route]
Destination=192.168.10.1/32
MultiPathRoute=149.10.124.59@dummy98 10
MultiPathRoute=149.10.124.60@dummy98 5
[Route]
Destination=2001:1234:5:7fff:ff:ff:ff:ff/128
MultiPathRoute=2001:1234:5:8fff:ff:ff:ff:ff@dummy98 10
MultiPathRoute=2001:1234:5:9fff:ff:ff:ff:ff@dummy98 5
[Route]
Destination=192.168.10.2/32
MultiPathRoute=2001:1234:5:8fff:ff:ff:ff:ff@dummy98 10
MultiPathRoute=2001:1234:5:9fff:ff:ff:ff:ff@dummy98 5

View File

@ -1812,30 +1812,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, 'prohibit 202.54.1.4 proto static')
print('### ip route show 192.168.10.1')
output = check_output('ip route show 192.168.10.1')
print(output)
self.assertRegex(output, '192.168.10.1 proto static')
self.assertRegex(output, 'nexthop via 149.10.124.59 dev dummy98 weight 10')
self.assertRegex(output, 'nexthop via 149.10.124.60 dev dummy98 weight 5')
print('### ip route show 192.168.10.2')
output = check_output('ip route show 192.168.10.2')
print(output)
# old ip command does not show IPv6 gateways...
self.assertRegex(output, '192.168.10.2 proto static')
self.assertRegex(output, 'nexthop')
self.assertRegex(output, 'dev dummy98 weight 10')
self.assertRegex(output, 'dev dummy98 weight 5')
print('### ip -6 route show 2001:1234:5:7fff:ff:ff:ff:ff')
output = check_output('ip -6 route show 2001:1234:5:7fff:ff:ff:ff:ff')
print(output)
# old ip command does not show 'nexthop' keyword and weight...
self.assertRegex(output, '2001:1234:5:7fff:ff:ff:ff:ff')
self.assertRegex(output, 'via 2001:1234:5:8fff:ff:ff:ff:ff dev dummy98')
self.assertRegex(output, 'via 2001:1234:5:9fff:ff:ff:ff:ff dev dummy98')
def test_gateway_reconfigure(self):
copy_unit_to_networkd_unit_path('25-gateway-static.network', '12-dummy.netdev')
start_networkd()