summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkctl.c116
-rw-r--r--src/network/networkd-address-pool.c1
-rw-r--r--src/network/networkd-address.c27
-rw-r--r--src/network/networkd-dhcp4.c105
-rw-r--r--src/network/networkd-dhcp6.c103
-rw-r--r--src/network/networkd-fdb.c84
-rw-r--r--src/network/networkd-link.c925
-rw-r--r--src/network/networkd-link.h25
-rw-r--r--src/network/networkd-manager.c16
-rw-r--r--src/network/networkd-netdev-bond.c319
-rw-r--r--src/network/networkd-netdev-bond.h85
-rw-r--r--src/network/networkd-netdev-bridge.c4
-rw-r--r--src/network/networkd-netdev-dummy.c5
-rw-r--r--src/network/networkd-netdev-gperf.gperf108
-rw-r--r--src/network/networkd-netdev-ipvlan.c3
-rw-r--r--src/network/networkd-netdev-macvlan.c2
-rw-r--r--src/network/networkd-netdev-tunnel.c287
-rw-r--r--src/network/networkd-netdev-tunnel.h1
-rw-r--r--src/network/networkd-netdev-tuntap.c14
-rw-r--r--src/network/networkd-netdev-veth.c2
-rw-r--r--src/network/networkd-netdev-vlan.c2
-rw-r--r--src/network/networkd-netdev-vxlan.c29
-rw-r--r--src/network/networkd-netdev-vxlan.h3
-rw-r--r--src/network/networkd-netdev.c197
-rw-r--r--src/network/networkd-netdev.h36
-rw-r--r--src/network/networkd-network-bus.c2
-rw-r--r--src/network/networkd-network-gperf.gperf3
-rw-r--r--src/network/networkd-network.c54
-rw-r--r--src/network/networkd-route.c3
-rw-r--r--src/network/networkd-wait-online-link.c2
-rw-r--r--src/network/networkd-wait-online-manager.c1
-rw-r--r--src/network/networkd-wait-online.c5
-rw-r--r--src/network/networkd-wait-online.h1
-rw-r--r--src/network/networkd.c15
-rw-r--r--src/network/networkd.h18
-rw-r--r--src/network/test-network-tables.c1
36 files changed, 1573 insertions, 1031 deletions
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index aa83f32f53..3454394977 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -26,7 +26,7 @@
#include "sd-network.h"
#include "sd-rtnl.h"
#include "sd-hwdb.h"
-#include "libudev.h"
+#include "sd-device.h"
#include "strv.h"
#include "build.h"
@@ -34,13 +34,14 @@
#include "pager.h"
#include "lldp.h"
#include "rtnl-util.h"
-#include "udev-util.h"
+#include "device-util.h"
#include "hwdb-util.h"
#include "arphrd-list.h"
#include "local-addresses.h"
#include "socket-util.h"
#include "ether-addr-util.h"
#include "verbs.h"
+#include "terminal-util.h"
static bool arg_no_pager = false;
static bool arg_legend = true;
@@ -54,17 +55,20 @@ static void pager_open_if_enabled(void) {
pager_open(false);
}
-static int link_get_type_string(int iftype, struct udev_device *d, char **ret) {
+static int link_get_type_string(int iftype, sd_device *d, char **ret) {
const char *t;
char *p;
+ assert(ret);
+
if (iftype == ARPHRD_ETHER && d) {
- const char *devtype, *id = NULL;
+ const char *devtype = NULL, *id = NULL;
/* WLANs have iftype ARPHRD_ETHER, but we want
* to show a more useful type string for
* them */
- devtype = udev_device_get_devtype(d);
+ (void)sd_device_get_devtype(d, &devtype);
+
if (streq_ptr(devtype, "wlan"))
id = "wlan";
else if (streq_ptr(devtype, "wwan"))
@@ -189,7 +193,6 @@ static void setup_state_to_color(const char *state, const char **on, const char
static int list_links(int argc, char *argv[], void *userdata) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
- _cleanup_udev_unref_ struct udev *udev = NULL;
_cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
_cleanup_free_ LinkInfo *links = NULL;
int r, c, i;
@@ -200,10 +203,6 @@ static int list_links(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to connect to netlink: %m");
- udev = udev_new();
- if (!udev)
- return log_error_errno(errno, "Failed to connect to udev: %m");
-
r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
if (r < 0)
return rtnl_log_create_error(r);
@@ -225,7 +224,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
for (i = 0; i < c; i++) {
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
- _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_device_unref_ sd_device *d = NULL;
const char *on_color_operational, *off_color_operational,
*on_color_setup, *off_color_setup;
char devid[2 + DECIMAL_STR_MAX(int)];
@@ -238,7 +237,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
sprintf(devid, "n%i", links[i].ifindex);
- d = udev_device_new_from_device_id(udev, devid);
+ (void)sd_device_new_from_device_id(&d, devid);
link_get_type_string(links[i].iftype, d, &t);
@@ -495,19 +494,19 @@ static void dump_list(const char *prefix, char **l) {
static int link_status_one(
sd_rtnl *rtnl,
- struct udev *udev,
sd_hwdb *hwdb,
const char *name) {
-
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
- _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_device_unref_ sd_device *d = NULL;
char devid[2 + DECIMAL_STR_MAX(int)];
_cleanup_free_ char *t = NULL, *network = NULL;
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
const char *on_color_operational, *off_color_operational,
*on_color_setup, *off_color_setup;
+ _cleanup_strv_free_ char **carrier_bound_to = NULL;
+ _cleanup_strv_free_ char **carrier_bound_by = NULL;
struct ether_addr e;
unsigned iftype;
int r, ifindex;
@@ -515,7 +514,6 @@ static int link_status_one(
uint32_t mtu;
assert(rtnl);
- assert(udev);
assert(name);
if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0)
@@ -587,31 +585,36 @@ static int link_status_one(
}
sprintf(devid, "n%i", ifindex);
- d = udev_device_new_from_device_id(udev, devid);
+
+ (void)sd_device_new_from_device_id(&d, devid);
+
if (d) {
- link = udev_device_get_property_value(d, "ID_NET_LINK_FILE");
- driver = udev_device_get_property_value(d, "ID_NET_DRIVER");
- path = udev_device_get_property_value(d, "ID_PATH");
+ (void)sd_device_get_property_value(d, "ID_NET_LINK_FILE", &link);
+ (void)sd_device_get_property_value(d, "ID_NET_DRIVER", &driver);
+ (void)sd_device_get_property_value(d, "ID_PATH", &path);
- vendor = udev_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE");
- if (!vendor)
- vendor = udev_device_get_property_value(d, "ID_VENDOR");
+ r = sd_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE", &vendor);
+ if (r < 0)
+ (void)sd_device_get_property_value(d, "ID_VENDOR", &vendor);
- model = udev_device_get_property_value(d, "ID_MODEL_FROM_DATABASE");
- if (!model)
- model = udev_device_get_property_value(d, "ID_MODEL");
+ r = sd_device_get_property_value(d, "ID_MODEL_FROM_DATABASE", &model);
+ if (r < 0)
+ (void)sd_device_get_property_value(d, "ID_MODEL", &model);
}
link_get_type_string(iftype, d, &t);
sd_network_link_get_network_file(ifindex, &network);
+ sd_network_link_get_carrier_bound_to(ifindex, &carrier_bound_to);
+ sd_network_link_get_carrier_bound_by(ifindex, &carrier_bound_by);
+
printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name);
- printf(" Link File: %s\n"
- "Network File: %s\n"
- " Type: %s\n"
- " State: %s%s%s (%s%s%s)\n",
+ printf(" Link File: %s\n"
+ " Network File: %s\n"
+ " Type: %s\n"
+ " State: %s%s%s (%s%s%s)\n",
strna(link),
strna(network),
strna(t),
@@ -619,13 +622,13 @@ static int link_status_one(
on_color_setup, strna(setup_state), off_color_setup);
if (path)
- printf(" Path: %s\n", path);
+ printf(" Path: %s\n", path);
if (driver)
- printf(" Driver: %s\n", driver);
+ printf(" Driver: %s\n", driver);
if (vendor)
- printf(" Vendor: %s\n", vendor);
+ printf(" Vendor: %s\n", vendor);
if (model)
- printf(" Model: %s\n", model);
+ printf(" Model: %s\n", model);
if (have_mac) {
_cleanup_free_ char *description = NULL;
@@ -634,30 +637,35 @@ static int link_status_one(
ieee_oui(hwdb, &e, &description);
if (description)
- printf(" HW Address: %s (%s)\n", ether_addr_to_string(&e, ea), description);
+ printf(" HW Address: %s (%s)\n", ether_addr_to_string(&e, ea), description);
else
- printf(" HW Address: %s\n", ether_addr_to_string(&e, ea));
+ printf(" HW Address: %s\n", ether_addr_to_string(&e, ea));
}
if (mtu > 0)
- printf(" MTU: %u\n", mtu);
+ printf(" MTU: %u\n", mtu);
- dump_addresses(rtnl, " Address: ", ifindex);
- dump_gateways(rtnl, hwdb, " Gateway: ", ifindex);
+ dump_addresses(rtnl, " Address: ", ifindex);
+ dump_gateways(rtnl, hwdb, " Gateway: ", ifindex);
if (!strv_isempty(dns))
- dump_list(" DNS: ", dns);
+ dump_list(" DNS: ", dns);
if (!strv_isempty(domains))
- dump_list(" Domain: ", domains);
+ dump_list(" Domain: ", domains);
if (!strv_isempty(ntp))
- dump_list(" NTP: ", ntp);
+ dump_list(" NTP: ", ntp);
+
+ if (!strv_isempty(carrier_bound_to))
+ dump_list("Carrier Bound To: ", carrier_bound_to);
+
+ if (!strv_isempty(carrier_bound_by))
+ dump_list("Carrier Bound By: ", carrier_bound_by);
return 0;
}
static int link_status(int argc, char *argv[], void *userdata) {
_cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL;
- _cleanup_udev_unref_ struct udev *udev = NULL;
_cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
char **name;
int r;
@@ -666,10 +674,6 @@ static int link_status(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to connect to netlink: %m");
- udev = udev_new();
- if (!udev)
- return log_error_errno(errno, "Failed to connect to udev: %m");
-
r = sd_hwdb_new(&hwdb);
if (r < 0)
log_debug_errno(r, "Failed to open hardware database: %m");
@@ -731,14 +735,14 @@ static int link_status(int argc, char *argv[], void *userdata) {
if (i > 0)
fputc('\n', stdout);
- link_status_one(rtnl, udev, hwdb, links[i].name);
+ link_status_one(rtnl, hwdb, links[i].name);
}
} else {
STRV_FOREACH(name, argv + 1) {
if (name != argv + 1)
fputc('\n', stdout);
- link_status_one(rtnl, udev, hwdb, *name);
+ link_status_one(rtnl, hwdb, *name);
}
}
@@ -954,17 +958,17 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) {
continue;
if (streq(a, "_Chassis")) {
- chassis = strdup(b);
- if (!chassis)
- return -ENOMEM;
+ r = free_and_strdup(&chassis, b);
+ if (r < 0)
+ return r;
} else if (streq(a, "_Port")) {
- port = strdup(b);
- if (!port)
- return -ENOMEM;
+ r = free_and_strdup(&port, b);
+ if (r < 0)
+ return r;
} else if (streq(a, "_TTL")) {
- long long unsigned x;
+ long long unsigned x = 0;
usec_t time;
r = safe_atollu(b, &x);
diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c
index 7ad11c6177..584a956a7e 100644
--- a/src/network/networkd-address-pool.c
+++ b/src/network/networkd-address-pool.c
@@ -19,7 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <arpa/inet.h>
#include "networkd.h"
#include "networkd-link.h"
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 47033acde4..069ba3eccb 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -25,7 +25,6 @@
#include "util.h"
#include "conf-parser.h"
#include "fw-util.h"
-#include "network-internal.h"
#include "networkd.h"
#include "networkd-link.h"
@@ -210,10 +209,18 @@ int address_update(Address *address, Link *link,
if (r < 0)
return log_error_errno(r, "Could not set prefixlen: %m");
- r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+ address->flags |= IFA_F_PERMANENT;
+
+ r = sd_rtnl_message_addr_set_flags(req, address->flags & 0xff);
if (r < 0)
return log_error_errno(r, "Could not set flags: %m");
+ if (address->flags & ~0xff && link->rtnl_extended_attrs) {
+ r = sd_rtnl_message_append_u32(req, IFA_FLAGS, address->flags);
+ if (r < 0)
+ return log_error_errno(r, "Could not set extended flags: %m");
+ }
+
r = sd_rtnl_message_addr_set_scope(req, address->scope);
if (r < 0)
return log_error_errno(r, "Could not set scope: %m");
@@ -267,10 +274,8 @@ static int address_acquire(Link *link, Address *original, Address **ret) {
/* The address is configured to be 0.0.0.0 or [::] by the user?
* Then let's acquire something more useful from the pool. */
r = manager_address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr);
- if (r < 0) {
- log_link_error(link, "Failed to acquire address from pool: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to acquire address from pool: %m");
if (r == 0) {
log_link_error(link, "Couldn't find free address for interface, all taken.");
return -EBUSY;
@@ -336,10 +341,18 @@ int address_configure(Address *address, Link *link,
if (r < 0)
return log_error_errno(r, "Could not set prefixlen: %m");
- r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+ address->flags |= IFA_F_PERMANENT;
+
+ r = sd_rtnl_message_addr_set_flags(req, (address->flags & 0xff));
if (r < 0)
return log_error_errno(r, "Could not set flags: %m");
+ if (address->flags & ~0xff) {
+ r = sd_rtnl_message_append_u32(req, IFA_FLAGS, address->flags);
+ if (r < 0)
+ return log_error_errno(r, "Could not set extended flags: %m");
+ }
+
r = sd_rtnl_message_addr_set_scope(req, address->scope);
if (r < 0)
return log_error_errno(r, "Could not set scope: %m");
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index c3d0e3d39d..20aee53d6e 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -22,6 +22,7 @@
#include <netinet/ether.h>
#include <linux/if.h>
+#include "hostname-util.h"
#include "networkd-link.h"
#include "network-internal.h"
#include "dhcp-lease-internal.h"
@@ -409,62 +410,43 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
assert(link);
r = sd_dhcp_client_get_lease(client, &lease);
- if (r < 0) {
- log_link_warning(link, "DHCP error: no lease: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "DHCP error: no lease: %m");
r = sd_dhcp_lease_get_address(lease, &address);
- if (r < 0) {
- log_link_warning(link, "DHCP error: no address: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "DHCP error: no address: %m");
r = sd_dhcp_lease_get_netmask(lease, &netmask);
- if (r < 0) {
- log_link_warning(link, "DHCP error: no netmask: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "DHCP error: no netmask: %m");
prefixlen = in_addr_netmask_to_prefixlen(&netmask);
r = sd_dhcp_lease_get_router(lease, &gateway);
- if (r < 0 && r != -ENOENT) {
- log_link_warning(link, "DHCP error: could not get gateway: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0 && r != -ENOENT)
+ return log_link_error_errno(link, r, "DHCP error: could not get gateway: %m");
if (r >= 0)
- log_link_struct(link, LOG_INFO,
- "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
- IFNAMSIZ,
- link->ifname,
- ADDRESS_FMT_VAL(address),
- prefixlen,
- ADDRESS_FMT_VAL(gateway),
- "ADDRESS=%u.%u.%u.%u",
- ADDRESS_FMT_VAL(address),
- "PREFIXLEN=%u",
- prefixlen,
- "GATEWAY=%u.%u.%u.%u",
- ADDRESS_FMT_VAL(gateway),
- NULL);
+ log_struct(LOG_INFO,
+ LOG_LINK_INTERFACE(link),
+ LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
+ ADDRESS_FMT_VAL(address),
+ prefixlen,
+ ADDRESS_FMT_VAL(gateway)),
+ "ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
+ "PREFIXLEN=%u", prefixlen,
+ "GATEWAY=%u.%u.%u.%u", ADDRESS_FMT_VAL(gateway),
+ NULL);
else
- log_link_struct(link, LOG_INFO,
- "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
- IFNAMSIZ,
- link->ifname,
- ADDRESS_FMT_VAL(address),
- prefixlen,
- "ADDRESS=%u.%u.%u.%u",
- ADDRESS_FMT_VAL(address),
- "PREFIXLEN=%u",
- prefixlen,
- NULL);
+ log_struct(LOG_INFO,
+ LOG_LINK_INTERFACE(link),
+ LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u",
+ ADDRESS_FMT_VAL(address),
+ prefixlen),
+ "ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
+ "PREFIXLEN=%u", prefixlen,
+ NULL);
link->dhcp_lease = lease;
@@ -475,8 +457,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
if (r >= 0) {
r = link_set_mtu(link, mtu);
if (r < 0)
- log_link_error(link, "Failed to set MTU "
- "to %" PRIu16, mtu);
+ log_link_error_errno(link, r, "Failed to set MTU to %" PRIu16 ": %m", mtu);
}
}
@@ -487,27 +468,21 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
if (r >= 0) {
r = link_set_hostname(link, hostname);
if (r < 0)
- log_link_error(link,
- "Failed to set transient hostname to '%s'",
- hostname);
+ log_link_error_errno(link, r, "Failed to set transient hostname to '%s': %m", hostname);
}
}
if (!link->network->dhcp_critical) {
- r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
- &lifetime);
+ r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
if (r < 0) {
- log_link_warning(link,
- "DHCP error: no lifetime: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
return r;
}
}
r = dhcp4_update_address(link, &address, &netmask, lifetime);
if (r < 0) {
- log_link_warning(link, "could not update IP address: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not update IP address: %m");
link_enter_failed(link);
return r;
}
@@ -661,5 +636,21 @@ int dhcp4_configure(Link *link) {
return r;
}
+ switch (link->network->dhcp_client_identifier) {
+ case DHCP_CLIENT_ID_DUID:
+ /* Library defaults to this. */
+ break;
+ case DHCP_CLIENT_ID_MAC:
+ r = sd_dhcp_client_set_client_id(link->dhcp_client,
+ ARPHRD_ETHER,
+ (const uint8_t *) &link->mac,
+ sizeof (link->mac));
+ if (r < 0)
+ return r;
+ break;
+ default:
+ assert_not_reached("Unknown client identifier type.");
+ }
+
return 0;
}
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index bcfad4c03f..33e18137d2 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -28,6 +28,8 @@
#include "sd-icmp6-nd.h"
#include "sd-dhcp6-client.h"
+static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
+
static int dhcp6_lease_information_acquired(sd_dhcp6_client *client,
Link *link) {
return 0;
@@ -42,6 +44,15 @@ static int dhcp6_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
+ if (link->rtnl_extended_attrs) {
+ log_link_warning(link, "Could not set extended netlink attributes, reverting to fallback mechanism");
+
+ link->rtnl_extended_attrs = false;
+ dhcp6_lease_address_acquired(link->dhcp6_client, link);
+
+ return 1;
+ }
+
log_link_error(link, "Could not set DHCPv6 address: %s",
strerror(-r));
@@ -65,61 +76,25 @@ static int dhcp6_address_update(Link *link, struct in6_addr *ip6_addr,
addr->family = AF_INET6;
memcpy(&addr->in_addr.in6, ip6_addr, sizeof(*ip6_addr));
+
+ addr->flags = IFA_F_NOPREFIXROUTE;
addr->prefixlen = prefixlen;
addr->cinfo.ifa_prefered = lifetime_preferred;
addr->cinfo.ifa_valid = lifetime_valid;
- log_link_struct(link, LOG_INFO, "MESSAGE=%-*s: DHCPv6 address "SD_ICMP6_ADDRESS_FORMAT_STR"/%d timeout preferred %d valid %d",
- IFNAMSIZ,
- link->ifname, SD_ICMP6_ADDRESS_FORMAT_VAL(addr->in_addr.in6),
- addr->prefixlen, lifetime_preferred, lifetime_valid,
- NULL);
+ log_link_info(link,
+ "DHCPv6 address "SD_ICMP6_ADDRESS_FORMAT_STR"/%d timeout preferred %d valid %d",
+ SD_ICMP6_ADDRESS_FORMAT_VAL(addr->in_addr.in6),
+ addr->prefixlen, lifetime_preferred, lifetime_valid);
r = address_update(addr, link, dhcp6_address_handler);
if (r < 0)
- log_link_warning(link, "Could not assign DHCPv6 address: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not assign DHCPv6 address: %m");
return r;
}
-static int dhcp6_prefix_expired(Link *link) {
- int r;
- sd_dhcp6_lease *lease;
- struct in6_addr *expired_prefix, ip6_addr;
- uint8_t expired_prefixlen;
- uint32_t lifetime_preferred, lifetime_valid;
-
- r = sd_icmp6_ra_get_expired_prefix(link->icmp6_router_discovery,
- &expired_prefix, &expired_prefixlen);
- if (r < 0)
- return r;
-
- r = sd_dhcp6_client_get_lease(link->dhcp6_client, &lease);
- if (r < 0)
- return r;
-
- sd_dhcp6_lease_reset_address_iter(lease);
-
- while (sd_dhcp6_lease_get_address(lease, &ip6_addr,
- &lifetime_preferred,
- &lifetime_valid) >= 0) {
-
- r = sd_icmp6_prefix_match(expired_prefix, expired_prefixlen,
- &ip6_addr);
- if (r >= 0) {
- r = dhcp6_address_update(link, &ip6_addr, 128,
- lifetime_preferred,
- lifetime_valid);
-
- return r;
- }
- }
-
- return 0;
-}
-
static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) {
int r;
sd_dhcp6_lease *lease;
@@ -296,6 +271,45 @@ static int dhcp6_configure(Link *link, int event) {
return r;
}
+static int dhcp6_prefix_expired(Link *link) {
+ int r;
+ sd_dhcp6_lease *lease;
+ struct in6_addr *expired_prefix, ip6_addr;
+ uint8_t expired_prefixlen;
+ uint32_t lifetime_preferred, lifetime_valid;
+
+ r = sd_icmp6_ra_get_expired_prefix(link->icmp6_router_discovery,
+ &expired_prefix, &expired_prefixlen);
+ if (r < 0)
+ return r;
+
+ r = sd_dhcp6_client_get_lease(link->dhcp6_client, &lease);
+ if (r < 0)
+ return r;
+
+ log_link_info(link, "IPv6 prefix "SD_ICMP6_ADDRESS_FORMAT_STR"/%d expired",
+ SD_ICMP6_ADDRESS_FORMAT_VAL(*expired_prefix),
+ expired_prefixlen);
+
+ sd_dhcp6_lease_reset_address_iter(lease);
+
+ while (sd_dhcp6_lease_get_address(lease, &ip6_addr,
+ &lifetime_preferred,
+ &lifetime_valid) >= 0) {
+
+ r = sd_icmp6_prefix_match(expired_prefix, expired_prefixlen,
+ &ip6_addr);
+ if (r < 0)
+ continue;
+
+ log_link_info(link, "IPv6 prefix length updated "SD_ICMP6_ADDRESS_FORMAT_STR"/%d", SD_ICMP6_ADDRESS_FORMAT_VAL(ip6_addr), 128);
+
+ dhcp6_address_update(link, &ip6_addr, 128, lifetime_preferred, lifetime_valid);
+ }
+
+ return 0;
+}
+
static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
Link *link = userdata;
@@ -318,7 +332,8 @@ static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
break;
case ICMP6_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED:
- dhcp6_prefix_expired(link);
+ if (!link->rtnl_extended_attrs)
+ dhcp6_prefix_expired(link);
break;
diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c
index feab8d421e..796d1117b6 100644
--- a/src/network/networkd-fdb.c
+++ b/src/network/networkd-fdb.c
@@ -19,16 +19,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <ctype.h>
#include <net/if.h>
#include <net/ethernet.h>
#include "networkd.h"
-#include "networkd-netdev.h"
#include "networkd-link.h"
-#include "network-internal.h"
-#include "path-util.h"
-#include "conf-files.h"
#include "conf-parser.h"
#include "util.h"
@@ -93,7 +88,7 @@ static int set_fdb_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
- log_link_error(link, "Could not add FDB entry: %s", strerror(-r));
+ log_link_error_errno(link, r, "Could not add FDB entry: %m");
return 1;
}
@@ -138,10 +133,8 @@ int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry) {
/* send message to the kernel to update its internal static MAC table. */
r = sd_rtnl_call_async(rtnl, req, set_fdb_handler, link, 0, NULL);
- if (r < 0) {
- log_link_error(link, "Could not send rtnetlink message: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
return 0;
}
@@ -155,9 +148,9 @@ void fdb_entry_free(FdbEntry *fdb_entry) {
LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries,
fdb_entry);
- if(fdb_entry->section)
- hashmap_remove(fdb_entry->network->fdb_entries_by_section,
- UINT_TO_PTR(fdb_entry->section));
+ if (fdb_entry->section)
+ hashmap_remove(fdb_entry->network->fdb_entries_by_section,
+ UINT_TO_PTR(fdb_entry->section));
}
free(fdb_entry->mac_addr);
@@ -166,16 +159,18 @@ void fdb_entry_free(FdbEntry *fdb_entry) {
}
/* parse the HW address from config files. */
-int config_parse_fdb_hwaddr(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) {
+int config_parse_fdb_hwaddr(
+ 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) {
+
Network *network = userdata;
_cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL;
int r;
@@ -187,10 +182,8 @@ int config_parse_fdb_hwaddr(const char *unit,
assert(data);
r = fdb_entry_new_static(network, section_line, &fdb_entry);
- if (r < 0) {
- log_error("Failed to allocate a new FDB entry: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_oom();
/* read in the MAC address for the FDB table. */
r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
@@ -201,9 +194,8 @@ int config_parse_fdb_hwaddr(const char *unit,
&fdb_entry->mac_addr->ether_addr_octet[4],
&fdb_entry->mac_addr->ether_addr_octet[5]);
- if (ETHER_ADDR_LEN != r) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Not a valid MAC address, ignoring assignment: %s", rvalue);
+ if (ETHER_ADDR_LEN != r) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Not a valid MAC address, ignoring assignment: %s", rvalue);
return 0;
}
@@ -213,16 +205,18 @@ int config_parse_fdb_hwaddr(const char *unit,
}
/* parse the VLAN Id from config files. */
-int config_parse_fdb_vlan_id(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) {
+int config_parse_fdb_vlan_id(
+ 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) {
+
Network *network = userdata;
_cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL;
int r;
@@ -234,18 +228,14 @@ int config_parse_fdb_vlan_id(const char *unit,
assert(data);
r = fdb_entry_new_static(network, section_line, &fdb_entry);
- if (r < 0) {
- log_error("Failed to allocate a new FDB entry: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_oom();
r = config_parse_unsigned(unit, filename, line, section,
section_line, lvalue, ltype,
rvalue, &fdb_entry->vlan_id, userdata);
- if (r < 0) {
- log_error("Failed to parse the unsigned integer: %s", strerror(-r));
+ if (r < 0)
return r;
- }
fdb_entry = NULL;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index f716e8231a..b30fd7ae89 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -26,14 +26,12 @@
#include "util.h"
#include "virt.h"
#include "fileio.h"
+#include "socket-util.h"
#include "bus-util.h"
#include "udev-util.h"
-#include "libudev-private.h"
#include "network-internal.h"
#include "networkd-link.h"
#include "networkd-netdev.h"
-#include "conf-parser.h"
-#include "dhcp-lease-internal.h"
bool link_dhcp6_enabled(Link *link) {
if (link->flags & IFF_LOOPBACK)
@@ -131,10 +129,8 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) {
assert(link);
r = sd_rtnl_message_link_get_flags(m, &flags);
- if (r < 0) {
- log_link_warning(link, "Could not get link flags");
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not get link flags: %m");
r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
if (r < 0)
@@ -146,7 +142,7 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) {
return 0;
if (link->flags != flags) {
- log_link_debug(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ log_link_debug(link, "Flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
@@ -180,12 +176,12 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) {
* printing 20 */
if (unknown_flags_added)
log_link_debug(link,
- "unknown link flags gained: %#.5x (ignoring)",
+ "Unknown link flags gained: %#.5x (ignoring)",
unknown_flags_added);
if (unknown_flags_removed)
log_link_debug(link,
- "unknown link flags lost: %#.5x (ignoring)",
+ "Unknown link flags lost: %#.5x (ignoring)",
unknown_flags_removed);
}
@@ -230,6 +226,7 @@ static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
link->n_ref = 1;
link->manager = manager;
link->state = LINK_STATE_PENDING;
+ link->rtnl_extended_attrs = true;
link->ifindex = ifindex;
link->ifname = strdup(ifname);
if (!link->ifname)
@@ -275,6 +272,8 @@ static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
static void link_free(Link *link) {
Address *address;
+ Iterator i;
+ Link *carrier;
if (!link)
return;
@@ -312,6 +311,14 @@ static void link_free(Link *link) {
udev_device_unref(link->udev_device);
+ HASHMAP_FOREACH (carrier, link->bound_to_links, i)
+ hashmap_remove(link->bound_to_links, INT_TO_PTR(carrier->ifindex));
+ hashmap_free(link->bound_to_links);
+
+ HASHMAP_FOREACH (carrier, link->bound_by_links, i)
+ hashmap_remove(link->bound_by_links, INT_TO_PTR(carrier->ifindex));
+ hashmap_free(link->bound_by_links);
+
free(link);
}
@@ -358,23 +365,10 @@ static void link_set_state(Link *link, LinkState state) {
return;
}
-void link_drop(Link *link) {
- if (!link || link->state == LINK_STATE_LINGER)
- return;
-
- link_set_state(link, LINK_STATE_LINGER);
-
- log_link_debug(link, "link removed");
-
- link_unref(link);
-
- return;
-}
-
static void link_enter_unmanaged(Link *link) {
assert(link);
- log_link_debug(link, "unmanaged");
+ log_link_debug(link, "Unmanaged");
link_set_state(link, LINK_STATE_UNMANAGED);
@@ -393,50 +387,32 @@ static int link_stop_clients(Link *link) {
if (link->dhcp_client) {
k = sd_dhcp_client_stop(link->dhcp_client);
- if (k < 0) {
- log_link_warning(link, "Could not stop DHCPv4 client: %s",
- strerror(-r));
- r = k;
- }
+ if (k < 0)
+ r = log_link_warning_errno(link, r, "Could not stop DHCPv4 client: %m");
}
if (link->ipv4ll) {
k = sd_ipv4ll_stop(link->ipv4ll);
- if (k < 0) {
- log_link_warning(link, "Could not stop IPv4 link-local: %s",
- strerror(-r));
- r = k;
- }
+ if (k < 0)
+ r = log_link_warning_errno(link, r, "Could not stop IPv4 link-local: %m");
}
if(link->icmp6_router_discovery) {
-
if (link->dhcp6_client) {
k = sd_dhcp6_client_stop(link->dhcp6_client);
- if (k < 0) {
- log_link_warning(link, "Could not stop DHCPv6 client: %s",
- strerror(-r));
- r = k;
- }
+ if (k < 0)
+ r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m");
}
k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
- if (k < 0) {
- log_link_warning(link,
- "Could not stop ICMPv6 router discovery: %s",
- strerror(-r));
- r = k;
- }
+ if (k < 0)
+ r = log_link_warning_errno(link, r, "Could not stop ICMPv6 router discovery: %m");
}
if (link->lldp) {
-
k = sd_lldp_stop(link->lldp);
- if (k < 0) {
- log_link_warning(link, "Could not stop LLDP : %s",
- strerror(-r));
- r = k;
- }
+ if (k < 0)
+ r = log_link_warning_errno(link, r, "Could not stop LLDP: %m");
}
return r;
@@ -448,7 +424,7 @@ void link_enter_failed(Link *link) {
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
- log_link_warning(link, "failed");
+ log_link_warning(link, "Failed");
link_set_state(link, LINK_STATE_FAILED);
@@ -491,7 +467,7 @@ static int link_enter_configured(Link *link) {
assert(link->network);
assert(link->state == LINK_STATE_SETTING_ROUTES);
- log_link_info(link, "link configured");
+ log_link_info(link, "Configured");
link_set_state(link, LINK_STATE_CONFIGURED);
@@ -537,10 +513,10 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
- log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
+ log_link_warning_errno(link, r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
if (link->link_messages == 0) {
- log_link_debug(link, "routes set");
+ log_link_debug(link, "Routes set");
link->static_configured = true;
link_client_handler(link);
}
@@ -561,9 +537,7 @@ static int link_enter_set_routes(Link *link) {
LIST_FOREACH(routes, rt, link->network->static_routes) {
r = route_configure(rt, link, &route_handler);
if (r < 0) {
- log_link_warning(link,
- "could not set routes: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not set routes: %m");
link_enter_failed(link);
return r;
}
@@ -575,7 +549,7 @@ static int link_enter_set_routes(Link *link) {
link->static_configured = true;
link_client_handler(link);
} else
- log_link_debug(link, "setting routes");
+ log_link_debug(link, "Setting routes");
return 0;
}
@@ -593,7 +567,7 @@ int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ESRCH)
- log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
+ log_link_warning_errno(link, r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
return 1;
}
@@ -617,12 +591,12 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
- log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
+ log_link_warning_errno(link, r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
else if (r >= 0)
link_rtnl_process_address(rtnl, m, link->manager);
if (link->link_messages == 0) {
- log_link_debug(link, "addresses set");
+ log_link_debug(link, "Addresses set");
link_enter_set_routes(link);
}
@@ -658,8 +632,7 @@ static int link_enter_set_addresses(Link *link) {
address = link_find_dhcp_server_address(link);
if (!address) {
- log_link_warning(link,
- "Failed to find suitable address for DHCPv4 server instance.");
+ log_link_warning(link, "Failed to find suitable address for DHCPv4 server instance.");
link_enter_failed(link);
return 0;
}
@@ -691,21 +664,20 @@ static int link_enter_set_addresses(Link *link) {
r = sd_dhcp_server_start(link->dhcp_server);
if (r < 0) {
- log_link_warning(link, "could not start DHCPv4 server "
- "instance: %s", strerror(-r));
+ log_link_warning_errno(link, r, "Could not start DHCPv4 server instance: %m");
link_enter_failed(link);
return 0;
}
- log_link_debug(link, "offering DHCPv4 leases");
+ log_link_debug(link, "Offering DHCPv4 leases");
}
- if (link->link_messages == 0) {
+ if (link->link_messages == 0)
link_enter_set_routes(link);
- } else
- log_link_debug(link, "setting addresses");
+ else
+ log_link_debug(link, "Setting addresses");
return 0;
}
@@ -723,7 +695,7 @@ int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata)
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EADDRNOTAVAIL)
- log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
+ log_link_warning_errno(link, r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
return 1;
}
@@ -735,7 +707,7 @@ static int link_set_bridge_fdb(Link *const link) {
LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
r = fdb_entry_configure(link, fdb_entry);
if(r < 0) {
- log_link_error(link, "Failed to add MAC entry to static MAC table: %s", strerror(-r));
+ log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m");
break;
}
}
@@ -747,16 +719,11 @@ static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
- log_link_debug(link, "set link");
+ log_link_debug(link, "Set link");
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
- log_link_struct(link, LOG_ERR,
- "MESSAGE=%-*s: could not join netdev: %s",
- IFNAMSIZ,
- link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
+ log_link_error_errno(link, r, "Could not join netdev: %m");
link_enter_failed(link);
return 1;
}
@@ -764,11 +731,11 @@ static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
return 0;
}
-static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
- sd_bus_error *ret_error) {
+static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
_cleanup_link_unref_ Link *link = userdata;
int r;
+ assert(m);
assert(link);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
@@ -776,8 +743,7 @@ static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
r = sd_bus_message_get_errno(m);
if (r > 0)
- log_link_warning(link, "Could not set hostname: %s",
- strerror(r));
+ log_link_warning_errno(link, r, "Could not set hostname: %m");
return 1;
}
@@ -794,8 +760,7 @@ int link_set_hostname(Link *link, const char *hostname) {
if (!link->manager->bus) {
/* TODO: replace by assert when we can rely on kdbus */
- log_link_info(link,
- "Not connected to system bus, ignoring transient hostname.");
+ log_link_info(link, "Not connected to system bus, ignoring transient hostname.");
return 0;
}
@@ -815,11 +780,8 @@ int link_set_hostname(Link *link, const char *hostname) {
r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
link, 0);
- if (r < 0) {
- log_link_error(link, "Could not set transient hostname: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set transient hostname: %m");
link_ref(link);
@@ -839,7 +801,7 @@ static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
r = sd_rtnl_message_get_errno(m);
if (r < 0)
- log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
+ log_link_warning_errno(link, r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
return 1;
}
@@ -852,29 +814,19 @@ int link_set_mtu(Link *link, uint32_t mtu) {
assert(link->manager);
assert(link->manager->rtnl);
- log_link_debug(link, "setting MTU: %" PRIu32, mtu);
+ log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
- RTM_SETLINK, link->ifindex);
- if (r < 0) {
- log_link_error(link, "Could not allocate RTM_SETLINK message");
- return r;
- }
+ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
- if (r < 0) {
- log_link_error(link, "Could not append MTU: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append MTU: %m");
- r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
- 0, NULL);
- if (r < 0) {
- log_link_error(link,
- "Could not send rtnetlink message: %s",
- strerror(-r));
- return r;
- }
+ r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
@@ -891,53 +843,31 @@ static int link_set_bridge(Link *link) {
if(link->network->cost == 0)
return 0;
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
- RTM_SETLINK, link->ifindex);
- if (r < 0) {
- log_link_error(link, "Could not allocate RTM_SETLINK message");
- return r;
- }
+ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
- if (r < 0) {
- log_link_error(link,
- "Could not set message family %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set message family: %m");
r = sd_rtnl_message_open_container(req, IFLA_PROTINFO);
- if (r < 0) {
- log_link_error(link,
- "Could not append IFLA_PROTINFO attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
if(link->network->cost != 0) {
r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
- if (r < 0) {
- log_link_error(link,
- "Could not append IFLA_BRPORT_COST attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
}
r = sd_rtnl_message_close_container(req);
- if (r < 0) {
- log_link_error(link,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
- if (r < 0) {
- log_link_error(link,
- "Could not send rtnetlink message: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
@@ -957,7 +887,7 @@ static void lldp_handler(sd_lldp *lldp, int event, void *userdata) {
r = sd_lldp_save(link->lldp, link->lldp_file);
if (r < 0)
- log_link_warning(link, "could not save LLDP");
+ log_link_warning_errno(link, r, "Could not save LLDP: %m");
}
@@ -972,40 +902,31 @@ static int link_acquire_conf(Link *link) {
if (link_ipv4ll_enabled(link)) {
assert(link->ipv4ll);
- log_link_debug(link, "acquiring IPv4 link-local address");
+ log_link_debug(link, "Acquiring IPv4 link-local address");
r = sd_ipv4ll_start(link->ipv4ll);
- if (r < 0) {
- log_link_warning(link, "could not acquire IPv4 "
- "link-local address");
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
}
if (link_dhcp4_enabled(link)) {
assert(link->dhcp_client);
- log_link_debug(link, "acquiring DHCPv4 lease");
+ log_link_debug(link, "Acquiring DHCPv4 lease");
r = sd_dhcp_client_start(link->dhcp_client);
- if (r < 0) {
- log_link_warning(link, "could not acquire DHCPv4 "
- "lease");
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
}
if (link_dhcp6_enabled(link)) {
assert(link->icmp6_router_discovery);
- log_link_debug(link, "discovering IPv6 routers");
+ log_link_debug(link, "Discovering IPv6 routers");
r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
- if (r < 0) {
- log_link_warning(link,
- "could not start IPv6 router discovery");
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not start IPv6 router discovery: %m");
}
if (link_lldp_enabled(link)) {
@@ -1014,10 +935,8 @@ static int link_acquire_conf(Link *link) {
log_link_debug(link, "Starting LLDP");
r = sd_lldp_start(link->lldp);
- if (r < 0) {
- log_link_warning(link, "could not start LLDP ");
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not start LLDP: %m");
}
return 0;
@@ -1047,11 +966,10 @@ static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
return 1;
r = sd_rtnl_message_get_errno(m);
- if (r < 0) {
- /* we warn but don't fail the link, as it may
- be brought up later */
- log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
- }
+ if (r < 0)
+ /* we warn but don't fail the link, as it may be
+ brought up later */
+ log_link_warning_errno(link, r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
return 1;
}
@@ -1066,98 +984,370 @@ static int link_up(Link *link) {
assert(link->manager);
assert(link->manager->rtnl);
- log_link_debug(link, "bringing link up");
+ log_link_debug(link, "Bringing link up");
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
- RTM_SETLINK, link->ifindex);
- if (r < 0) {
- log_link_error(link, "Could not allocate RTM_SETLINK message");
- return r;
- }
+ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
- if (r < 0) {
- log_link_error(link, "Could not set link flags: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set link flags: %m");
if (link->network->mac) {
r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
- if (r < 0) {
- log_link_error(link, "Could not set MAC address: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set MAC address: %m");
}
if (link->network->mtu) {
r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu);
- if (r < 0) {
- log_link_error(link, "Could not set MTU: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set MTU: %m");
}
r = sd_rtnl_message_open_container(req, IFLA_AF_SPEC);
- if (r < 0) {
- log_link_error(link, "Could not open IFLA_AF_SPEC container: %s", strerror(-r));
- return r;
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
+
+ if (socket_ipv6_is_supported()) {
+ /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
+ r = sd_rtnl_message_open_container(req, AF_INET6);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
+
+ ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE;
+ r = sd_rtnl_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
+
+ if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
+ r = sd_rtnl_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_INET6_TOKEN: %m");
+ }
+
+ r = sd_rtnl_message_close_container(req);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
}
- r = sd_rtnl_message_open_container(req, AF_INET6);
- if (r < 0) {
- log_link_error(link, "Could not open AF_INET6 container: %s", strerror(-r));
- return r;
+ r = sd_rtnl_message_close_container(req);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
+
+ r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+
+ link_ref(link);
+
+ return 0;
+}
+
+static int link_down_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+ _cleanup_link_unref_ Link *link = userdata;
+ int r;
+
+ assert(link);
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 1;
+
+ r = sd_rtnl_message_get_errno(m);
+ if (r < 0)
+ log_link_warning_errno(link, r, "%-*s: could not bring down interface: %m", IFNAMSIZ, link->ifname);
+
+ return 1;
+}
+
+static int link_down(Link *link) {
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
+ int r;
+
+ assert(link);
+ assert(link->manager);
+ assert(link->manager->rtnl);
+
+ log_link_debug(link, "Bringing link down");
+
+ r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
+ RTM_SETLINK, link->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
+
+ r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set link flags: %m");
+
+ r = sd_rtnl_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+
+ link_ref(link);
+
+ return 0;
+}
+
+static int link_handle_bound_to_list(Link *link) {
+ Link *l;
+ Iterator i;
+ int r;
+ bool required_up = false;
+ bool link_is_up = false;
+
+ assert(link);
+
+ if (hashmap_isempty(link->bound_to_links))
+ return 0;
+
+ if (link->flags & IFF_UP)
+ link_is_up = true;
+
+ HASHMAP_FOREACH (l, link->bound_to_links, i)
+ if (link_has_carrier(l)) {
+ required_up = true;
+ break;
+ }
+
+ if (!required_up && link_is_up) {
+ r = link_down(link);
+ if (r < 0)
+ return r;
+ } else if (required_up && !link_is_up) {
+ r = link_up(link);
+ if (r < 0)
+ return r;
}
- ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE;
- r = sd_rtnl_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
- if (r < 0) {
- log_link_error(link, "Could not append IFLA_INET6_ADDR_GEN_MODE: %s", strerror(-r));
+ return 0;
+}
+
+static int link_handle_bound_by_list(Link *link) {
+ Iterator i;
+ Link *l;
+ int r;
+
+ assert(link);
+
+ if (hashmap_isempty(link->bound_by_links))
+ return 0;
+
+ HASHMAP_FOREACH (l, link->bound_by_links, i) {
+ r = link_handle_bound_to_list(l);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
+ int r;
+
+ assert(link);
+ assert(carrier);
+
+ if (link == carrier)
+ return 0;
+
+ if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
+ return 0;
+
+ r = hashmap_ensure_allocated(h, NULL);
+ if (r < 0)
+ return r;
+
+ r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
+ if (r < 0)
return r;
+
+ return 0;
+}
+
+static int link_new_bound_by_list(Link *link) {
+ Manager *m;
+ Link *carrier;
+ Iterator i;
+ int r;
+ bool list_updated = false;
+
+ assert(link);
+ assert(link->manager);
+
+ m = link->manager;
+
+ HASHMAP_FOREACH (carrier, m->links, i) {
+ if (!carrier->network)
+ continue;
+
+ if (strv_isempty(carrier->network->bind_carrier))
+ continue;
+
+ if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
+ r = link_put_carrier(link, carrier, &link->bound_by_links);
+ if (r < 0)
+ return r;
+
+ list_updated = true;
+ }
}
- if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
- r = sd_rtnl_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
- if (r < 0) {
- log_link_error(link, "Could not append IFLA_INET6_TOKEN: %s", strerror(-r));
+ if (list_updated)
+ link_save(link);
+
+ HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
+ r = link_put_carrier(carrier, link, &carrier->bound_to_links);
+ if (r < 0)
return r;
+
+ link_save(carrier);
+ }
+
+ return 0;
+}
+
+static int link_new_bound_to_list(Link *link) {
+ Manager *m;
+ Link *carrier;
+ Iterator i;
+ int r;
+ bool list_updated = false;
+
+ assert(link);
+ assert(link->manager);
+
+ if (!link->network)
+ return 0;
+
+ if (strv_isempty(link->network->bind_carrier))
+ return 0;
+
+ m = link->manager;
+
+ HASHMAP_FOREACH (carrier, m->links, i) {
+ if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
+ r = link_put_carrier(link, carrier, &link->bound_to_links);
+ if (r < 0)
+ return r;
+
+ list_updated = true;
}
}
- r = sd_rtnl_message_close_container(req);
- if (r < 0) {
- log_link_error(link, "Could not close AF_INET6 container: %s", strerror(-r));
- return r;
+ if (list_updated)
+ link_save(link);
+
+ HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
+ r = link_put_carrier(carrier, link, &carrier->bound_by_links);
+ if (r < 0)
+ return r;
+
+ link_save(carrier);
}
- r = sd_rtnl_message_close_container(req);
- if (r < 0) {
- log_link_error(link, "Could not close IFLA_AF_SPEC container: %s", strerror(-r));
+ return 0;
+}
+
+static int link_new_carrier_maps(Link *link) {
+ int r;
+
+ r = link_new_bound_by_list(link);
+ if (r < 0)
return r;
- }
- r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
- 0, NULL);
- if (r < 0) {
- log_link_error(link,
- "Could not send rtnetlink message: %s",
- strerror(-r));
+ r = link_handle_bound_by_list(link);
+ if (r < 0)
return r;
- }
- link_ref(link);
+ r = link_new_bound_to_list(link);
+ if (r < 0)
+ return r;
+
+ r = link_handle_bound_to_list(link);
+ if (r < 0)
+ return r;
return 0;
}
+static void link_free_bound_to_list(Link *link) {
+ Link *bound_to;
+ Iterator i;
+
+ HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
+ hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
+
+ if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
+ link_save(bound_to);
+ }
+
+ return;
+}
+
+static void link_free_bound_by_list(Link *link) {
+ Link *bound_by;
+ Iterator i;
+
+ HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
+ hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
+
+ if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
+ link_save(bound_by);
+ link_handle_bound_to_list(bound_by);
+ }
+ }
+
+ return;
+}
+
+static void link_free_carrier_maps(Link *link) {
+ bool list_updated = false;
+
+ assert(link);
+
+ if (!hashmap_isempty(link->bound_to_links)) {
+ link_free_bound_to_list(link);
+ list_updated = true;
+ }
+
+ if (!hashmap_isempty(link->bound_by_links)) {
+ link_free_bound_by_list(link);
+ list_updated = true;
+ }
+
+ if (list_updated)
+ link_save(link);
+
+ return;
+}
+
+void link_drop(Link *link) {
+ if (!link || link->state == LINK_STATE_LINGER)
+ return;
+
+ link_set_state(link, LINK_STATE_LINGER);
+
+ link_free_carrier_maps(link);
+
+ log_link_debug(link, "Link removed");
+
+ link_unref(link);
+
+ return;
+}
+
static int link_joined(Link *link) {
int r;
assert(link);
assert(link->network);
- if (!(link->flags & IFF_UP)) {
+ if (!hashmap_isempty(link->bound_to_links)) {
+ r = link_handle_bound_to_list(link);
+ if (r < 0)
+ return r;
+ } else if (!(link->flags & IFF_UP)) {
r = link_up(link);
if (r < 0) {
link_enter_failed(link);
@@ -1167,11 +1357,8 @@ static int link_joined(Link *link) {
if(link->network->bridge) {
r = link_set_bridge(link);
- if (r < 0) {
- log_link_error(link,
- "Could not set bridge message: %s",
- strerror(-r));
- }
+ if (r < 0)
+ log_link_error_errno(link, r, "Could not set bridge message: %m");
}
return link_enter_set_addresses(link);
@@ -1192,11 +1379,11 @@ static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
- log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
+ log_link_error_errno(link, r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
link_enter_failed(link);
return 1;
} else
- log_link_debug(link, "joined netdev");
+ log_link_debug(link, "Joined netdev");
if (link->enslaving <= 0)
link_joined(link);
@@ -1223,22 +1410,20 @@ static int link_enter_join_netdev(Link *link) {
return link_joined(link);
if (link->network->bond) {
- log_link_struct(link, LOG_DEBUG,
- "MESSAGE=%-*s: enslaving by '%s'",
- IFNAMSIZ,
- link->ifname, link->network->bond->ifname,
- NETDEVIF(link->network->bond),
- NULL);
-
- r = netdev_join(link->network->bond, link, &netdev_join_handler);
+ log_struct(LOG_DEBUG,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(link->network->bond),
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname),
+ NULL);
+
+ r = netdev_join(link->network->bond, link, netdev_join_handler);
if (r < 0) {
- log_link_struct(link, LOG_WARNING,
- "MESSAGE=%-*s: could not join netdev '%s': %s",
- IFNAMSIZ,
- link->ifname, link->network->bond->ifname,
- strerror(-r),
- NETDEVIF(link->network->bond),
- NULL);
+ log_struct_errno(LOG_WARNING, r,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(link->network->bond),
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname),
+ NULL);
+
link_enter_failed(link);
return r;
}
@@ -1247,23 +1432,19 @@ static int link_enter_join_netdev(Link *link) {
}
if (link->network->bridge) {
- log_link_struct(link, LOG_DEBUG,
- "MESSAGE=%-*s: enslaving by '%s'",
- IFNAMSIZ,
- link->ifname, link->network->bridge->ifname,
- NETDEVIF(link->network->bridge),
- NULL);
-
- r = netdev_join(link->network->bridge, link,
- &netdev_join_handler);
+ log_struct(LOG_DEBUG,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(link->network->bridge),
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname),
+ NULL);
+
+ r = netdev_join(link->network->bridge, link, netdev_join_handler);
if (r < 0) {
- log_link_struct(link, LOG_WARNING,
- "MESSAGE=%-*s: could not join netdev '%s': %s",
- IFNAMSIZ,
- link->ifname, link->network->bridge->ifname,
- strerror(-r),
- NETDEVIF(link->network->bridge),
- NULL);
+ log_struct_errno(LOG_WARNING, r,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(link->network->bridge),
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname),
+ NULL),
link_enter_failed(link);
return r;
}
@@ -1272,20 +1453,20 @@ static int link_enter_join_netdev(Link *link) {
}
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
- log_link_struct(link, LOG_DEBUG,
- "MESSAGE=%-*s: enslaving by '%s'",
- IFNAMSIZ,
- link->ifname, netdev->ifname, NETDEVIF(netdev),
- NULL);
- r = netdev_join(netdev, link, &netdev_join_handler);
+ log_struct(LOG_DEBUG,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(netdev),
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname),
+ NULL);
+
+ r = netdev_join(netdev, link, netdev_join_handler);
if (r < 0) {
- log_link_struct(link, LOG_WARNING,
- "MESSAGE=%-*s: could not join netdev '%s': %s",
- IFNAMSIZ,
- link->ifname, netdev->ifname,
- strerror(-r),
- NETDEVIF(netdev), NULL);
+ log_struct_errno(LOG_WARNING, r,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(netdev),
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname),
+ NULL);
link_enter_failed(link);
return r;
}
@@ -1298,39 +1479,16 @@ static int link_enter_join_netdev(Link *link) {
static int link_set_ipv4_forward(Link *link) {
const char *p = NULL;
- bool b;
int r;
- b = link_ipv4_forward_enabled(link);
+ if (link->network->ip_forward == ADDRESS_FAMILY_KERNEL)
+ return 0;
p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
- r = write_string_file_no_create(p, one_zero(b));
+ r = write_string_file_no_create(p, one_zero(link_ipv4_forward_enabled(link)));
if (r < 0)
log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
- if (b) {
- _cleanup_free_ char *buf = NULL;
-
- /* If IP forwarding is turned on for this interface,
- * then propagate this to the global setting. Given
- * that turning this on has side-effects on other
- * fields, we'll try to avoid doing this unless
- * necessary, hence check the previous value
- * first. Note that we never turn this option off
- * again, since all interfaces we manage do not do
- * forwarding anyway by default, and ownership rules
- * of this control are so unclear. */
-
- r = read_one_line_file("/proc/sys/net/ipv4/ip_forward", &buf);
- if (r < 0)
- log_link_warning_errno(link, r, "Cannot read /proc/sys/net/ipv4/ip_forward: %m");
- else if (!streq(buf, "1")) {
- r = write_string_file_no_create("/proc/sys/net/ipv4/ip_forward", "1");
- if (r < 0)
- log_link_warning_errno(link, r, "Cannot write /proc/sys/net/ipv4/ip_forward: %m");
- }
- }
-
return 0;
}
@@ -1338,6 +1496,13 @@ static int link_set_ipv6_forward(Link *link) {
const char *p = NULL;
int r;
+ /* Make this a NOP if IPv6 is not available */
+ if (!socket_ipv6_is_supported())
+ return 0;
+
+ if (link->network->ip_forward == ADDRESS_FAMILY_KERNEL)
+ return 0;
+
p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link)));
if (r < 0)
@@ -1430,7 +1595,15 @@ static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
if (link->state != LINK_STATE_PENDING)
return 1;
- log_link_debug(link, "link state is up-to-date");
+ log_link_debug(link, "Link state is up-to-date");
+
+ r = link_new_bound_by_list(link);
+ if (r < 0)
+ return r;
+
+ r = link_handle_bound_by_list(link);
+ if (r < 0)
+ return r;
r = network_get(link->manager, link->udev_device, link->ifname,
&link->mac, &network);
@@ -1442,19 +1615,23 @@ static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
if (link->flags & IFF_LOOPBACK) {
if (network->link_local != ADDRESS_FAMILY_NO)
- log_link_debug(link, "ignoring link-local autoconfiguration for loopback link");
+ log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
if (network->dhcp != ADDRESS_FAMILY_NO)
- log_link_debug(link, "ignoring DHCP clients for loopback link");
+ log_link_debug(link, "Ignoring DHCP clients for loopback link");
if (network->dhcp_server)
- log_link_debug(link, "ignoring DHCP server for loopback link");
+ log_link_debug(link, "Ignoring DHCP server for loopback link");
}
r = network_apply(link->manager, network, link);
if (r < 0)
return r;
+ r = link_new_bound_to_list(link);
+ if (r < 0)
+ return r;
+
r = link_configure(link);
if (r < 0)
return r;
@@ -1519,6 +1696,7 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
Link *link = NULL;
uint16_t type;
_cleanup_address_free_ Address *address = NULL;
+ unsigned char flags;
Address *existing;
char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
const char *valid_str = NULL;
@@ -1538,13 +1716,16 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
r = sd_rtnl_message_get_type(message, &type);
if (r < 0) {
- log_warning("rtnl: could not get message type");
+ log_warning_errno(r, "rtnl: could not get message type: %m");
+ return 0;
+ } else if (type != RTM_NEWADDR && type != RTM_DELADDR) {
+ log_warning("rtnl: received unexpected message type when processing address");
return 0;
}
r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
if (r < 0) {
- log_warning_errno(r, "rtnl: could not get ifindex: %m");
+ log_warning_errno(r, "rtnl: could not get ifindex from address: %m");
return 0;
} else if (ifindex <= 0) {
log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
@@ -1566,33 +1747,34 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
r = sd_rtnl_message_addr_get_family(message, &address->family);
if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
- log_link_warning(link, "rtnl: received address with invalid family, ignoring");
+ log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
return 0;
}
r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
if (r < 0) {
- log_link_warning(link, "rtnl: received address with invalid prefixlen, ignoring");
+ log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m");
return 0;
}
r = sd_rtnl_message_addr_get_scope(message, &address->scope);
if (r < 0) {
- log_link_warning(link, "rtnl: received address with invalid scope, ignoring");
+ log_link_warning_errno(link, r, "rtnl: received address with invalid scope, ignoring: %m");
return 0;
}
- r = sd_rtnl_message_addr_get_flags(message, &address->flags);
+ r = sd_rtnl_message_addr_get_flags(message, &flags);
if (r < 0) {
- log_link_warning(link, "rtnl: received address with invalid flags, ignoring");
+ log_link_warning_errno(link, r, "rtnl: received address with invalid flags, ignoring: %m");
return 0;
}
+ address->flags = flags;
switch (address->family) {
case AF_INET:
r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
if (r < 0) {
- log_link_warning(link, "rtnl: received address without valid address, ignoring");
+ log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
return 0;
}
@@ -1601,7 +1783,7 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
case AF_INET6:
r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
if (r < 0) {
- log_link_warning(link, "rtnl: received address without valid address, ignoring");
+ log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
return 0;
}
@@ -1612,7 +1794,7 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
}
if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
- log_link_warning(link, "could not print address");
+ log_link_warning(link, "Could not print address");
return 0;
}
@@ -1686,17 +1868,14 @@ int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
link = *ret;
- log_link_debug(link, "link %d added", link->ifindex);
+ log_link_debug(link, "Link %d added", link->ifindex);
if (detect_container(NULL) <= 0) {
/* not in a container, udev will be around */
sprintf(ifindex_str, "n%d", link->ifindex);
device = udev_device_new_from_device_id(m->udev, ifindex_str);
- if (!device) {
- log_link_warning(link,
- "could not find udev device: %m");
- return -errno;
- }
+ if (!device)
+ return log_link_warning_errno(link, errno, "Could not find udev device: %m");
if (udev_device_get_is_initialized(device) <= 0) {
/* not yet ready */
@@ -1732,6 +1911,10 @@ static int link_carrier_gained(Link *link) {
}
}
+ r = link_handle_bound_by_list(link);
+ if (r < 0)
+ return r;
+
return 0;
}
@@ -1746,6 +1929,10 @@ static int link_carrier_lost(Link *link) {
return r;
}
+ r = link_handle_bound_by_list(link);
+ if (r < 0)
+ return r;
+
return 0;
}
@@ -1763,7 +1950,7 @@ int link_carrier_reset(Link *link) {
if (r < 0)
return r;
- log_link_info(link, "reset carrier");
+ log_link_info(link, "Reset carrier");
}
return 0;
@@ -1783,18 +1970,28 @@ int link_update(Link *link, sd_rtnl_message *m) {
if (link->state == LINK_STATE_LINGER) {
link_ref(link);
- log_link_info(link, "link readded");
+ log_link_info(link, "Link readded");
link_set_state(link, LINK_STATE_ENSLAVING);
+
+ r = link_new_carrier_maps(link);
+ if (r < 0)
+ return r;
}
r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
if (r >= 0 && !streq(ifname, link->ifname)) {
- log_link_info(link, "renamed to %s", ifname);
+ log_link_info(link, "Renamed to %s", ifname);
+
+ link_free_carrier_maps(link);
free(link->ifname);
link->ifname = strdup(ifname);
if (!link->ifname)
return -ENOMEM;
+
+ r = link_new_carrier_maps(link);
+ if (r < 0)
+ return r;
}
r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
@@ -1802,17 +1999,14 @@ int link_update(Link *link, sd_rtnl_message *m) {
link->mtu = mtu;
if (!link->original_mtu) {
link->original_mtu = mtu;
- log_link_debug(link, "saved original MTU: %"
- PRIu32, link->original_mtu);
+ log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
}
if (link->dhcp_client) {
r = sd_dhcp_client_set_mtu(link->dhcp_client,
link->mtu);
if (r < 0) {
- log_link_warning(link,
- "Could not update MTU in DHCP client: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
return r;
}
}
@@ -1839,12 +2033,8 @@ int link_update(Link *link, sd_rtnl_message *m) {
if (link->ipv4ll) {
r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
- if (r < 0) {
- log_link_warning(link,
- "Could not update MAC address in IPv4LL client: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
}
if (link->dhcp_client) {
@@ -1852,12 +2042,8 @@ int link_update(Link *link, sd_rtnl_message *m) {
(const uint8_t *) &link->mac,
sizeof (link->mac),
ARPHRD_ETHER);
- if (r < 0) {
- log_link_warning(link,
- "Could not update MAC address in DHCP client: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
}
if (link->dhcp6_client) {
@@ -1865,12 +2051,8 @@ int link_update(Link *link, sd_rtnl_message *m) {
(const uint8_t *) &link->mac,
sizeof (link->mac),
ARPHRD_ETHER);
- if (r < 0) {
- log_link_warning(link,
- "Could not update MAC address in DHCPv6 client: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
}
}
}
@@ -1885,13 +2067,13 @@ int link_update(Link *link, sd_rtnl_message *m) {
carrier_lost = had_carrier && !link_has_carrier(link);
if (carrier_gained) {
- log_link_info(link, "gained carrier");
+ log_link_info(link, "Gained carrier");
r = link_carrier_gained(link);
if (r < 0)
return r;
} else if (carrier_lost) {
- log_link_info(link, "lost carrier");
+ log_link_info(link, "Lost carrier");
r = link_carrier_lost(link);
if (r < 0)
@@ -1971,7 +2153,7 @@ int link_save(Link *link) {
r = fopen_temporary(link->state_file, &f, &temp_path);
if (r < 0)
- return r;
+ goto fail;
fchmod(fileno(f), 0644);
@@ -2063,6 +2245,38 @@ int link_save(Link *link) {
llmnr_support_to_string(link->network->llmnr));
}
+ if (!hashmap_isempty(link->bound_to_links)) {
+ Link *carrier;
+ Iterator i;
+ bool space = false;
+
+ fputs("CARRIER_BOUND_TO=", f);
+ HASHMAP_FOREACH(carrier, link->bound_to_links, i) {
+ if (space)
+ fputc(' ', f);
+ fputs(carrier->ifname, f);
+ space = true;
+ }
+
+ fputs("\n", f);
+ }
+
+ if (!hashmap_isempty(link->bound_by_links)) {
+ Link *carrier;
+ Iterator i;
+ bool space = false;
+
+ fputs("CARRIER_BOUND_BY=", f);
+ HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
+ if (space)
+ fputc(' ', f);
+ fputs(carrier->ifname, f);
+ space = true;
+ }
+
+ fputs("\n", f);
+ }
+
if (link->dhcp_lease) {
assert(link->network);
@@ -2100,9 +2314,12 @@ int link_save(Link *link) {
return 0;
fail:
- log_link_error(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
- unlink(link->state_file);
- unlink(temp_path);
+ log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
+ (void) unlink(link->state_file);
+
+ if (temp_path)
+ (void) unlink(temp_path);
+
return r;
}
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index cec158e47d..c599952c45 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -82,9 +82,13 @@ struct Link {
sd_icmp6_nd *icmp6_router_discovery;
sd_dhcp6_client *dhcp6_client;
+ bool rtnl_extended_attrs;
sd_lldp *lldp;
char *lldp_file;
+
+ Hashmap *bound_by_links;
+ Hashmap *bound_to_links;
};
Link *link_unref(Link *link);
@@ -137,14 +141,18 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
/* Macros which append INTERFACE= to the message */
-#define log_link_full(link, level, error, fmt, ...) \
- log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
+#define log_link_full(link, level, error, ...) \
+ ({ \
+ Link *_l = (link); \
+ _l ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _l->ifname, ##__VA_ARGS__) : \
+ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
+ }) \
-#define log_link_debug(link, ...) log_link_full(link, LOG_DEBUG, 0, ##__VA_ARGS__)
-#define log_link_info(link, ...) log_link_full(link, LOG_INFO, 0, ##__VA_ARGS__)
-#define log_link_notice(link, ...) log_link_full(link, LOG_NOTICE, 0, ##__VA_ARGS__)
-#define log_link_warning(link, ...) log_link_full(link, LOG_WARNING, 0, ##__VA_ARGS__)
-#define log_link_error(link, ...) log_link_full(link, LOG_ERR, 0, ##__VA_ARGS__)
+#define log_link_debug(link, ...) log_link_full(link, LOG_DEBUG, 0, ##__VA_ARGS__)
+#define log_link_info(link, ...) log_link_full(link, LOG_INFO, 0, ##__VA_ARGS__)
+#define log_link_notice(link, ...) log_link_full(link, LOG_NOTICE, 0, ##__VA_ARGS__)
+#define log_link_warning(link, ...) log_link_full(link, LOG_WARNING, 0, ##__VA_ARGS__)
+#define log_link_error(link, ...) log_link_full(link, LOG_ERR, 0, ##__VA_ARGS__)
#define log_link_debug_errno(link, error, ...) log_link_full(link, LOG_DEBUG, error, ##__VA_ARGS__)
#define log_link_info_errno(link, error, ...) log_link_full(link, LOG_INFO, error, ##__VA_ARGS__)
@@ -152,7 +160,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
#define log_link_warning_errno(link, error, ...) log_link_full(link, LOG_WARNING, error, ##__VA_ARGS__)
#define log_link_error_errno(link, error, ...) log_link_full(link, LOG_ERR, error, ##__VA_ARGS__)
-#define log_link_struct(link, level, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__)
+#define LOG_LINK_MESSAGE(link, fmt, ...) "MESSAGE=%s: " fmt, (link)->ifname, ##__VA_ARGS__
+#define LOG_LINK_INTERFACE(link) "INTERFACE=%s", (link)->ifname
#define ADDRESS_FMT_VAL(address) \
be32toh((address).s_addr) >> 24, \
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index ce97ac0778..2cc53df4b1 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -27,13 +27,11 @@
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-link.h"
-#include "network-internal.h"
#include "libudev-private.h"
#include "udev-util.h"
#include "rtnl-util.h"
#include "bus-util.h"
#include "def.h"
-#include "mkdir.h"
#include "virt.h"
#include "sd-rtnl.h"
@@ -107,12 +105,11 @@ static int manager_reset_all(Manager *m) {
return 0;
}
-static int match_prepare_for_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
+static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
Manager *m = userdata;
int b, r;
- assert(bus);
- assert(bus);
+ assert(message);
r = sd_bus_message_read(message, "b", &b);
if (r < 0) {
@@ -301,11 +298,14 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
if (r < 0) {
log_warning_errno(r, "rtnl: could not get message type: %m");
return 0;
+ } else if (type != RTM_NEWLINK && type != RTM_DELLINK) {
+ log_warning("rtnl: received unexpected message type when processing link");
+ return 0;
}
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
if (r < 0) {
- log_warning_errno(r, "rtnl: could not get ifindex: %m");
+ log_warning_errno(r, "rtnl: could not get ifindex from link: %m");
return 0;
} else if (ifindex <= 0) {
log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
@@ -853,6 +853,8 @@ const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
return "ipv4";
if (b == ADDRESS_FAMILY_IPV6)
return "ipv6";
+ if (b == ADDRESS_FAMILY_KERNEL)
+ return "kernel";
return NULL;
}
@@ -872,6 +874,8 @@ AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
return ADDRESS_FAMILY_IPV4;
if (streq(s, "ipv6"))
return ADDRESS_FAMILY_IPV6;
+ if (streq(s, "kernel"))
+ return ADDRESS_FAMILY_KERNEL;
return _ADDRESS_FAMILY_BOOLEAN_INVALID;
}
diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c
index 88321ef84c..70df08a5e1 100644
--- a/src/network/networkd-netdev-bond.c
+++ b/src/network/networkd-netdev-bond.c
@@ -21,14 +21,45 @@
***/
#include <netinet/ether.h>
-#include <arpa/inet.h>
#include <linux/if_bonding.h>
#include "conf-parser.h"
#include "sd-rtnl.h"
+#include "rtnl-types.h"
#include "networkd-netdev-bond.h"
#include "missing.h"
+/*
+ * Number of seconds between instances where the bonding
+ * driver sends learning packets to each slaves peer switch
+ */
+#define LEARNING_PACKETS_INTERVAL_MIN_SEC (1 * USEC_PER_SEC)
+#define LEARNING_PACKETS_INTERVAL_MAX_SEC (0x7fffffff * USEC_PER_SEC)
+
+/* Number of IGMP membership reports to be issued after
+ * a failover event.
+ */
+#define RESEND_IGMP_MIN 0
+#define RESEND_IGMP_MAX 255
+#define RESEND_IGMP_DEFAULT 1
+
+/*
+ * Number of packets to transmit through a slave before
+ * moving to the next one.
+ */
+#define PACKETS_PER_SLAVE_MIN 0
+#define PACKETS_PER_SLAVE_MAX 65535
+#define PACKETS_PER_SLAVE_DEFAULT 1
+
+/*
+ * Number of peer notifications (gratuitous ARPs and
+ * unsolicited IPv6 Neighbor Advertisements) to be issued after a
+ * failover event.
+ */
+#define GRATUITOUS_ARP_MIN 0
+#define GRATUITOUS_ARP_MAX 255
+#define GRATUITOUS_ARP_DEFAULT 1
+
static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
[NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr",
[NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup",
@@ -42,7 +73,6 @@ static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode");
-
static const char* const bond_xmit_hash_policy_table[_NETDEV_BOND_XMIT_HASH_POLICY_MAX] = {
[NETDEV_BOND_XMIT_HASH_POLICY_LAYER2] = "layer2",
[NETDEV_BOND_XMIT_HASH_POLICY_LAYER34] = "layer3+4",
@@ -65,6 +95,51 @@ static const char* const bond_lacp_rate_table[_NETDEV_BOND_LACP_RATE_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate);
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_lacp_rate, bond_lacp_rate, BondLacpRate, "Failed to parse bond lacp rate")
+static const char* const bond_ad_select_table[_NETDEV_BOND_AD_SELECT_MAX] = {
+ [NETDEV_BOND_AD_SELECT_STABLE] = "stable",
+ [NETDEV_BOND_AD_SELECT_BANDWIDTH] = "bandwidth",
+ [NETDEV_BOND_AD_SELECT_COUNT] = "count",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_ad_select, BondAdSelect);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_ad_select, bond_ad_select, BondAdSelect, "Failed to parse bond AD select");
+
+static const char* const bond_fail_over_mac_table[_NETDEV_BOND_FAIL_OVER_MAC_MAX] = {
+ [NETDEV_BOND_FAIL_OVER_MAC_NONE] = "none",
+ [NETDEV_BOND_FAIL_OVER_MAC_ACTIVE] = "active",
+ [NETDEV_BOND_FAIL_OVER_MAC_FOLLOW] = "follow",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_fail_over_mac, BondFailOverMac);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_fail_over_mac, bond_fail_over_mac, BondFailOverMac, "Failed to parse bond fail over MAC");
+
+static const char *const bond_arp_validate_table[_NETDEV_BOND_ARP_VALIDATE_MAX] = {
+ [NETDEV_BOND_ARP_VALIDATE_NONE] = "none",
+ [NETDEV_BOND_ARP_VALIDATE_ACTIVE]= "active",
+ [NETDEV_BOND_ARP_VALIDATE_BACKUP]= "backup",
+ [NETDEV_BOND_ARP_VALIDATE_ALL]= "all",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_arp_validate, BondArpValidate);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_validate, bond_arp_validate, BondArpValidate, "Failed to parse bond arp validate");
+
+static const char *const bond_arp_all_targets_table[_NETDEV_BOND_ARP_ALL_TARGETS_MAX] = {
+ [NETDEV_BOND_ARP_ALL_TARGETS_ANY] = "any",
+ [NETDEV_BOND_ARP_ALL_TARGETS_ALL] = "all",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_arp_all_targets, BondArpAllTargets);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_all_targets, bond_arp_all_targets, BondArpAllTargets, "Failed to parse bond Arp all targets");
+
+static const char *bond_primary_reselect_table[_NETDEV_BOND_PRIMARY_RESELECT_MAX] = {
+ [NETDEV_BOND_PRIMARY_RESELECT_ALWAYS] = "always",
+ [NETDEV_BOND_PRIMARY_RESELECT_BETTER]= "better",
+ [NETDEV_BOND_PRIMARY_RESELECT_FAILURE]= "failure",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_primary_reselect, BondPrimaryReselect);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect");
+
static uint8_t bond_mode_to_kernel(BondMode mode) {
switch (mode) {
case NETDEV_BOND_MODE_BALANCE_RR:
@@ -105,7 +180,8 @@ static uint8_t bond_xmit_hash_policy_to_kernel(BondXmitHashPolicy policy) {
static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
Bond *b = BOND(netdev);
- int r;
+ ArpIpTarget *target = NULL;
+ int r, i = 0;
assert(netdev);
assert(!link);
@@ -175,9 +251,230 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
}
}
+ if (b->arp_interval != 0) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_ARP_INTERVAL, b->arp_interval / USEC_PER_MSEC);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_ARP_INTERVAL attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if ((b->lp_interval >= LEARNING_PACKETS_INTERVAL_MIN_SEC) &&
+ (b->lp_interval <= LEARNING_PACKETS_INTERVAL_MAX_SEC)) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_LP_INTERVAL, b->lp_interval / USEC_PER_SEC);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_LP_INTERVAL attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->ad_select != _NETDEV_BOND_AD_SELECT_INVALID &&
+ b->mode == BOND_MODE_8023AD) {
+ r = sd_rtnl_message_append_u8(m, IFLA_BOND_AD_SELECT, b->ad_select);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_AD_SELECT attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->fail_over_mac != _NETDEV_BOND_FAIL_OVER_MAC_INVALID &&
+ b->mode == NETDEV_BOND_MODE_ACTIVE_BACKUP) {
+ r = sd_rtnl_message_append_u8(m, IFLA_BOND_FAIL_OVER_MAC, b->fail_over_mac);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_FAIL_OVER_MAC attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->arp_validate != _NETDEV_BOND_ARP_VALIDATE_INVALID) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_ARP_VALIDATE, b->arp_validate);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_ARP_VALIDATE attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->arp_all_targets != _NETDEV_BOND_ARP_ALL_TARGETS_INVALID) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->arp_all_targets);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_ARP_VALIDATE attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->primary_reselect != _NETDEV_BOND_PRIMARY_RESELECT_INVALID) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->primary_reselect);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->resend_igmp <= RESEND_IGMP_MAX) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_RESEND_IGMP, b->resend_igmp);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_RESEND_IGMP attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->packets_per_slave <= PACKETS_PER_SLAVE_MAX) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_PACKETS_PER_SLAVE, b->packets_per_slave);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_PACKETS_PER_SLAVE attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->num_grat_arp <= GRATUITOUS_ARP_MAX) {
+ r = sd_rtnl_message_append_u8(m, IFLA_BOND_NUM_PEER_NOTIF, b->num_grat_arp);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_NUM_PEER_NOTIF attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (b->min_links != 0) {
+ r = sd_rtnl_message_append_u32(m, IFLA_BOND_MIN_LINKS, b->min_links);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_MIN_LINKS attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ r = sd_rtnl_message_append_u8(m, IFLA_BOND_ALL_SLAVES_ACTIVE, b->all_slaves_active);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+ if (b->arp_interval > 0) {
+ if (b->n_arp_ip_targets > 0) {
+
+ r = sd_rtnl_message_open_container(m, IFLA_BOND_ARP_IP_TARGET);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not open contaniner IFLA_BOND_ARP_IP_TARGET : %s",
+ strerror(-r));
+ return r;
+ }
+
+ LIST_FOREACH(arp_ip_target, target, b->arp_ip_targets) {
+ r = sd_rtnl_message_append_u32(m, i++, target->ip.in.s_addr);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ r = sd_rtnl_message_close_container(m);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not close contaniner IFLA_BOND_ARP_IP_TARGET : %s",
+ strerror(-r));
+ return r;
+ }
+ }
+ }
+
return 0;
}
+int config_parse_arp_ip_target_address(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) {
+ Bond *b = userdata;
+ const char *word, *state;
+ size_t l;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+ _cleanup_free_ ArpIpTarget *buffer = NULL;
+ _cleanup_free_ char *n = NULL;
+ int f;
+
+ n = strndup(word, l);
+ if (!n)
+ return -ENOMEM;
+
+ buffer = new0(ArpIpTarget, 1);
+ if (!buffer)
+ return -ENOMEM;
+
+ r = in_addr_from_string_auto(n, &f, &buffer->ip);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
+ return 0;
+ }
+
+ if (f != AF_INET) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
+ return 0;
+ }
+
+ LIST_PREPEND(arp_ip_target, b->arp_ip_targets, buffer);
+ b->n_arp_ip_targets ++;
+
+ buffer = NULL;
+
+ if (b->n_arp_ip_targets > BOND_ARP_TARGETS_MAX)
+ break;
+ }
+
+ return 0;
+}
+
+static void bond_done(NetDev *netdev) {
+ ArpIpTarget *t = NULL, *n = NULL;
+ Bond *b = BOND(netdev);
+
+ assert(netdev);
+ assert(b);
+
+ LIST_FOREACH_SAFE(arp_ip_target, t, n, b->arp_ip_targets)
+ free(t);
+
+ b->arp_ip_targets = NULL;
+}
+
static void bond_init(NetDev *netdev) {
Bond *b = BOND(netdev);
@@ -187,11 +484,27 @@ static void bond_init(NetDev *netdev) {
b->mode = _NETDEV_BOND_MODE_INVALID;
b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
+ b->ad_select = _NETDEV_BOND_AD_SELECT_INVALID;
+ b->fail_over_mac = _NETDEV_BOND_FAIL_OVER_MAC_INVALID;
+ b->arp_validate = _NETDEV_BOND_ARP_VALIDATE_INVALID;
+ b->arp_all_targets = _NETDEV_BOND_ARP_ALL_TARGETS_INVALID;
+ b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID;
+
+ b->all_slaves_active = false;
+
+ b->resend_igmp = RESEND_IGMP_DEFAULT;
+ b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT;
+ b->num_grat_arp = GRATUITOUS_ARP_DEFAULT;
+ b->lp_interval = LEARNING_PACKETS_INTERVAL_MIN_SEC;
+
+ LIST_HEAD_INIT(b->arp_ip_targets);
+ b->n_arp_ip_targets = 0;
}
const NetDevVTable bond_vtable = {
.object_size = sizeof(Bond),
.init = bond_init,
+ .done = bond_done,
.sections = "Match\0NetDev\0Bond\0",
.fill_message_create = netdev_bond_fill_message_create,
.create_type = NETDEV_CREATE_MASTER,
diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h
index c09af5fa52..32d1702d58 100644
--- a/src/network/networkd-netdev-bond.h
+++ b/src/network/networkd-netdev-bond.h
@@ -47,7 +47,6 @@ typedef enum BondXmitHashPolicy {
_NETDEV_BOND_XMIT_HASH_POLICY_INVALID = -1
} BondXmitHashPolicy;
-
typedef enum BondLacpRate {
NETDEV_BOND_LACP_RATE_SLOW,
NETDEV_BOND_LACP_RATE_FAST,
@@ -55,16 +54,79 @@ typedef enum BondLacpRate {
_NETDEV_BOND_LACP_RATE_INVALID = -1,
} BondLacpRate;
+typedef enum BondAdSelect {
+ NETDEV_BOND_AD_SELECT_STABLE,
+ NETDEV_BOND_AD_SELECT_BANDWIDTH,
+ NETDEV_BOND_AD_SELECT_COUNT,
+ _NETDEV_BOND_AD_SELECT_MAX,
+ _NETDEV_BOND_AD_SELECT_INVALID = -1,
+} BondAdSelect;
+
+typedef enum BondFailOverMac {
+ NETDEV_BOND_FAIL_OVER_MAC_NONE,
+ NETDEV_BOND_FAIL_OVER_MAC_ACTIVE,
+ NETDEV_BOND_FAIL_OVER_MAC_FOLLOW,
+ _NETDEV_BOND_FAIL_OVER_MAC_MAX,
+ _NETDEV_BOND_FAIL_OVER_MAC_INVALID = -1,
+} BondFailOverMac;
+
+typedef enum BondArpValidate {
+ NETDEV_BOND_ARP_VALIDATE_NONE,
+ NETDEV_BOND_ARP_VALIDATE_ACTIVE,
+ NETDEV_BOND_ARP_VALIDATE_BACKUP,
+ NETDEV_BOND_ARP_VALIDATE_ALL,
+ _NETDEV_BOND_ARP_VALIDATE_MAX,
+ _NETDEV_BOND_ARP_VALIDATE_INVALID = -1,
+} BondArpValidate;
+
+typedef enum BondArpAllTargets {
+ NETDEV_BOND_ARP_ALL_TARGETS_ANY,
+ NETDEV_BOND_ARP_ALL_TARGETS_ALL,
+ _NETDEV_BOND_ARP_ALL_TARGETS_MAX,
+ _NETDEV_BOND_ARP_ALL_TARGETS_INVALID = -1,
+} BondArpAllTargets;
+
+typedef enum BondPrimaryReselect {
+ NETDEV_BOND_PRIMARY_RESELECT_ALWAYS,
+ NETDEV_BOND_PRIMARY_RESELECT_BETTER,
+ NETDEV_BOND_PRIMARY_RESELECT_FAILURE,
+ _NETDEV_BOND_PRIMARY_RESELECT_MAX,
+ _NETDEV_BOND_PRIMARY_RESELECT_INVALID = -1,
+} BondPrimaryReselect;
+
+typedef struct ArpIpTarget {
+ union in_addr_union ip;
+
+ LIST_FIELDS(struct ArpIpTarget, arp_ip_target);
+} ArpIpTarget;
+
struct Bond {
NetDev meta;
BondMode mode;
BondXmitHashPolicy xmit_hash_policy;
BondLacpRate lacp_rate;
+ BondAdSelect ad_select;
+ BondFailOverMac fail_over_mac;
+ BondArpValidate arp_validate;
+ BondArpAllTargets arp_all_targets;
+ BondPrimaryReselect primary_reselect;
+
+ bool all_slaves_active;
+
+ unsigned resend_igmp;
+ unsigned packets_per_slave;
+ unsigned num_grat_arp;
+ unsigned min_links;
usec_t miimon;
usec_t updelay;
usec_t downdelay;
+ usec_t arp_interval;
+ usec_t lp_interval;
+
+ int n_arp_ip_targets;
+ ArpIpTarget *arp_ip_targets;
};
extern const NetDevVTable bond_vtable;
@@ -78,6 +140,27 @@ BondXmitHashPolicy bond_xmit_hash_policy_from_string(const char *d) _pure_;
const char *bond_lacp_rate_to_string(BondLacpRate d) _const_;
BondLacpRate bond_lacp_rate_from_string(const char *d) _pure_;
+const char *bond_fail_over_mac_to_string(BondFailOverMac d) _const_;
+BondFailOverMac bond_fail_over_mac_from_string(const char *d) _pure_;
+
+const char *bond_ad_select_to_string(BondAdSelect d) _const_;
+BondAdSelect bond_ad_select_from_string(const char *d) _pure_;
+
+const char *bond_arp_validate_to_string(BondArpValidate d) _const_;
+BondArpValidate bond_arp_validate_from_string(const char *d) _pure_;
+
+const char *bond_arp_all_targets_to_string(BondArpAllTargets d) _const_;
+BondArpAllTargets bond_arp_all_targets_from_string(const char *d) _pure_;
+
+const char *bond_primary_reselect_to_string(BondPrimaryReselect d) _const_;
+BondPrimaryReselect bond_primary_reselect_from_string(const char *d) _pure_;
+
int config_parse_bond_mode(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);
int config_parse_bond_xmit_hash_policy(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);
int config_parse_bond_lacp_rate(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);
+int config_parse_bond_ad_select(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);
+int config_parse_bond_fail_over_mac(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);
+int config_parse_bond_arp_validate(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);
+int config_parse_bond_arp_all_targets(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);
+int config_parse_bond_primary_reselect(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);
+int config_parse_arp_ip_target_address(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-netdev-bridge.c b/src/network/networkd-netdev-bridge.c
index 91b7051a06..fd6af7e99b 100644
--- a/src/network/networkd-netdev-bridge.c
+++ b/src/network/networkd-netdev-bridge.c
@@ -20,11 +20,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <netinet/ether.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include "sd-rtnl.h"
#include "networkd-netdev-bridge.h"
#include "missing.h"
diff --git a/src/network/networkd-netdev-dummy.c b/src/network/networkd-netdev-dummy.c
index 01c10a2d73..bb246a2be0 100644
--- a/src/network/networkd-netdev-dummy.c
+++ b/src/network/networkd-netdev-dummy.c
@@ -20,12 +20,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <netinet/ether.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <linux/veth.h>
-#include "sd-rtnl.h"
#include "networkd-netdev-dummy.h"
const NetDevVTable dummy_vtable = {
diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
index 963c47c3e5..66ed2e013c 100644
--- a/src/network/networkd-netdev-gperf.gperf
+++ b/src/network/networkd-netdev-gperf.gperf
@@ -18,49 +18,65 @@ struct ConfigPerfItem;
%struct-type
%includes
%%
-Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host)
-Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
-Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch)
-NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
-NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
-NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
-NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
-NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
-VLAN.Id, config_parse_uint64, 0, offsetof(VLan, id)
-MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
-IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
-Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local)
-Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
-Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
-Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
-Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
-Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
-Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
-Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
-VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id)
-VXLAN.Group, config_parse_vxlan_group_address, 0, offsetof(VxLan, group)
-VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos)
-VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl)
-VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning)
-VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy)
-VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss)
-VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss)
-VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit)
-VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing)
-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)
-Tun.User, config_parse_string, 0, offsetof(TunTap, user_name)
-Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name)
-Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
-Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
-Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
-Tap.User, config_parse_string, 0, offsetof(TunTap, user_name)
-Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name)
-Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
-Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy)
-Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate)
-Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon)
-Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay)
-Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay)
+Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host)
+Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
+Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch)
+NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
+NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
+NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
+NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
+NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
+VLAN.Id, config_parse_uint64, 0, offsetof(VLan, id)
+MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
+IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
+Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local)
+Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
+Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
+Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
+Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
+Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
+Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
+Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
+VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id)
+VXLAN.Group, config_parse_vxlan_group_address, 0, offsetof(VxLan, group)
+VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos)
+VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl)
+VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning)
+VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy)
+VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss)
+VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss)
+VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit)
+VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum)
+VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx)
+VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx)
+VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing)
+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)
+Tun.User, config_parse_string, 0, offsetof(TunTap, user_name)
+Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name)
+Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
+Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
+Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
+Tap.User, config_parse_string, 0, offsetof(TunTap, user_name)
+Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name)
+Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
+Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy)
+Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate)
+Bond.AdSelect, config_parse_bond_ad_select, 0, offsetof(Bond, ad_select)
+Bond.FailOverMACPolicy, config_parse_bond_fail_over_mac, 0, offsetof(Bond, fail_over_mac)
+Bond.ARPIPTargets, config_parse_arp_ip_target_address, 0, 0
+Bond.ARPValidate, config_parse_bond_arp_validate, 0, offsetof(Bond, arp_validate)
+Bond.ARPAllTargets, config_parse_bond_arp_all_targets, 0, offsetof(Bond, arp_all_targets)
+Bond.PrimaryReselectPolicy, config_parse_bond_primary_reselect, 0, offsetof(Bond, primary_reselect)
+Bond.ResendIGMP, config_parse_unsigned, 0, offsetof(Bond, resend_igmp)
+Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave)
+Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp)
+Bond.AllSlavesActive, config_parse_unsigned, 0, offsetof(Bond, all_slaves_active)
+Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links)
+Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon)
+Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay)
+Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay)
+Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval)
+Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval)
diff --git a/src/network/networkd-netdev-ipvlan.c b/src/network/networkd-netdev-ipvlan.c
index 9a7c280c6b..5189000c1f 100644
--- a/src/network/networkd-netdev-ipvlan.c
+++ b/src/network/networkd-netdev-ipvlan.c
@@ -20,12 +20,9 @@
***/
#include <net/if.h>
-#include <linux/if_link.h>
#include "networkd-netdev-ipvlan.h"
-#include "network-internal.h"
#include "conf-parser.h"
-#include "list.h"
static const char* const ipvlan_mode_table[_NETDEV_IPVLAN_MODE_MAX] = {
[NETDEV_IPVLAN_MODE_L2] = "L2",
diff --git a/src/network/networkd-netdev-macvlan.c b/src/network/networkd-netdev-macvlan.c
index 198fb575ee..5f41f1c865 100644
--- a/src/network/networkd-netdev-macvlan.c
+++ b/src/network/networkd-netdev-macvlan.c
@@ -22,9 +22,7 @@
#include <net/if.h>
#include "networkd-netdev-macvlan.h"
-#include "network-internal.h"
#include "conf-parser.h"
-#include "list.h"
static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = {
[NETDEV_MACVLAN_MODE_PRIVATE] = "private",
diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c
index e95082d119..8af4be4974 100644
--- a/src/network/networkd-netdev-tunnel.c
+++ b/src/network/networkd-netdev-tunnel.c
@@ -19,7 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <netinet/ether.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/ip.h>
@@ -29,7 +28,6 @@
#include "sd-rtnl.h"
#include "networkd-netdev-tunnel.h"
#include "networkd-link.h"
-#include "network-internal.h"
#include "util.h"
#include "missing.h"
#include "conf-parser.h"
@@ -56,44 +54,24 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LINK attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LOCAL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_REMOTE attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_TTL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
return r;
}
@@ -109,44 +87,24 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LINK attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LOCAL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_REMOTE attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_TTL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
return r;
}
@@ -158,9 +116,9 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
assert(netdev);
if (netdev->kind == NETDEV_KIND_GRE)
- t = GRE(netdev);
+ t = GRE(netdev);
else
- t = GRETAP(netdev);
+ t = GRETAP(netdev);
assert(t);
assert(t->family == AF_INET);
@@ -168,52 +126,28 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
assert(m);
r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_LINK attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LINK attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_LOCAL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LOCAL attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_REMOTE attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_REMOTE attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_TTL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TTL attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_TOS attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TOS attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_GRE_PMTUDISC, t->pmtudisc);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_PMTUDISC attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_PMTUDISC attribute: %m");
return r;
}
@@ -225,9 +159,9 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl
assert(netdev);
if (netdev->kind == NETDEV_KIND_IP6GRE)
- t = IP6GRE(netdev);
+ t = IP6GRE(netdev);
else
- t = IP6GRETAP(netdev);
+ t = IP6GRETAP(netdev);
assert(t);
assert(t->family == AF_INET6);
@@ -235,36 +169,20 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl
assert(m);
r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_LINK attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LINK attribute: %m");
r = sd_rtnl_message_append_in6_addr(m, IFLA_GRE_LOCAL, &t->local.in6);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_LOCAL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_LOCAL attribute: %m");
r = sd_rtnl_message_append_in6_addr(m, IFLA_GRE_REMOTE, &t->remote.in6);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_REMOTE attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_REMOTE attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_GRE_TTL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_TTL attribute: %m");
return r;
}
@@ -280,28 +198,41 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LINK attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LOCAL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_REMOTE attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
+
+ return r;
+}
+
+static int netdev_vti6_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ Tunnel *t = VTI6(netdev);
+ int r;
+
+ assert(netdev);
+ assert(link);
+ assert(m);
+ assert(t);
+ assert(t->family == AF_INET6);
+
+ r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
+
+ r = sd_rtnl_message_append_in6_addr(m, IFLA_VTI_LOCAL, &t->local.in6);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
+
+ r = sd_rtnl_message_append_in6_addr(m, IFLA_VTI_REMOTE, &t->remote.in6);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
return r;
}
@@ -318,36 +249,20 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_rtnl
assert(t->family == AF_INET6);
r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LINK attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
r = sd_rtnl_message_append_in6_addr(m, IFLA_IPTUN_LOCAL, &t->local.in6);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_LOCAL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
r = sd_rtnl_message_append_in6_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in6);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_REMOTE attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_REMOTE attribute: %m");
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_TTL attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
switch (t->ip6tnl_mode) {
case NETDEV_IP6_TNL_MODE_IP6IP6:
@@ -363,12 +278,8 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_rtnl
}
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PROTO, proto);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IPTUN_MODE attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_MODE attribute: %m");
return r;
}
@@ -401,6 +312,9 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
case NETDEV_KIND_VTI:
t = VTI(netdev);
break;
+ case NETDEV_KIND_VTI6:
+ t = VTI6(netdev);
+ break;
case NETDEV_KIND_IP6TNL:
t = IP6TNL(netdev);
break;
@@ -411,13 +325,13 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
assert(t);
if (t->remote.in.s_addr == INADDR_ANY) {
- log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
- return -EINVAL;
+ log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
+ return -EINVAL;
}
if (t->family != AF_INET && t->family != AF_INET6) {
- log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
- return -EINVAL;
+ log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
+ return -EINVAL;
}
if (netdev->kind == NETDEV_KIND_IP6TNL) {
@@ -485,9 +399,15 @@ static void sit_init(NetDev *n) {
}
static void vti_init(NetDev *n) {
- Tunnel *t = VTI(n);
+ Tunnel *t;
assert(n);
+
+ if (n->kind == NETDEV_KIND_VTI)
+ t = VTI(n);
+ else
+ t = VTI6(n);
+
assert(t);
t->pmtudisc = true;
@@ -561,6 +481,15 @@ const NetDevVTable vti_vtable = {
.config_verify = netdev_tunnel_verify,
};
+const NetDevVTable vti6_vtable = {
+ .object_size = sizeof(Tunnel),
+ .init = vti_init,
+ .sections = "Match\0NetDev\0Tunnel\0",
+ .fill_message_create = netdev_vti6_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
+ .config_verify = netdev_tunnel_verify,
+};
+
const NetDevVTable gre_vtable = {
.object_size = sizeof(Tunnel),
.init = gre_init,
diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h
index 453d73c596..88f57ac105 100644
--- a/src/network/networkd-netdev-tunnel.h
+++ b/src/network/networkd-netdev-tunnel.h
@@ -55,6 +55,7 @@ struct Tunnel {
extern const NetDevVTable ipip_vtable;
extern const NetDevVTable sit_vtable;
extern const NetDevVTable vti_vtable;
+extern const NetDevVTable vti6_vtable;
extern const NetDevVTable gre_vtable;
extern const NetDevVTable gretap_vtable;
extern const NetDevVTable ip6gre_vtable;
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c
index 4f449aea48..4e974927cb 100644
--- a/src/network/networkd-netdev-tuntap.c
+++ b/src/network/networkd-netdev-tuntap.c
@@ -108,7 +108,7 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
}
- if(t->group_name) {
+ if (t->group_name) {
group = t->group_name;
@@ -173,15 +173,11 @@ static void tuntap_done(NetDev *netdev) {
static int tuntap_verify(NetDev *netdev, const char *filename) {
assert(netdev);
- if (netdev->mtu) {
- log_warning_netdev(netdev, "MTU configured for %s, ignoring",
- netdev_kind_to_string(netdev->kind));
- }
+ if (netdev->mtu)
+ log_netdev_warning(netdev, "MTU configured for %s, ignoring", netdev_kind_to_string(netdev->kind));
- if (netdev->mac) {
- log_warning_netdev(netdev, "MAC configured for %s, ignoring",
- netdev_kind_to_string(netdev->kind));
- }
+ if (netdev->mac)
+ log_netdev_warning(netdev, "MAC configured for %s, ignoring", netdev_kind_to_string(netdev->kind));
return 0;
}
diff --git a/src/network/networkd-netdev-veth.c b/src/network/networkd-netdev-veth.c
index 251cf92aec..9e9e1225e7 100644
--- a/src/network/networkd-netdev-veth.c
+++ b/src/network/networkd-netdev-veth.c
@@ -19,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <netinet/ether.h>
-#include <arpa/inet.h>
#include <net/if.h>
#include <linux/veth.h>
diff --git a/src/network/networkd-netdev-vlan.c b/src/network/networkd-netdev-vlan.c
index 665559f895..0ed024b41d 100644
--- a/src/network/networkd-netdev-vlan.c
+++ b/src/network/networkd-netdev-vlan.c
@@ -22,8 +22,6 @@
#include <net/if.h>
#include "networkd-netdev-vlan.h"
-#include "network-internal.h"
-#include "list.h"
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
VLan *v = VLAN(netdev);
diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c
index d5128cb7c0..e2c2b108b9 100644
--- a/src/network/networkd-netdev-vxlan.c
+++ b/src/network/networkd-netdev-vxlan.c
@@ -19,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <netinet/ether.h>
-#include <arpa/inet.h>
#include <net/if.h>
#include "sd-rtnl.h"
@@ -135,6 +133,30 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
}
}
+ r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_CSUM, v->udpcsum);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_VXLAN_UDP_CSUM attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_TX attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
+ if (r < 0) {
+ log_netdev_error(netdev,
+ "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
return r;
}
@@ -199,6 +221,9 @@ static void vxlan_init(NetDev *netdev) {
v->id = VXLAN_VID_MAX + 1;
v->learning = true;
+ v->udpcsum = false;
+ v->udp6zerocsumtx = false;
+ v->udp6zerocsumrx = false;
}
const NetDevVTable vxlan_vtable = {
diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h
index 6339af9add..fe5254e91f 100644
--- a/src/network/networkd-netdev-vxlan.h
+++ b/src/network/networkd-netdev-vxlan.h
@@ -47,6 +47,9 @@ struct VxLan {
bool route_short_circuit;
bool l2miss;
bool l3miss;
+ bool udpcsum;
+ bool udp6zerocsumtx;
+ bool udp6zerocsumrx;
};
extern const NetDevVTable vxlan_vtable;
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 8119205dde..66fd0fac0a 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -24,7 +24,6 @@
#include "networkd-netdev.h"
#include "networkd-link.h"
#include "network-internal.h"
-#include "path-util.h"
#include "conf-files.h"
#include "conf-parser.h"
#include "list.h"
@@ -44,6 +43,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_IP6GRETAP] = &ip6gretap_vtable,
[NETDEV_KIND_SIT] = &sit_vtable,
[NETDEV_KIND_VTI] = &vti_vtable,
+ [NETDEV_KIND_VTI6] = &vti6_vtable,
[NETDEV_KIND_VETH] = &veth_vtable,
[NETDEV_KIND_DUMMY] = &dummy_vtable,
[NETDEV_KIND_TUN] = &tun_vtable,
@@ -66,6 +66,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_SIT] = "sit",
[NETDEV_KIND_VETH] = "veth",
[NETDEV_KIND_VTI] = "vti",
+ [NETDEV_KIND_VTI6] = "vti6",
[NETDEV_KIND_DUMMY] = "dummy",
[NETDEV_KIND_TUN] = "tun",
[NETDEV_KIND_TAP] = "tap",
@@ -191,34 +192,21 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_hand
assert(link);
assert(callback);
- r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req,
- RTM_SETLINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not allocate RTM_SETLINK message: %s",
- strerror(-r));
- return r;
- }
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
r = sd_rtnl_message_append_u32(req, IFLA_MASTER, netdev->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_MASTER attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m");
r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not send rtnetlink message: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error(netdev, "Could not send rtnetlink message: %m");
link_ref(link);
- log_netdev_debug(netdev, "enslaving link '%s'", link->ifname);
+ log_netdev_debug(netdev, "Enslaving link '%s'", link->ifname);
return 0;
}
@@ -235,7 +223,7 @@ static int netdev_enter_ready(NetDev *netdev) {
netdev->state = NETDEV_STATE_READY;
- log_info_netdev(netdev, "netdev ready");
+ log_netdev_info(netdev, "netdev ready");
LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks) {
/* enslave the links that were attempted to be enslaved before the
@@ -261,15 +249,15 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda
r = sd_rtnl_message_get_errno(m);
if (r == -EEXIST)
- log_netdev_debug(netdev, "netdev exists, using existing");
+ log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
else if (r < 0) {
- log_warning_netdev(netdev, "netdev could not be created: %s", strerror(-r));
+ log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
netdev_drop(netdev);
return 1;
}
- log_netdev_debug(netdev, "created");
+ log_netdev_debug(netdev, "Created");
return 1;
}
@@ -298,8 +286,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callbac
LIST_PREPEND(callbacks, netdev->callbacks, cb);
- log_netdev_debug(netdev, "will enslave '%s', when reday",
- link->ifname);
+ log_netdev_debug(netdev, "Will enslave '%s', when ready", link->ifname);
}
return 0;
@@ -316,25 +303,23 @@ int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
assert(message);
r = sd_rtnl_message_get_type(message, &type);
- if (r < 0) {
- log_netdev_error(netdev, "Could not get rtnl message type");
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not get rtnl message type: %m");
if (type != RTM_NEWLINK) {
- log_netdev_error(netdev, "Can not set ifindex from unexpected rtnl message type");
+ log_netdev_error(netdev, "Cannot set ifindex from unexpected rtnl message type.");
return -EINVAL;
}
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
if (r < 0) {
- log_netdev_error(netdev, "Could not get ifindex: %s", strerror(-r));
+ log_netdev_error_errno(netdev, r, "Could not get ifindex: %m");
netdev_enter_failed(netdev);
return r;
} else if (ifindex <= 0) {
log_netdev_error(netdev, "Got invalid ifindex: %d", ifindex);
netdev_enter_failed(netdev);
- return r;
+ return -EINVAL;
}
if (netdev->ifindex > 0) {
@@ -349,35 +334,26 @@ int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
}
r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &received_name);
- if (r < 0) {
- log_netdev_error(netdev, "Could not get IFNAME");
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not get IFNAME: %m");
if (!streq(netdev->ifname, received_name)) {
- log_netdev_error(netdev, "Received newlink with wrong IFNAME %s",
- received_name);
+ log_netdev_error(netdev, "Received newlink with wrong IFNAME %s", received_name);
netdev_enter_failed(netdev);
return r;
}
r = sd_rtnl_message_enter_container(message, IFLA_LINKINFO);
- if (r < 0) {
- log_netdev_error(netdev, "Could not get LINKINFO");
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not get LINKINFO: %m");
r = sd_rtnl_message_read_string(message, IFLA_INFO_KIND, &received_kind);
- if (r < 0) {
- log_netdev_error(netdev, "Could not get KIND");
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not get KIND: %m");
r = sd_rtnl_message_exit_container(message);
- if (r < 0) {
- log_netdev_error(netdev, "Could not exit container");
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not exit container: %m");
if (netdev->kind == NETDEV_KIND_TAP)
/* the kernel does not distinguish between tun and tap */
@@ -469,72 +445,43 @@ static int netdev_create(NetDev *netdev, Link *link,
if (r < 0)
return r;
- log_netdev_debug(netdev, "created");
+ log_netdev_debug(netdev, "Created");
} else {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not allocate RTM_NEWLINK message: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not allocate RTM_NEWLINK message: %m");
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m");
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
}
if (netdev->mtu) {
r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_MTU attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_MTU attribute: %m");
}
if (link) {
r = sd_rtnl_message_append_u32(m, IFLA_LINK, link->ifindex);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_LINK attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINK attribute: %m");
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
- netdev_kind_to_string(netdev->kind));
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
+ r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
if (NETDEV_VTABLE(netdev)->fill_message_create) {
r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m);
@@ -543,50 +490,30 @@ static int netdev_create(NetDev *netdev, Link *link,
}
r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
if (link) {
- r = sd_rtnl_call_async(netdev->manager->rtnl, m,
- callback, link, 0, NULL);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not send rtnetlink message: %s",
- strerror(-r));
- return r;
- }
+ r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
link_ref(link);
} else {
- r = sd_rtnl_call_async(netdev->manager->rtnl, m,
- netdev_create_handler, netdev, 0,
- NULL);
- if (r < 0) {
- log_netdev_error(netdev,
- "Could not send rtnetlink message: %s",
- strerror(-r));
- return r;
- }
+ r = sd_rtnl_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
netdev_ref(netdev);
}
netdev->state = NETDEV_STATE_CREATING;
- log_netdev_debug(netdev, "creating");
+ log_netdev_debug(netdev, "Creating");
}
return 0;
@@ -710,11 +637,8 @@ static int netdev_load_one(Manager *manager, const char *filename) {
if (!netdev->mac) {
r = netdev_get_mac(netdev->ifname, &netdev->mac);
- if (r < 0) {
- log_error("Failed to generate predictable MAC address for %s",
- netdev->ifname);
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname);
}
r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
@@ -743,8 +667,9 @@ static int netdev_load_one(Manager *manager, const char *filename) {
}
int netdev_load(Manager *manager) {
+ _cleanup_strv_free_ char **files = NULL;
NetDev *netdev;
- char **files, **f;
+ char **f;
int r;
assert(manager);
@@ -762,7 +687,5 @@ int netdev_load(Manager *manager) {
return r;
}
- strv_free(files);
-
return 0;
}
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
index 3756b1e5a7..1ded495e4a 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/networkd-netdev.h
@@ -22,10 +22,7 @@
#pragma once
#include "networkd.h"
-#include "hashmap.h"
#include "list.h"
-#include "set.h"
-#include "in-addr-util.h"
typedef struct NetDevVTable NetDevVTable;
@@ -53,6 +50,7 @@ typedef enum NetDevKind {
NETDEV_KIND_SIT,
NETDEV_KIND_VETH,
NETDEV_KIND_VTI,
+ NETDEV_KIND_VTI6,
NETDEV_KIND_IP6TNL,
NETDEV_KIND_DUMMY,
NETDEV_KIND_TUN,
@@ -172,6 +170,7 @@ DEFINE_CAST(IP6GRE, Tunnel);
DEFINE_CAST(IP6GRETAP, Tunnel);
DEFINE_CAST(SIT, Tunnel);
DEFINE_CAST(VTI, Tunnel);
+DEFINE_CAST(VTI6, Tunnel);
DEFINE_CAST(IP6TNL, Tunnel);
DEFINE_CAST(VETH, Veth);
DEFINE_CAST(DUMMY, Dummy);
@@ -203,13 +202,24 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsign
/* Macros which append INTERFACE= to the message */
-#define log_full_netdev(level, netdev, fmt, ...) log_object_internal(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__)
-#define log_netdev_debug(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
-#define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
-#define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)
-#define log_warning_netdev(netdev, ...) log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__)
-#define log_netdev_error(netdev, ...) log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__)
-
-#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__)
-
-#define NETDEVIF(netdev) "INTERFACE=%s", netdev->ifname
+#define log_netdev_full(netdev, level, error, ...) \
+ ({ \
+ NetDev *_n = (netdev); \
+ _n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, ##__VA_ARGS__) : \
+ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
+ })
+
+#define log_netdev_debug(netdev, ...) log_netdev_full(netdev, LOG_DEBUG, 0, ##__VA_ARGS__)
+#define log_netdev_info(netdev, ...) log_netdev_full(netdev, LOG_INFO, 0, ##__VA_ARGS__)
+#define log_netdev_notice(netdev, ...) log_netdev_full(netdev, LOG_NOTICE, 0, ##__VA_ARGS__)
+#define log_netdev_warning(netdev, ...) log_netdev_full(netdev, LOG_WARNING, 0, ## __VA_ARGS__)
+#define log_netdev_error(netdev, ...) log_netdev_full(netdev, LOG_ERR, 0, ##__VA_ARGS__)
+
+#define log_netdev_debug_errno(netdev, error, ...) log_netdev_full(netdev, LOG_DEBUG, error, ##__VA_ARGS__)
+#define log_netdev_info_errno(netdev, error, ...) log_netdev_full(netdev, LOG_INFO, error, ##__VA_ARGS__)
+#define log_netdev_notice_errno(netdev, error, ...) log_netdev_full(netdev, LOG_NOTICE, error, ##__VA_ARGS__)
+#define log_netdev_warning_errno(netdev, error, ...) log_netdev_full(netdev, LOG_WARNING, error, ##__VA_ARGS__)
+#define log_netdev_error_errno(netdev, error, ...) log_netdev_full(netdev, LOG_ERR, error, ##__VA_ARGS__)
+
+#define LOG_NETDEV_MESSAGE(netdev, fmt, ...) "MESSAGE=%s: " fmt, (netdev)->ifname, ##__VA_ARGS__
+#define LOG_NETDEV_INTERFACE(netdev) "INTERFACE=%s", (netdev)->ifname
diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c
index 36b40d32b9..b5f8f5cfb2 100644
--- a/src/network/networkd-network-bus.c
+++ b/src/network/networkd-network-bus.c
@@ -19,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "bus-util.h"
-#include "bus-label.h"
#include "strv.h"
#include "networkd.h"
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index fc277df949..8abf5bcf2e 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -48,6 +48,7 @@ Network.LLMNR, config_parse_llmnr, 0,
Network.NTP, config_parse_strv, 0, offsetof(Network, ntp)
Network.IPForward, config_parse_address_family_boolean,0, offsetof(Network, ip_forward)
Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade)
+Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier)
Address.Address, config_parse_address, 0, 0
Address.Peer, config_parse_address, 0, 0
Address.Broadcast, config_parse_broadcast, 0, 0
@@ -57,7 +58,9 @@ Route.Destination, config_parse_destination, 0,
Route.Source, config_parse_destination, 0, 0
Route.Metric, config_parse_route_priority, 0, 0
Route.Scope, config_parse_route_scope, 0, 0
+DHCP.ClientIdentifier, config_parse_dhcp_client_identifier,0, offsetof(Network, dhcp_client_identifier)
DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns)
+DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_ntp)
DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu)
DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname)
DHCP.UseDomains, config_parse_bool, 0, offsetof(Network, dhcp_domains)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 35ac064cf6..5947084106 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -22,10 +22,10 @@
#include <ctype.h>
#include <net/if.h>
-#include "path-util.h"
#include "conf-files.h"
#include "conf-parser.h"
#include "util.h"
+#include "hostname-util.h"
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-link.h"
@@ -104,6 +104,7 @@ static int network_load_one(Manager *manager, const char *filename) {
network->dhcp_routes = true;
network->dhcp_sendhost = true;
network->dhcp_route_metric = DHCP_ROUTE_METRIC;
+ network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID;
network->llmnr = LLMNR_SUPPORT_YES;
@@ -209,6 +210,7 @@ void network_free(Network *network) {
strv_free(network->ntp);
strv_free(network->dns);
strv_free(network->domains);
+ strv_free(network->bind_carrier);
netdev_unref(network->bridge);
@@ -271,29 +273,39 @@ int network_get(Manager *manager, struct udev_device *device,
const char *ifname, const struct ether_addr *address,
Network **ret) {
Network *network;
+ struct udev_device *parent;
+ const char *path = NULL, *parent_driver = NULL, *driver = NULL, *devtype = NULL;
assert(manager);
assert(ret);
+ if (device) {
+ path = udev_device_get_property_value(device, "ID_PATH");
+
+ parent = udev_device_get_parent(device);
+ if (parent)
+ parent_driver = udev_device_get_driver(parent);
+
+ driver = udev_device_get_property_value(device, "ID_NET_DRIVER");
+
+ devtype = udev_device_get_devtype(device);
+ }
+
LIST_FOREACH(networks, network, manager->networks) {
if (net_match_config(network->match_mac, network->match_path,
network->match_driver, network->match_type,
network->match_name, network->match_host,
network->match_virt, network->match_kernel,
network->match_arch,
- address,
- udev_device_get_property_value(device, "ID_PATH"),
- udev_device_get_driver(udev_device_get_parent(device)),
- udev_device_get_property_value(device, "ID_NET_DRIVER"),
- udev_device_get_devtype(device),
- ifname)) {
- if (network->match_name) {
+ address, path, parent_driver, driver,
+ devtype, ifname)) {
+ if (network->match_name && device) {
const char *attr;
uint8_t name_assign_type = NET_NAME_UNKNOWN;
attr = udev_device_get_sysattr_value(device, "name_assign_type");
if (attr)
- (void)safe_atou8(attr, &name_assign_type);
+ (void) safe_atou8(attr, &name_assign_type);
if (name_assign_type == NET_NAME_ENUM)
log_warning("%-*s: found matching network '%s', based on potentially unpredictable ifname",
@@ -413,8 +425,8 @@ int config_parse_netdev(const char *unit,
r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Can not add VLAN '%s' to network: %s",
- rvalue, strerror(-r));
+ "Can not add VLAN '%s' to network: %m",
+ rvalue);
return 0;
}
@@ -490,8 +502,7 @@ int config_parse_tunnel(const char *unit,
r = netdev_get(network->manager, rvalue, &netdev);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Tunnel is invalid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Tunnel is invalid, ignoring assignment: %s", rvalue);
return 0;
}
@@ -502,6 +513,7 @@ int config_parse_tunnel(const char *unit,
netdev->kind != NETDEV_KIND_IP6GRE &&
netdev->kind != NETDEV_KIND_IP6GRETAP &&
netdev->kind != NETDEV_KIND_VTI &&
+ netdev->kind != NETDEV_KIND_VTI6 &&
netdev->kind != NETDEV_KIND_IP6TNL
) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
@@ -511,9 +523,7 @@ int config_parse_tunnel(const char *unit,
r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Can not add VLAN '%s' to network: %s",
- rvalue, strerror(-r));
+ log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue);
return 0;
}
@@ -600,6 +610,14 @@ int config_parse_dhcp(
return 0;
}
+static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
+ [DHCP_CLIENT_ID_MAC] = "mac",
+ [DHCP_CLIENT_ID_DUID] = "duid"
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier, DCHPClientIdentifier);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier, dhcp_client_identifier, DCHPClientIdentifier, "Failed to parse client identifier type");
+
static const char* const llmnr_support_table[_LLMNR_SUPPORT_MAX] = {
[LLMNR_SUPPORT_NO] = "no",
[LLMNR_SUPPORT_YES] = "yes",
@@ -674,13 +692,13 @@ int config_parse_ipv6token(
r = in_addr_from_string(AF_INET6, rvalue, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse IPv6 token, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IPv6 token, ignoring: %s", rvalue);
return 0;
}
r = in_addr_is_null(AF_INET6, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, -r, "IPv6 token can not be the ANY address, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "IPv6 token can not be the ANY address, ignoring: %s", rvalue);
return 0;
}
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index c2d1ffca25..7f110a5217 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -19,15 +19,12 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <net/if.h>
#include "networkd.h"
#include "networkd-link.h"
-#include "utf8.h"
#include "util.h"
#include "conf-parser.h"
-#include "network-internal.h"
int route_new_static(Network *network, unsigned section, Route **ret) {
_cleanup_route_free_ Route *route = NULL;
diff --git a/src/network/networkd-wait-online-link.c b/src/network/networkd-wait-online-link.c
index e091b20ed9..341bcae3fb 100644
--- a/src/network/networkd-wait-online-link.c
+++ b/src/network/networkd-wait-online-link.c
@@ -20,10 +20,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <net/if.h>
#include "sd-network.h"
-#include "strv.h"
#include "networkd-wait-online-link.h"
diff --git a/src/network/networkd-wait-online-manager.c b/src/network/networkd-wait-online-manager.c
index cafe110e50..1c997a50a4 100644
--- a/src/network/networkd-wait-online-manager.c
+++ b/src/network/networkd-wait-online-manager.c
@@ -25,7 +25,6 @@
#include "rtnl-util.h"
-#include "network-util.h"
#include "network-internal.h"
#include "networkd-wait-online-link.h"
#include "networkd-wait-online.h"
diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
index f0ca6def87..6a96f1de55 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/networkd-wait-online.c
@@ -21,11 +21,10 @@
#include <getopt.h>
#include "sd-daemon.h"
-
-#include "networkd-wait-online.h"
-
#include "strv.h"
#include "build.h"
+#include "signal-util.h"
+#include "networkd-wait-online.h"
static bool arg_quiet = false;
static usec_t arg_timeout = 120 * USEC_PER_SEC;
diff --git a/src/network/networkd-wait-online.h b/src/network/networkd-wait-online.h
index 66b865cfe2..73d129699d 100644
--- a/src/network/networkd-wait-online.h
+++ b/src/network/networkd-wait-online.h
@@ -25,7 +25,6 @@
#include "sd-rtnl.h"
#include "sd-network.h"
-#include "util.h"
#include "hashmap.h"
typedef struct Manager Manager;
diff --git a/src/network/networkd.c b/src/network/networkd.c
index 7319276c53..41ec7cf904 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -19,10 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "capability.h"
-#include "sd-event.h"
#include "sd-daemon.h"
-
+#include "capability.h"
+#include "signal-util.h"
#include "networkd.h"
int main(int argc, char *argv[]) {
@@ -54,21 +53,19 @@ int main(int argc, char *argv[]) {
* watches in. */
r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid);
if (r < 0)
- log_error_errno(r, "Could not create runtime directory: %m");
+ log_warning_errno(r, "Could not create runtime directory: %m");
r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid);
if (r < 0)
- log_error_errno(r, "Could not create runtime directory 'links': %m");
+ log_warning_errno(r, "Could not create runtime directory 'links': %m");
r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid);
if (r < 0)
- log_error_errno(r, "Could not create runtime directory 'leases': %m");
+ log_warning_errno(r, "Could not create runtime directory 'leases': %m");
r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid);
if (r < 0)
- log_error("Could not create runtime directory 'lldp': %s",
- strerror(-r));
-
+ log_warning_errno(r, "Could not create runtime directory 'lldp': %m");
r = drop_privileges(uid, gid,
(1ULL << CAP_NET_ADMIN) |
diff --git a/src/network/networkd.h b/src/network/networkd.h
index bdb2f20e2f..49afeffe81 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -60,6 +60,7 @@ typedef enum AddressFamilyBoolean {
ADDRESS_FAMILY_IPV4 = 1,
ADDRESS_FAMILY_IPV6 = 2,
ADDRESS_FAMILY_YES = 3,
+ ADDRESS_FAMILY_KERNEL = 4,
_ADDRESS_FAMILY_BOOLEAN_MAX,
_ADDRESS_FAMILY_BOOLEAN_INVALID = -1,
} AddressFamilyBoolean;
@@ -83,6 +84,13 @@ typedef enum LinkOperationalState {
_LINK_OPERSTATE_INVALID = -1
} LinkOperationalState;
+typedef enum DCHPClientIdentifier {
+ DHCP_CLIENT_ID_MAC,
+ DHCP_CLIENT_ID_DUID,
+ _DHCP_CLIENT_ID_MAX,
+ _DHCP_CLIENT_ID_INVALID = -1,
+} DCHPClientIdentifier;
+
struct FdbEntry {
Network *network;
unsigned section;
@@ -115,6 +123,7 @@ struct Network {
NetDev *bond;
Hashmap *stacked_netdevs;
AddressFamilyBoolean dhcp;
+ DCHPClientIdentifier dhcp_client_identifier;
char *dhcp_vendor_class_identifier;
bool dhcp_dns;
bool dhcp_ntp;
@@ -151,7 +160,7 @@ struct Network {
Hashmap *fdb_entries_by_section;
bool wildcard_domain;
- char **domains, **dns, **ntp;
+ char **domains, **dns, **ntp, **bind_carrier;
LLMNRSupport llmnr;
@@ -165,7 +174,7 @@ struct Address {
int family;
unsigned char prefixlen;
unsigned char scope;
- unsigned char flags;
+ uint32_t flags;
char *label;
struct in_addr broadcast;
@@ -403,6 +412,9 @@ int config_parse_fdb_vlan_id(const char *unit, const char *filename, unsigned li
int config_parse_dhcp(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);
+int config_parse_dhcp_client_identifier(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);
/* IPv4LL support (legacy) */
@@ -437,7 +449,7 @@ AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_;
int config_parse_address_family_boolean(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);
-/* Opeartional State */
+/* Operational State */
const char* link_operstate_to_string(LinkOperationalState s) _const_;
LinkOperationalState link_operstate_from_string(const char *s) _pure_;
diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c
index 6709ab0957..67fcca2ac0 100644
--- a/src/network/test-network-tables.c
+++ b/src/network/test-network-tables.c
@@ -1,5 +1,4 @@
#include "networkd.h"
-#include "networkd-link.h"
#include "networkd-netdev-bond.h"
#include "networkd-netdev-macvlan.h"
#include "dhcp6-internal.h"