/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/* Make sure the net/if.h header is included before any linux/ one */
+#include <net/if.h>
#include <arpa/inet.h>
#include <getopt.h>
#include <linux/if_addrlabel.h>
-#include <net/if.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "glob-util.h"
#include "hwdb-util.h"
#include "ipvlan-util.h"
+#include "journal-internal.h"
#include "local-addresses.h"
#include "locale-util.h"
#include "logs-show.h"
STATIC_DESTRUCTOR_REGISTER(arg_drop_in, freep);
static int varlink_connect_networkd(Varlink **ret_varlink) {
- _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+ _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
JsonVariant *reply;
uint64_t id;
int r;
if (r < 0)
return log_error_errno(r, "Failed to connect to network service /run/systemd/netif/io.systemd.Network: %m");
+ (void) varlink_set_description(vl, "varlink-network");
+
+ r = varlink_set_allow_fd_passing_output(vl, true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allow passing file descriptor through varlink: %m");
+
r = varlink_call_and_log(vl, "io.systemd.Network.GetNamespaceId", /* parameters= */ NULL, &reply);
if (r < 0)
return r;
}
if (type != RTM_NEWNEIGH) {
- log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Got unexpected netlink message type %u, ignoring",
- type);
+ log_error("Got unexpected netlink message type %u, ignoring.", type);
continue;
}
}
if (fam != family) {
- log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Got invalid rtnl family %d, ignoring", fam);
+ log_error("Got invalid rtnl family %d, ignoring.", fam);
continue;
}
break;
default:
- continue;
+ assert_not_reached();
}
if (!in_addr_equal(fam, &gw, gateway))
r = strv_extendf(&buf, "%s%s%s%s%s%s",
IN_ADDR_TO_STRING(local->family, &local->address),
- dhcp4 ? " (DHCP4 via " : "",
+ dhcp4 ? " (DHCPv4 via " : "",
dhcp4 ? IN4_ADDR_TO_STRING(&server_address) : "",
dhcp4 ? ")" : "",
ifindex <= 0 ? " on " : "",
return log_error_errno(r, "Failed to add boot matches: %m");
if (info) {
- char m1[STRLEN("_KERNEL_DEVICE=n") + DECIMAL_STR_MAX(int)];
- const char *m2, *m3;
-
- /* kernel */
- xsprintf(m1, "_KERNEL_DEVICE=n%i", info->ifindex);
- /* networkd */
- m2 = strjoina("INTERFACE=", info->name);
- /* udevd */
- m3 = strjoina("DEVICE=", info->name);
-
- (void)(
- (r = sd_journal_add_match(j, m1, 0)) ||
+ (void) (
+ (r = journal_add_matchf(j, "_KERNEL_DEVICE=n%i", info->ifindex)) || /* kernel */
(r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, m2, 0)) ||
+ (r = journal_add_match_pair(j, "INTERFACE", info->name)) || /* networkd */
(r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, m3, 0))
+ (r = journal_add_match_pair(j, "DEVICE", info->name)) /* udevd */
);
if (r < 0)
return log_error_errno(r, "Failed to add link matches: %m");
r = sd_dhcp_client_id_to_string(client_id, &id);
if (r >= 0) {
r = table_add_many(table,
- TABLE_FIELD, "DHCP4 Client ID",
+ TABLE_FIELD, "DHCPv4 Client ID",
TABLE_STRING, id);
if (r < 0)
return table_log_add_error(r);
r = sd_network_link_get_dhcp6_client_iaid_string(info->ifindex, &iaid);
if (r >= 0) {
r = table_add_many(table,
- TABLE_FIELD, "DHCP6 Client IAID",
+ TABLE_FIELD, "DHCPv6 Client IAID",
TABLE_STRING, iaid);
if (r < 0)
return table_log_add_error(r);
r = sd_network_link_get_dhcp6_client_duid_string(info->ifindex, &duid);
if (r >= 0) {
r = table_add_many(table,
- TABLE_FIELD, "DHCP6 Client DUID",
+ TABLE_FIELD, "DHCPv6 Client DUID",
TABLE_STRING, duid);
if (r < 0)
return table_log_add_error(r);
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
_cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
- _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+ _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
_cleanup_(link_info_array_freep) LinkInfo *links = NULL;
int r, c;
}
static int link_lldp_status(int argc, char *argv[], void *userdata) {
- _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+ _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
JsonVariant *reply;
uint64_t all = 0;
return 0;
}
+static int verb_persistent_storage(int argc, char *argv[], void *userdata) {
+ _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
+ bool ready;
+ int r;
+
+ r = parse_boolean(argv[1]);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse argument: %s", argv[1]);
+ ready = r;
+
+ r = varlink_connect_networkd(&vl);
+ if (r < 0)
+ return r;
+
+ if (ready) {
+ _cleanup_close_ int fd = -EBADF;
+
+ fd = open("/var/lib/systemd/network/", O_CLOEXEC | O_DIRECTORY);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to open /var/lib/systemd/network/: %m");
+
+ r = varlink_push_fd(vl, fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to push file descriptor of /var/lib/systemd/network/ into varlink: %m");
+
+ TAKE_FD(fd);
+ }
+
+ return varlink_callb_and_log(vl, "io.systemd.Network.SetPersistentStorage", /* reply = */ NULL,
+ JSON_BUILD_OBJECT(JSON_BUILD_PAIR_BOOLEAN("Ready", ready)));
+}
+
static int help(void) {
_cleanup_free_ char *link = NULL;
int r;
" reconfigure DEVICES... Reconfigure interfaces\n"
" reload Reload .network and .netdev files\n"
" edit FILES|DEVICES... Edit network configuration files\n"
- " cat FILES|DEVICES... Show network configuration files\n"
+ " cat [FILES|DEVICES...] Show network configuration files\n"
" mask FILES... Mask network configuration files\n"
" unmask FILES... Unmask network configuration files\n"
+ " persistent-storage BOOL\n"
+ " Notify systemd-networkd if persistent storage is ready\n"
"\nOptions:\n"
" -h --help Show this help\n"
" --version Show package version\n"
static int networkctl_main(int argc, char *argv[]) {
static const Verb verbs[] = {
- { "list", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_links },
- { "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, link_status },
- { "lldp", VERB_ANY, VERB_ANY, 0, link_lldp_status },
- { "label", 1, 1, 0, list_address_labels },
- { "delete", 2, VERB_ANY, 0, link_delete },
- { "up", 2, VERB_ANY, 0, link_up_down },
- { "down", 2, VERB_ANY, 0, link_up_down },
- { "renew", 2, VERB_ANY, VERB_ONLINE_ONLY, link_renew },
- { "forcerenew", 2, VERB_ANY, VERB_ONLINE_ONLY, link_force_renew },
- { "reconfigure", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_reconfigure },
- { "reload", 1, 1, VERB_ONLINE_ONLY, verb_reload },
- { "edit", 2, VERB_ANY, 0, verb_edit },
- { "cat", 2, VERB_ANY, 0, verb_cat },
- { "mask", 2, VERB_ANY, 0, verb_mask },
- { "unmask", 2, VERB_ANY, 0, verb_unmask },
+ { "list", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_links },
+ { "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, link_status },
+ { "lldp", VERB_ANY, VERB_ANY, 0, link_lldp_status },
+ { "label", 1, 1, 0, list_address_labels },
+ { "delete", 2, VERB_ANY, 0, link_delete },
+ { "up", 2, VERB_ANY, 0, link_up_down },
+ { "down", 2, VERB_ANY, 0, link_up_down },
+ { "renew", 2, VERB_ANY, VERB_ONLINE_ONLY, link_renew },
+ { "forcerenew", 2, VERB_ANY, VERB_ONLINE_ONLY, link_force_renew },
+ { "reconfigure", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_reconfigure },
+ { "reload", 1, 1, VERB_ONLINE_ONLY, verb_reload },
+ { "edit", 2, VERB_ANY, 0, verb_edit },
+ { "cat", 1, VERB_ANY, 0, verb_cat },
+ { "mask", 2, VERB_ANY, 0, verb_mask },
+ { "unmask", 2, VERB_ANY, 0, verb_unmask },
+ { "persistent-storage", 2, 2, 0, verb_persistent_storage },
{}
};