summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkctl.c29
-rw-r--r--src/network/networkd-address.c23
-rw-r--r--src/network/networkd-dhcp6.c30
-rw-r--r--src/network/networkd-fdb.c2
-rw-r--r--src/network/networkd-ipv4ll.c9
-rw-r--r--src/network/networkd-link.c1
-rw-r--r--src/network/networkd-netdev-bond.c6
-rw-r--r--src/network/networkd-netdev-bridge.c86
-rw-r--r--src/network/networkd-netdev-bridge.h4
-rw-r--r--src/network/networkd-netdev-gperf.gperf3
-rw-r--r--src/network/networkd-netdev-tunnel.c24
-rw-r--r--src/network/networkd-netdev-vxlan.c8
-rw-r--r--src/network/networkd-netdev.c3
-rw-r--r--src/network/networkd-netdev.h3
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.c35
-rw-r--r--src/network/networkd-route.c55
-rw-r--r--src/network/networkd-route.h1
-rw-r--r--src/network/networkd-util.c4
-rw-r--r--src/network/networkd-wait-online.c10
20 files changed, 220 insertions, 117 deletions
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 75572b6388..c78b9444b6 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -19,29 +19,28 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdbool.h>
#include <getopt.h>
#include <net/if.h>
+#include <stdbool.h>
-#include "sd-network.h"
-#include "sd-netlink.h"
-#include "sd-hwdb.h"
#include "sd-device.h"
+#include "sd-hwdb.h"
+#include "sd-netlink.h"
+#include "sd-network.h"
-#include "strv.h"
-#include "build.h"
-#include "util.h"
-#include "pager.h"
-#include "lldp.h"
-#include "netlink-util.h"
+#include "arphrd-list.h"
#include "device-util.h"
+#include "ether-addr-util.h"
#include "hwdb-util.h"
-#include "arphrd-list.h"
+#include "lldp.h"
#include "local-addresses.h"
+#include "netlink-util.h"
+#include "pager.h"
#include "socket-util.h"
-#include "ether-addr-util.h"
-#include "verbs.h"
+#include "strv.h"
#include "terminal-util.h"
+#include "util.h"
+#include "verbs.h"
static bool arg_no_pager = false;
static bool arg_legend = true;
@@ -1063,9 +1062,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index b0d296941e..388beb5d4c 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -430,15 +430,13 @@ int config_parse_broadcast(
return r;
if (n->family == AF_INET6) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
return 0;
}
r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Broadcast is invalid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Broadcast is invalid, ignoring assignment: %s", rvalue);
return 0;
}
@@ -487,10 +485,10 @@ int config_parse_address(const char *unit,
e = strchr(rvalue, '/');
if (e) {
unsigned i;
+
r = safe_atou(e + 1, &i);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Prefix length is invalid, ignoring assignment: %s", e + 1);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Prefix length is invalid, ignoring assignment: %s", e + 1);
return 0;
}
@@ -502,23 +500,20 @@ int config_parse_address(const char *unit,
r = in_addr_from_string_auto(address, &f, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Address is invalid, ignoring assignment: %s", address);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Address is invalid, ignoring assignment: %s", address);
return 0;
}
if (!e && f == AF_INET) {
r = in_addr_default_prefixlen(&buffer.in, &n->prefixlen);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Prefix length not specified, and a default one can not be deduced for '%s', ignoring assignment", address);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Prefix length not specified, and a default one can not be deduced for '%s', ignoring assignment", address);
return 0;
}
}
if (n->family != AF_UNSPEC && f != n->family) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Address is incompatible, ignoring assignment: %s", address);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Address is incompatible, ignoring assignment: %s", address);
return 0;
}
@@ -567,9 +562,7 @@ int config_parse_label(const char *unit,
return log_oom();
if (!ascii_is_valid(label) || strlen(label) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Interface label is not ASCII clean or is too"
- " long, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
free(label);
return 0;
}
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index 13105c7865..3cb7b8d9ca 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -53,8 +53,7 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m,
return 1;
}
- log_link_error(link, "Could not set DHCPv6 address: %s",
- strerror(-r));
+ log_link_error_errno(link, r, "Could not set DHCPv6 address: %m");
link_enter_failed(link);
@@ -115,8 +114,7 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) {
r = sd_icmp6_ra_get_prefixlen(link->icmp6_router_discovery,
&ip6_addr, &prefixlen);
if (r < 0 && r != -EADDRNOTAVAIL) {
- log_link_warning(link, "Could not get prefix information: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not get prefix information: %m");
return r;
}
@@ -172,11 +170,9 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
default:
if (event < 0)
- log_link_warning(link, "DHCPv6 error: %s",
- strerror(-event));
+ log_link_warning_errno(link, event, "DHCPv6 error: %m");
else
- log_link_warning(link, "DHCPv6 unknown event: %d",
- event);
+ log_link_warning(link, "DHCPv6 unknown event: %d", event);
return;
}
@@ -198,24 +194,21 @@ static int dhcp6_configure(Link *link, int event) {
r = sd_dhcp6_client_get_information_request(link->dhcp6_client,
&information_request);
if (r < 0) {
- log_link_warning(link, "Could not get DHCPv6 Information request setting: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not get DHCPv6 Information request setting: %m");
goto error;
}
if (information_request && event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER) {
r = sd_dhcp6_client_stop(link->dhcp6_client);
if (r < 0) {
- log_link_warning(link, "Could not stop DHCPv6 while setting Managed mode %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not stop DHCPv6 while setting Managed mode: %m");
goto error;
}
r = sd_dhcp6_client_set_information_request(link->dhcp6_client,
false);
if (r < 0) {
- log_link_warning(link, "Could not unset DHCPv6 Information request: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not unset DHCPv6 Information request: %m");
goto error;
}
@@ -223,8 +216,7 @@ static int dhcp6_configure(Link *link, int event) {
r = sd_dhcp6_client_start(link->dhcp6_client);
if (r < 0 && r != -EALREADY) {
- log_link_warning(link, "Could not restart DHCPv6: %s",
- strerror(-r));
+ log_link_warning_errno(link, r, "Could not restart DHCPv6: %m");
goto error;
}
@@ -343,11 +335,9 @@ static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
default:
if (event < 0)
- log_link_warning(link, "ICMPv6 error: %s",
- strerror(-event));
+ log_link_warning_errno(link, event, "ICMPv6 error: %m");
else
- log_link_warning(link, "ICMPv6 unknown event: %d",
- event);
+ log_link_warning(link, "ICMPv6 unknown event: %d", event);
break;
}
diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c
index 22efadb843..9cb63cb79f 100644
--- a/src/network/networkd-fdb.c
+++ b/src/network/networkd-fdb.c
@@ -197,7 +197,7 @@ int config_parse_fdb_hwaddr(
&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);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring assignment: %s", rvalue);
return 0;
}
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index af3e3884e6..1902b3d23a 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -44,7 +44,7 @@ static int ipv4ll_address_lost(Link *link) {
r = address_new_dynamic(&address);
if (r < 0) {
- log_link_error(link, "Could not allocate address: %s", strerror(-r));
+ log_link_error_errno(link, r, "Could not allocate address: %m");
return r;
}
@@ -57,8 +57,7 @@ static int ipv4ll_address_lost(Link *link) {
r = route_new_dynamic(&route, RTPROT_UNSPEC);
if (r < 0) {
- log_link_error(link, "Could not allocate route: %s",
- strerror(-r));
+ log_link_error_errno(link, r, "Could not allocate route: %m");
return r;
}
@@ -82,7 +81,7 @@ static int ipv4ll_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *u
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
- log_link_error(link, "could not set ipv4ll route: %s", strerror(-r));
+ log_link_error_errno(link, r, "could not set ipv4ll route: %m");
link_enter_failed(link);
}
@@ -103,7 +102,7 @@ static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
- log_link_error(link, "could not set ipv4ll address: %s", strerror(-r));
+ log_link_error_errno(link, r, "could not set ipv4ll address: %m");
link_enter_failed(link);
} else if (r >= 0)
link_rtnl_process_address(rtnl, m, link->manager);
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index db3975f466..ffc9578e86 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2539,7 +2539,6 @@ int link_save(Link *link) {
if (space)
fputc(' ', f);
serialize_in6_addrs(f, in6_addrs, r);
- space = true;
}
}
diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c
index 12e2321674..bcaba57937 100644
--- a/src/network/networkd-netdev-bond.c
+++ b/src/network/networkd-netdev-bond.c
@@ -357,12 +357,12 @@ int config_parse_arp_ip_target_address(const char *unit,
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);
+ log_syntax(unit, LOG_ERR, filename, line, r, "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);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
return 0;
}
@@ -373,7 +373,7 @@ int config_parse_arp_ip_target_address(const char *unit,
}
if (b->n_arp_ip_targets > NETDEV_BOND_ARP_TARGETS_MAX)
- log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "More than the maximum number of kernel-supported ARP ip targets specified: %d > %d", b->n_arp_ip_targets, NETDEV_BOND_ARP_TARGETS_MAX);
+ log_syntax(unit, LOG_WARNING, filename, line, 0, "More than the maximum number of kernel-supported ARP ip targets specified: %d > %d", b->n_arp_ip_targets, NETDEV_BOND_ARP_TARGETS_MAX);
return 0;
}
diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c
index fd6af7e99b..2eeb86a683 100644
--- a/src/network/networkd-netdev-bridge.c
+++ b/src/network/networkd-netdev-bridge.c
@@ -20,12 +20,96 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <net/if.h>
#include "networkd-netdev-bridge.h"
#include "missing.h"
+#include "netlink-util.h"
+
+/* callback for brige netdev's parameter set */
+static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ _cleanup_netdev_unref_ NetDev *netdev = userdata;
+ int r;
+
+ assert(netdev);
+ assert(m);
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0) {
+ log_netdev_warning_errno(netdev, r, "Bridge parameters could not be set: %m");
+ return 1;
+ }
+
+ log_netdev_debug(netdev, "Bridge parametres set success");
+
+ return 1;
+}
+
+static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
+ _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
+ Bridge *b;
+ int r;
+
+ assert(netdev);
+
+ b = BRIDGE(netdev);
+
+ assert(b);
+
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, netdev->ifindex);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
+
+ r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set netlink flags: %m");
+
+ r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_PROTINFO attribute: %m");
+
+ r = sd_netlink_message_open_container_union(req, 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 (b->forward_delay > 0) {
+ r = sd_netlink_message_append_u32(req, IFLA_BR_FORWARD_DELAY, b->forward_delay / USEC_PER_SEC);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_FORWARD_DELAY attribute: %m");
+ }
+
+ if (b->hello_time > 0) {
+ r = sd_netlink_message_append_u32(req, IFLA_BR_HELLO_TIME, b->hello_time / USEC_PER_SEC );
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_HELLO_TIME attribute: %m");
+ }
+
+ if (b->max_age > 0) {
+ r = sd_netlink_message_append_u32(req, IFLA_BR_MAX_AGE, b->max_age / USEC_PER_SEC);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m");
+ }
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+ r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, netdev, 0, NULL);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
+
+ netdev_ref(netdev);
+
+ return r;
+}
const NetDevVTable bridge_vtable = {
.object_size = sizeof(Bridge),
- .sections = "Match\0NetDev\0",
+ .sections = "Match\0NetDev\0Bridge\0",
+ .post_create = netdev_bridge_post_create,
.create_type = NETDEV_CREATE_MASTER,
};
diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h
index a7d02b1c91..d3bd15e0d6 100644
--- a/src/network/networkd-netdev-bridge.h
+++ b/src/network/networkd-netdev-bridge.h
@@ -27,6 +27,10 @@ typedef struct Bridge Bridge;
struct Bridge {
NetDev meta;
+
+ usec_t forward_delay;
+ usec_t hello_time;
+ usec_t max_age;
};
extern const NetDevVTable bridge_vtable;
diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
index e0bd0e024a..4aac239850 100644
--- a/src/network/networkd-netdev-gperf.gperf
+++ b/src/network/networkd-netdev-gperf.gperf
@@ -86,3 +86,6 @@ Bond.UpDelaySec, config_parse_sec, 0,
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)
+Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time)
+Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age)
+Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c
index a906e473b6..c9b7fa96e2 100644
--- a/src/network/networkd-netdev-tunnel.c
+++ b/src/network/networkd-netdev-tunnel.c
@@ -395,12 +395,12 @@ int config_parse_tunnel_address(const char *unit,
r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
return 0;
}
if (t->family != AF_UNSPEC && t->family != f) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
return 0;
}
@@ -435,13 +435,14 @@ int config_parse_ipv6_flowlabel(const char* unit,
t->flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
} else {
r = config_parse_int(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &k, userdata);
- if (r >= 0) {
- if (k > 0xFFFFF)
- log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue);
- else {
- *ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL;
- t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
- }
+ if (r < 0)
+ return r;
+
+ if (k > 0xFFFFF)
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue);
+ else {
+ *ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL;
+ t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
}
}
@@ -471,13 +472,12 @@ int config_parse_encap_limit(const char* unit,
else {
r = safe_atoi(rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse Tunnel Encapsulation Limit option, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Tunnel Encapsulation Limit option, ignoring: %s", rvalue);
return 0;
}
if (k > 255 || k < 0)
- log_syntax(unit, LOG_ERR, filename, line, k, "Invalid Tunnel Encapsulation value, ignoring: %d", k);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid Tunnel Encapsulation value, ignoring: %d", k);
else {
t->encap_limit = k;
t->flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c
index 2518e2732b..03a599c0d4 100644
--- a/src/network/networkd-netdev-vxlan.c
+++ b/src/network/networkd-netdev-vxlan.c
@@ -131,14 +131,12 @@ int config_parse_vxlan_group_address(const char *unit,
r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue);
return 0;
}
- if(v->family != AF_UNSPEC && v->family != f) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "vxlan multicast group incompatible, ignoring assignment: %s", rvalue);
+ if (v->family != AF_UNSPEC && v->family != f) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "vxlan multicast group incompatible, ignoring assignment: %s", rvalue);
return 0;
}
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index ff1edf2c39..3d4865a780 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -245,6 +245,9 @@ static int netdev_enter_ready(NetDev *netdev) {
free(callback);
}
+ if (NETDEV_VTABLE(netdev)->post_create)
+ NETDEV_VTABLE(netdev)->post_create(netdev, NULL, NULL);
+
return 0;
}
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
index 1f8510c4f7..3b9ab27b67 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/networkd-netdev.h
@@ -141,6 +141,9 @@ struct NetDevVTable {
/* create netdev, if not done via rtnl */
int (*create)(NetDev *netdev);
+ /* perform additional configuration after netdev has been createad */
+ int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
+
/* verify that compulsory configuration options were specified */
int (*config_verify)(NetDev *netdev, const char *filename);
};
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 8257ab45da..b6f70e191d 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -61,6 +61,7 @@ Route.Destination, config_parse_destination,
Route.Source, config_parse_destination, 0, 0
Route.Metric, config_parse_route_priority, 0, 0
Route.Scope, config_parse_route_scope, 0, 0
+Route.PreferredSource, config_parse_preferred_src, 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)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 57495b58e0..5d22598fc0 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -409,21 +409,18 @@ int config_parse_netdev(const char *unit,
kind = netdev_kind_from_string(kind_string);
if (kind == _NETDEV_KIND_INVALID) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Invalid NetDev kind: %s", lvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid NetDev kind: %s", lvalue);
return 0;
}
r = netdev_get(network->manager, rvalue, &netdev);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "%s could not be found, ignoring assignment: %s", lvalue, rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "%s could not be found, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
if (netdev->kind != kind) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "NetDev is not a %s, ignoring assignment: %s", lvalue, rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "NetDev is not a %s, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
@@ -443,9 +440,7 @@ int config_parse_netdev(const char *unit,
case NETDEV_KIND_VXLAN:
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: %m",
- rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Can not add VLAN '%s' to network: %m", rvalue);
return 0;
}
@@ -484,7 +479,7 @@ int config_parse_domains(const char *unit,
STRV_FOREACH(domain, *domains) {
if (is_localhost(*domain))
- log_syntax(unit, LOG_ERR, filename, line, EINVAL, "'localhost' domain names may not be configured, ignoring assignment: %s", *domain);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "'localhost' domain names may not be configured, ignoring assignment: %s", *domain);
else {
r = dns_name_is_valid(*domain);
if (r <= 0 && !streq(*domain, "*")) {
@@ -540,7 +535,7 @@ int config_parse_tunnel(const char *unit,
netdev->kind != NETDEV_KIND_VTI6 &&
netdev->kind != NETDEV_KIND_IP6TNL
) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ log_syntax(unit, LOG_ERR, filename, line, 0,
"NetDev is not a tunnel, ignoring assignment: %s", rvalue);
return 0;
}
@@ -625,7 +620,7 @@ int config_parse_dhcp(
else if (streq(rvalue, "both"))
s = ADDRESS_FAMILY_YES;
else {
- log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse DHCP option, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DHCP option, ignoring: %s", rvalue);
return 0;
}
}
@@ -670,13 +665,13 @@ int config_parse_ipv6token(
}
r = in_addr_is_null(AF_INET6, &buffer);
- if (r < 0) {
+ if (r != 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "IPv6 token can not be the ANY address, ignoring: %s", rvalue);
return 0;
}
if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL, "IPv6 token can not be longer than 64 bits, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "IPv6 token can not be longer than 64 bits, ignoring: %s", rvalue);
return 0;
}
@@ -730,7 +725,7 @@ int config_parse_ipv6_privacy_extensions(
if (streq(rvalue, "kernel"))
s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
else {
- log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
return 0;
}
}
@@ -765,7 +760,7 @@ int config_parse_hostname(
return r;
if (!hostname_is_valid(hn, false)) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Hostname is not valid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Hostname is not valid, ignoring assignment: %s", rvalue);
free(hn);
return 0;
}
@@ -799,7 +794,7 @@ int config_parse_timezone(
return r;
if (!timezone_is_valid(tz)) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Timezone is not valid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Timezone is not valid, ignoring assignment: %s", rvalue);
free(tz);
return 0;
}
@@ -844,7 +839,7 @@ int config_parse_dhcp_server_dns(
return 0;
if (inet_pton(AF_INET, w, &a) <= 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server address, ignoring: %s", w);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DNS server address, ignoring: %s", w);
continue;
}
@@ -883,7 +878,7 @@ int config_parse_dhcp_server_ntp(
r = extract_first_word(&p, &w, NULL, 0);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, r, line, "Failed to extract word, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
return 0;
}
@@ -891,7 +886,7 @@ int config_parse_dhcp_server_ntp(
return 0;
if (inet_pton(AF_INET, w, &a) <= 0) {
- log_syntax(unit, LOG_ERR, filename, r, line, "Failed to parse NTP server address, ignoring: %s", w);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse NTP server address, ignoring: %s", w);
continue;
}
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index fbaad40579..ee1ddd81fe 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -294,8 +294,7 @@ int config_parse_gateway(const char *unit,
r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Route is invalid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Route is invalid, ignoring assignment: %s", rvalue);
return 0;
}
@@ -306,6 +305,46 @@ int config_parse_gateway(const char *unit,
return 0;
}
+int config_parse_preferred_src(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_route_free_ Route *n = NULL;
+ union in_addr_union buffer;
+ int r, f;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = route_new_static(network, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = in_addr_from_string_auto(rvalue, &f, &buffer);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Preferred source is invalid, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ n->family = f;
+ n->prefsrc_addr = buffer;
+ n = NULL;
+
+ return 0;
+}
+
int config_parse_destination(const char *unit,
const char *filename,
unsigned line,
@@ -345,14 +384,12 @@ int config_parse_destination(const char *unit,
r = in_addr_from_string_auto(address, &f, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Destination is invalid, ignoring assignment: %s", address);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Destination is invalid, ignoring assignment: %s", address);
return 0;
}
if (f != AF_INET && f != AF_INET6) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Unknown address family, ignoring assignment: %s", address);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown address family, ignoring assignment: %s", address);
return 0;
}
@@ -360,8 +397,7 @@ int config_parse_destination(const char *unit,
if (e) {
r = safe_atou8(e + 1, &prefixlen);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Route destination prefix length is invalid, ignoring assignment: %s", e + 1);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Route destination prefix length is invalid, ignoring assignment: %s", e + 1);
return 0;
}
} else {
@@ -456,8 +492,7 @@ int config_parse_route_scope(const char *unit,
else if (streq(rvalue, "global"))
n->scope = RT_SCOPE_UNIVERSE;
else {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Unknown route scope: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown route scope: %s", rvalue);
return 0;
}
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index d090b9c91e..11e94d44fb 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -55,6 +55,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
#define _cleanup_route_free_ _cleanup_(route_freep)
int config_parse_gateway(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_preferred_src(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_destination(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_route_priority(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_route_scope(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-util.c b/src/network/networkd-util.c
index a41cd86239..dde6b327ed 100644
--- a/src/network/networkd-util.c
+++ b/src/network/networkd-util.c
@@ -82,7 +82,7 @@ int config_parse_address_family_boolean_with_kernel(
if (streq(rvalue, "kernel"))
s = _ADDRESS_FAMILY_BOOLEAN_INVALID;
else {
- log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse IPForwarding= option, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPForwarding= option, ignoring: %s", rvalue);
return 0;
}
}
@@ -133,7 +133,7 @@ int config_parse_resolve(
s = resolve_support_from_string(rvalue);
if (s < 0){
- log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse %s= option, ignoring: %s", lvalue, rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse %s= option, ignoring: %s", lvalue, rvalue);
return 0;
}
diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
index d958b48771..3220c4b7ef 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/networkd-wait-online.c
@@ -21,10 +21,10 @@
#include <getopt.h>
#include "sd-daemon.h"
-#include "strv.h"
-#include "build.h"
-#include "signal-util.h"
+
#include "networkd-wait-online.h"
+#include "signal-util.h"
+#include "strv.h"
static bool arg_quiet = false;
static usec_t arg_timeout = 120 * USEC_PER_SEC;
@@ -79,9 +79,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'i':
if (strv_extend(&arg_interfaces, optarg) < 0)