summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/missing.h8
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c6
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c3
-rw-r--r--src/login/logind-inhibit.c5
-rw-r--r--src/network/netdev/netdev-gperf.gperf1
-rw-r--r--src/network/netdev/vxlan.c40
-rw-r--r--src/network/netdev/vxlan.h13
-rw-r--r--src/network/networkd-ipv4ll.c10
-rw-r--r--src/network/networkd-ndisc.c30
-rw-r--r--src/network/networkd-network.c2
-rw-r--r--src/nspawn/nspawn.c23
-rw-r--r--src/resolve/resolved-bus.c3
-rw-r--r--src/systemd/sd-ipv4ll.h1
-rw-r--r--src/udev/udev-builtin-net_id.c40
14 files changed, 175 insertions, 10 deletions
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 480462357d..284cbaffc0 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -726,7 +726,7 @@ struct btrfs_ioctl_quota_ctl_args {
#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1)
#endif
-#if !HAVE_DECL_IFLA_VXLAN_REMCSUM_NOPARTIAL
+#if !HAVE_DECL_IFLA_VXLAN_GPE
#define IFLA_VXLAN_UNSPEC 0
#define IFLA_VXLAN_ID 1
#define IFLA_VXLAN_GROUP 2
@@ -752,7 +752,11 @@ struct btrfs_ioctl_quota_ctl_args {
#define IFLA_VXLAN_REMCSUM_RX 22
#define IFLA_VXLAN_GBP 23
#define IFLA_VXLAN_REMCSUM_NOPARTIAL 24
-#define __IFLA_VXLAN_MAX 25
+#define IFLA_VXLAN_COLLECT_METADATA 25
+#define IFLA_VXLAN_LABEL 26
+#define IFLA_VXLAN_GPE 27
+
+#define __IFLA_VXLAN_MAX 28
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
#endif
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index 13209261f9..88a90e593b 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -248,6 +248,12 @@ static int ipv4ll_pick_address(sd_ipv4ll *ll) {
return sd_ipv4ll_set_address(ll, &(struct in_addr) { addr });
}
+int sd_ipv4ll_restart(sd_ipv4ll *ll) {
+ ll->address = 0;
+
+ return sd_ipv4ll_start(ll);
+}
+
#define MAC_HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
int sd_ipv4ll_start(sd_ipv4ll *ll) {
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index ff0e99558e..fc13a4ce14 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -170,6 +170,9 @@ static const NLType rtnl_link_info_data_vxlan_types[] = {
[IFLA_VXLAN_REMCSUM_RX] = { .type = NETLINK_TYPE_U8 },
[IFLA_VXLAN_GBP] = { .type = NETLINK_TYPE_FLAG },
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG },
+ [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG },
};
static const NLType rtnl_bond_arp_target_types[] = {
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index 5ca42b1ca2..1e6f383738 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -347,7 +347,7 @@ InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
assert(m);
HASHMAP_FOREACH(i, m->inhibitors, j)
- if (i->mode == mm)
+ if (i->mode == mm && i->started)
what |= i->what;
return what;
@@ -388,6 +388,9 @@ bool manager_is_inhibited(
assert(w > 0 && w < _INHIBIT_WHAT_MAX);
HASHMAP_FOREACH(i, m->inhibitors, j) {
+ if (!i->started)
+ continue;
+
if (!(i->what & w))
continue;
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index e19fa9817e..925af1c579 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -78,6 +78,7 @@ VXLAN.GroupPolicyExtension, config_parse_bool, 0,
VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb)
VXLAN.PortRange, config_parse_port_range, 0, 0
VXLAN.DestinationPort, config_parse_destination_port, 0, offsetof(VxLan, dest_port)
+VXLAN.FlowLabel, config_parse_flow_label, 0, 0
Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c
index b677b000fd..7f20e6cdfe 100644
--- a/src/network/netdev/vxlan.c
+++ b/src/network/netdev/vxlan.c
@@ -157,6 +157,10 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PORT_RANGE attribute: %m");
}
+ r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LABEL, htobe32(v->flow_label));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LABEL attribute: %m");
+
if (v->group_policy) {
r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GBP);
if (r < 0)
@@ -297,6 +301,42 @@ int config_parse_destination_port(const char *unit,
return 0;
}
+int config_parse_flow_label(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) {
+ VxLan *v = userdata;
+ unsigned f;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou(rvalue, &f);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN flow label '%s'.", rvalue);
+ return 0;
+ }
+
+ if (f & ~VXLAN_FLOW_LABEL_MAX_MASK) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "VXLAN flow label '%s' not valid. Flow label range should be [0-1048575].", rvalue);
+ return 0;
+ }
+
+ v->flow_label = f;
+
+ return 0;
+}
+
static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
VxLan *v = VXLAN(netdev);
diff --git a/src/network/netdev/vxlan.h b/src/network/netdev/vxlan.h
index dca58e7fe6..7f97a9edc4 100644
--- a/src/network/netdev/vxlan.h
+++ b/src/network/netdev/vxlan.h
@@ -25,6 +25,7 @@ typedef struct VxLan VxLan;
#include "netdev/netdev.h"
#define VXLAN_VID_MAX (1u << 24) - 1
+#define VXLAN_FLOW_LABEL_MAX_MASK 0xFFFFFU
struct VxLan {
NetDev meta;
@@ -40,6 +41,7 @@ struct VxLan {
unsigned tos;
unsigned ttl;
unsigned max_fdb;
+ unsigned flow_label;
uint16_t dest_port;
@@ -94,3 +96,14 @@ int config_parse_destination_port(const char *unit,
const char *rvalue,
void *data,
void *userdata);
+
+int config_parse_flow_label(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);
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 7ba05dbec3..e2578a298b 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -179,12 +179,22 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata) {
switch(event) {
case SD_IPV4LL_EVENT_STOP:
+ r = ipv4ll_address_lost(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return;
+ }
+ break;
case SD_IPV4LL_EVENT_CONFLICT:
r = ipv4ll_address_lost(link);
if (r < 0) {
link_enter_failed(link);
return;
}
+
+ r = sd_ipv4ll_restart(ll);
+ if (r < 0)
+ log_link_warning(link, "Could not acquire IPv4 link-local address");
break;
case SD_IPV4LL_EVENT_BIND:
r = ipv4ll_address_claimed(ll, link);
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 4fd5d8ae70..d52b511bb5 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -27,6 +27,7 @@
#define NDISC_DNSSL_MAX 64U
#define NDISC_RDNSS_MAX 64U
+#define NDISC_PREFIX_LFT_MIN 7200U
static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
@@ -152,13 +153,21 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
_cleanup_address_free_ Address *address = NULL;
- uint32_t lifetime_valid, lifetime_preferred;
+ Address *existing_address;
+ uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
+ usec_t time_now;
unsigned prefixlen;
int r;
assert(link);
assert(rt);
+ r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
+ return;
+ }
+
r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
if (r < 0) {
log_link_error_errno(link, r, "Failed to get prefix length: %m");
@@ -207,7 +216,24 @@ static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *
address->prefixlen = prefixlen;
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
address->cinfo.ifa_prefered = lifetime_preferred;
- address->cinfo.ifa_valid = lifetime_valid;
+
+ /* see RFC4862 section 5.5.3.e */
+ r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address);
+ if (r > 0) {
+ lifetime_remaining = existing_address->cinfo.tstamp / 100 + existing_address->cinfo.ifa_valid - time_now / USEC_PER_SEC;
+ if (lifetime_valid > NDISC_PREFIX_LFT_MIN || lifetime_valid > lifetime_remaining)
+ address->cinfo.ifa_valid = lifetime_valid;
+ else if (lifetime_remaining <= NDISC_PREFIX_LFT_MIN)
+ address->cinfo.ifa_valid = lifetime_remaining;
+ else
+ address->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN;
+ } else if (lifetime_valid > 0)
+ address->cinfo.ifa_valid = lifetime_valid;
+ else
+ return; /* see RFC4862 section 5.5.3.d */
+
+ if (address->cinfo.ifa_valid == 0)
+ return;
r = address_configure(address, link, ndisc_netlink_handler, true);
if (r < 0) {
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index ab372568de..fac42d8478 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -428,7 +428,7 @@ int network_apply(Network *network, Link *link) {
if (network->ipv4ll_route) {
Route *route;
- r = route_new_static(network, "Network", 0, &route);
+ r = route_new_static(network, NULL, 0, &route);
if (r < 0)
return r;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 1fc0501c2e..bce26a383b 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1321,17 +1321,32 @@ static int setup_timezone(const char *dest) {
return 0;
}
-static int resolved_running(void) {
+static int resolved_listening(void) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_free_ char *dns_stub_listener_mode = NULL;
int r;
- /* Check if resolved is running */
+ /* Check if resolved is listening */
r = sd_bus_open_system(&bus);
if (r < 0)
return r;
- return bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
+ r = bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
+ if (r <= 0)
+ return r;
+
+ r = sd_bus_get_property_string(bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "DNSStubListener",
+ NULL,
+ &dns_stub_listener_mode);
+ if (r < 0)
+ return r;
+
+ return STR_IN_SET(dns_stub_listener_mode, "udp", "yes");
}
static int setup_resolv_conf(const char *dest) {
@@ -1358,7 +1373,7 @@ static int setup_resolv_conf(const char *dest) {
}
if (access("/usr/lib/systemd/resolv.conf", F_OK) >= 0 &&
- resolved_running() > 0) {
+ resolved_listening() > 0) {
/* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
* container, so that the container can use the host's resolver. Given that network namespacing is
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 2c50109388..efa16ad93d 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -1450,6 +1450,8 @@ static int bus_property_get_ntas(
return sd_bus_message_close_container(reply);
}
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode);
+
static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
DnsScope *s;
@@ -1577,6 +1579,7 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported, 0, 0),
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
+ SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0),
SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h
index 1109ec52e0..5ba92083f4 100644
--- a/src/systemd/sd-ipv4ll.h
+++ b/src/systemd/sd-ipv4ll.h
@@ -47,6 +47,7 @@ int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index);
int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address);
int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed);
int sd_ipv4ll_is_running(sd_ipv4ll *ll);
+int sd_ipv4ll_restart(sd_ipv4ll *ll);
int sd_ipv4ll_start(sd_ipv4ll *ll);
int sd_ipv4ll_stop(sd_ipv4ll *ll);
sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll);
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index bd7b789cad..dcbfba359f 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -45,6 +45,7 @@
* — PCI geographical location
* [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
* — USB port number chain
+ * v<slot> - VIO slot number (IBM PowerVM)
*
* All multi-function PCI devices will carry the [f<function>] number in the
* device name, including the function 0 device.
@@ -122,6 +123,7 @@ enum netname_type{
NET_BCMA,
NET_VIRTIO,
NET_CCW,
+ NET_VIO,
};
struct netnames {
@@ -139,6 +141,7 @@ struct netnames {
char usb_ports[IFNAMSIZ];
char bcma_core[IFNAMSIZ];
char ccw_busid[IFNAMSIZ];
+ char vio_slot[IFNAMSIZ];
};
/* skip intermediate virtio devices */
@@ -319,6 +322,33 @@ out:
return err;
}
+static int names_vio(struct udev_device *dev, struct netnames *names) {
+ struct udev_device *parent;
+ unsigned busid, slotid, ethid;
+ const char *syspath;
+
+ /* check if our direct parent is a VIO device with no other bus in-between */
+ parent = udev_device_get_parent(dev);
+ if (!parent)
+ return -ENOENT;
+
+ if (!streq_ptr("vio", udev_device_get_subsystem(parent)))
+ return -ENOENT;
+
+ /* The devices' $DEVPATH number is tied to (virtual) hardware (slot id
+ * selected in the HMC), thus this provides a reliable naming (e.g.
+ * "/devices/vio/30000002/net/eth1"); we ignore the bus number, as
+ * there should only ever be one bus, and then remove leading zeros. */
+ syspath = udev_device_get_syspath(dev);
+
+ if (sscanf(syspath, "/sys/devices/vio/%4x%4x/net/eth%u", &busid, &slotid, &ethid) != 3)
+ return -EINVAL;
+
+ xsprintf(names->vio_slot, "v%u", slotid);
+ names->type = NET_VIO;
+ return 0;
+}
+
static int names_pci(struct udev_device *dev, struct netnames *names) {
struct udev_device *parent;
@@ -591,6 +621,16 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
goto out;
}
+ /* get ibmveth/ibmvnic slot-based names. */
+ err = names_vio(dev, &names);
+ if (err >= 0 && names.type == NET_VIO) {
+ char str[IFNAMSIZ];
+
+ if (snprintf(str, sizeof(str), "%s%s", prefix, names.vio_slot) < (int)sizeof(str))
+ udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+ goto out;
+ }
+
/* get PCI based path names, we compose only PCI based paths */
err = names_pci(dev, &names);
if (err < 0)