networkctl: load information about DHCP client from varlink
By the previous commit, networkd now exposes the received DHCP message in the Descibe() DBus/Varlink method. Let's make networkctl deserialize the DHCP message and use it where necessary.
This commit is contained in:
@@ -131,6 +131,7 @@ networkctl_sources = files(
|
||||
'networkctl-dump-util.c',
|
||||
'networkctl-journal.c',
|
||||
'networkctl-link-info.c',
|
||||
'networkctl-link-info-json.c',
|
||||
'networkctl-list.c',
|
||||
'networkctl-lldp.c',
|
||||
'networkctl-misc.c',
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dhcp-protocol.h"
|
||||
#include "ether-addr-util.h"
|
||||
#include "format-ifname.h"
|
||||
#include "format-table.h"
|
||||
@@ -210,13 +211,14 @@ int dump_gateways(sd_netlink *rtnl, sd_hwdb *hwdb, Table *table, int ifindex) {
|
||||
|
||||
int dump_addresses(
|
||||
sd_netlink *rtnl,
|
||||
sd_dhcp_message *message,
|
||||
sd_dhcp_lease *lease,
|
||||
Table *table,
|
||||
int ifindex) {
|
||||
|
||||
_cleanup_free_ struct local_address *local_addrs = NULL;
|
||||
_cleanup_strv_free_ char **buf = NULL;
|
||||
struct in_addr dhcp4_address = {};
|
||||
struct in_addr dhcp4_address = {}, server_address = {};
|
||||
int r, n;
|
||||
|
||||
assert(rtnl);
|
||||
@@ -226,15 +228,18 @@ int dump_addresses(
|
||||
if (n <= 0)
|
||||
return n;
|
||||
|
||||
if (lease)
|
||||
if (message) {
|
||||
dhcp4_address.s_addr = message->header.yiaddr;
|
||||
if (dhcp_message_get_option_address(message, SD_DHCP_OPTION_SERVER_IDENTIFIER, &server_address) < 0)
|
||||
/* The message should be BOOTP, let's fallback to the siaddr field. */
|
||||
server_address.s_addr = message->header.siaddr;
|
||||
} else if (lease) {
|
||||
(void) sd_dhcp_lease_get_address(lease, &dhcp4_address);
|
||||
(void) sd_dhcp_lease_get_server_identifier(lease, &server_address);
|
||||
}
|
||||
|
||||
FOREACH_ARRAY(local, local_addrs, n) {
|
||||
struct in_addr server_address;
|
||||
bool dhcp4 = false;
|
||||
|
||||
if (local->family == AF_INET && in4_addr_equal(&local->address.in, &dhcp4_address))
|
||||
dhcp4 = sd_dhcp_lease_get_server_identifier(lease, &server_address) >= 0;
|
||||
bool dhcp4 = local->family == AF_INET && in4_addr_equal(&local->address.in, &dhcp4_address);
|
||||
|
||||
r = strv_extendf(&buf, "%s%s%s%s%s%s",
|
||||
IN_ADDR_TO_STRING(local->family, &local->address),
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
#include "shared-forward.h"
|
||||
|
||||
#include "dhcp-message.h"
|
||||
|
||||
int dump_list(Table *table, const char *key, char * const *l);
|
||||
int ieee_oui(sd_hwdb *hwdb, const struct ether_addr *mac, char **ret);
|
||||
int dump_gateways(sd_netlink *rtnl, sd_hwdb *hwdb, Table *table, int ifindex);
|
||||
int dump_addresses(sd_netlink *rtnl, sd_dhcp_lease *lease, Table *table, int ifindex);
|
||||
int dump_addresses(sd_netlink *rtnl, sd_dhcp_message *message, sd_dhcp_lease *lease, Table *table, int ifindex);
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-dhcp-client-id.h"
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "iovec-util.h"
|
||||
#include "json-util.h"
|
||||
#include "networkctl-link-info.h"
|
||||
#include "networkctl-link-info-json.h"
|
||||
#include "networkctl-util.h"
|
||||
|
||||
static int acquire_link_bitrates(LinkInfo *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
sd_json_variant *v;
|
||||
r = json_variant_find_object(link->description, STRV_MAKE("Interface", "BitRates"), &v);
|
||||
if (r == -ENODATA)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "TxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, tx_bitrate), SD_JSON_MANDATORY },
|
||||
{ "RxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, rx_bitrate), SD_JSON_MANDATORY },
|
||||
{}
|
||||
};
|
||||
|
||||
r = sd_json_dispatch(v, dispatch_table,
|
||||
SD_JSON_LOG | SD_JSON_WARNING | SD_JSON_ALLOW_EXTENSIONS,
|
||||
link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link->has_bitrates = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acquire_link_dhcp_client(LinkInfo *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
sd_json_variant *v;
|
||||
r = json_variant_find_object(link->description, STRV_MAKE("Interface", "DHCPv4Client", "ClientIdentifier"), &v);
|
||||
if (r == -ENODATA)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_(iovec_done) struct iovec iov = {};
|
||||
r = json_dispatch_byte_array_iovec("ClientIdentifier", v, /* flags= */ 0, &iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_dhcp_client_id_set_raw(&link->dhcp_client_id, iov.iov_base, iov.iov_len);
|
||||
}
|
||||
|
||||
static int acquire_link_dhcp_message(LinkInfo *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
sd_json_variant *v;
|
||||
r = json_variant_find_object(link->description, STRV_MAKE("Interface", "DHCPv4Client", "Lease", "Message"), &v);
|
||||
if (r == -ENODATA)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dhcp_message_parse_json(v, &link->dhcp_message);
|
||||
}
|
||||
|
||||
int link_info_parse_description(LinkInfo *link, sd_varlink *vl) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
if (!vl)
|
||||
return 0;
|
||||
|
||||
r = acquire_link_description(vl, link->ifindex, &link->description);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) acquire_link_bitrates(link);
|
||||
(void) acquire_link_dhcp_client(link);
|
||||
(void) acquire_link_dhcp_message(link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "shared-forward.h"
|
||||
|
||||
typedef struct LinkInfo LinkInfo;
|
||||
|
||||
int link_info_parse_description(LinkInfo *link, sd_varlink *vl);
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "glob-util.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkctl-link-info.h"
|
||||
#include "networkctl-util.h"
|
||||
#include "networkctl-link-info-json.h"
|
||||
#include "sort-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
@@ -26,6 +26,7 @@ LinkInfo* link_info_array_free(LinkInfo *array) {
|
||||
for (unsigned i = 0; array && array[i].needs_freeing; i++) {
|
||||
sd_device_unref(array[i].sd_device);
|
||||
sd_json_variant_unref(array[i].description);
|
||||
sd_dhcp_message_unref(array[i].dhcp_message);
|
||||
free(array[i].netdev_kind);
|
||||
free(array[i].ssid);
|
||||
free(array[i].qdisc);
|
||||
@@ -278,34 +279,6 @@ static int decode_link(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int acquire_link_bitrates(LinkInfo *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
sd_json_variant *v;
|
||||
r = json_variant_find_object(link->description, STRV_MAKE("Interface", "BitRates"), &v);
|
||||
if (r == -ENODATA)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "TxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, tx_bitrate), SD_JSON_MANDATORY },
|
||||
{ "RxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, rx_bitrate), SD_JSON_MANDATORY },
|
||||
{}
|
||||
};
|
||||
|
||||
r = sd_json_dispatch(v, dispatch_table,
|
||||
SD_JSON_LOG | SD_JSON_WARNING | SD_JSON_ALLOW_EXTENSIONS,
|
||||
link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link->has_bitrates = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acquire_ether_link_info(int *fd, LinkInfo *link) {
|
||||
assert(fd);
|
||||
assert(link);
|
||||
@@ -398,9 +371,7 @@ int acquire_link_info(sd_varlink *vl, sd_netlink *rtnl, char * const *patterns,
|
||||
acquire_ether_link_info(&fd, &links[c]);
|
||||
acquire_wlan_link_info(&links[c]);
|
||||
|
||||
if (vl)
|
||||
(void) acquire_link_description(vl, links[c].ifindex, &links[c].description);
|
||||
(void) acquire_link_bitrates(&links[c]);
|
||||
(void) link_info_parse_description(&links[c], vl);
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
#include "dhcp-client-id-internal.h"
|
||||
#include "dhcp-message.h"
|
||||
#include "ether-addr-util.h"
|
||||
#include "ethtool-util.h"
|
||||
#include "shared-forward.h"
|
||||
@@ -58,6 +60,10 @@ typedef struct LinkInfo {
|
||||
uint64_t tx_bitrate;
|
||||
uint64_t rx_bitrate;
|
||||
|
||||
/* DHCPv4 */
|
||||
sd_dhcp_message *dhcp_message;
|
||||
sd_dhcp_client_id dhcp_client_id;
|
||||
|
||||
/* bridge info */
|
||||
uint32_t forward_delay;
|
||||
uint32_t hello_time;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "sd-device.h"
|
||||
#include "sd-dhcp-client-id.h"
|
||||
#include "sd-dhcp-lease.h"
|
||||
#include "sd-dhcp-protocol.h"
|
||||
#include "sd-hwdb.h"
|
||||
#include "sd-netlink.h"
|
||||
#include "sd-network.h"
|
||||
@@ -779,7 +780,7 @@ static int link_status_one(
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dump_addresses(rtnl, lease, table, info->ifindex);
|
||||
r = dump_addresses(rtnl, info->dhcp_message, lease, table, info->ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -837,8 +838,18 @@ static int link_status_one(
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
if (lease) {
|
||||
const sd_dhcp_client_id *client_id;
|
||||
if (info->dhcp_message) {
|
||||
_cleanup_free_ char *tz = NULL;
|
||||
|
||||
if (dhcp_message_get_option_string(info->dhcp_message, SD_DHCP_OPTION_TZDB_TIMEZONE, &tz) >= 0
|
||||
&& timezone_is_valid(tz, LOG_DEBUG)) {
|
||||
r = table_add_many(table,
|
||||
TABLE_FIELD, "Time Zone",
|
||||
TABLE_STRING, tz);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
} else if (lease) {
|
||||
const char *tz;
|
||||
|
||||
r = sd_dhcp_lease_get_timezone(lease, &tz);
|
||||
@@ -849,19 +860,18 @@ static int link_status_one(
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_client_id(lease, &client_id);
|
||||
if (sd_dhcp_client_id_is_set(&info->dhcp_client_id)) {
|
||||
_cleanup_free_ char *id = NULL;
|
||||
|
||||
r = sd_dhcp_client_id_to_string(&info->dhcp_client_id, &id);
|
||||
if (r >= 0) {
|
||||
_cleanup_free_ char *id = NULL;
|
||||
|
||||
r = sd_dhcp_client_id_to_string(client_id, &id);
|
||||
if (r >= 0) {
|
||||
r = table_add_many(table,
|
||||
TABLE_FIELD, "DHCPv4 Client ID",
|
||||
TABLE_STRING, id);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
r = table_add_many(table,
|
||||
TABLE_FIELD, "DHCPv4 Client ID",
|
||||
TABLE_STRING, id);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
r = dump_addresses(rtnl, NULL, table, 0);
|
||||
r = dump_addresses(rtnl, /* message= */ NULL, /* lease= */ NULL, table, /* ifindex= */ 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user