mirror of
https://github.com/systemd/systemd
synced 2026-03-15 09:34:47 +01:00
Compare commits
No commits in common. "893e3ffe7d25b182713998a42dbcd4d200ab6fcf" and "cbdc29492097e24ef3320280bc2a8dedbce02d9a" have entirely different histories.
893e3ffe7d
...
cbdc294920
@ -367,7 +367,6 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<xi:include href="standard-options.xml" xpointer="json" />
|
|
||||||
<xi:include href="standard-options.xml" xpointer="help" />
|
<xi:include href="standard-options.xml" xpointer="help" />
|
||||||
<xi:include href="standard-options.xml" xpointer="version" />
|
<xi:include href="standard-options.xml" xpointer="version" />
|
||||||
<xi:include href="standard-options.xml" xpointer="no-legend" />
|
<xi:include href="standard-options.xml" xpointer="no-legend" />
|
||||||
|
|||||||
@ -25,38 +25,11 @@ __contains_word () {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
__get_machines() {
|
|
||||||
local a b
|
|
||||||
machinectl list --full --no-legend --no-pager 2>/dev/null |
|
|
||||||
{ while read a b; do echo " $a"; done; };
|
|
||||||
}
|
|
||||||
|
|
||||||
_hostnamectl() {
|
_hostnamectl() {
|
||||||
local i verb comps
|
local i verb comps
|
||||||
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||||
local -A OPTS=(
|
local OPTS='-h --help --version --transient --static --pretty
|
||||||
[STANDALONE]='-h --help --version --transient --static --pretty --no-ask-password'
|
--no-ask-password -H --host -M --machine'
|
||||||
[ARG]='-H --host -M --machine --json'
|
|
||||||
)
|
|
||||||
|
|
||||||
if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then
|
|
||||||
case $prev in
|
|
||||||
--host|-H)
|
|
||||||
comps=$(compgen -A hostname)
|
|
||||||
;;
|
|
||||||
--machine|-M)
|
|
||||||
comps=$( __get_machines )
|
|
||||||
;;
|
|
||||||
--json)
|
|
||||||
comps=$( hostnamectl --json=help 2>/dev/null )
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $cur = -* ]]; then
|
if [[ $cur = -* ]]; then
|
||||||
COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
|
COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
|
||||||
|
|||||||
@ -33,7 +33,7 @@ _networkctl() {
|
|||||||
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
|
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
|
||||||
local -A OPTS=(
|
local -A OPTS=(
|
||||||
[STANDALONE]='-a --all -h --help --version --no-pager --no-legend -s --stats -l --full'
|
[STANDALONE]='-a --all -h --help --version --no-pager --no-legend -s --stats -l --full'
|
||||||
[ARG]='-n --lines --json'
|
[ARG]='-n --lines'
|
||||||
)
|
)
|
||||||
|
|
||||||
local -A VERBS=(
|
local -A VERBS=(
|
||||||
@ -51,19 +51,6 @@ _networkctl() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if __contains_word "$prev" ${OPTS[ARG]}; then
|
|
||||||
case $prev in
|
|
||||||
--json)
|
|
||||||
comps=$(networkctl --json=help | sort 2>/dev/null)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$cur" = -* ]]; then
|
if [[ "$cur" = -* ]]; then
|
||||||
COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
|
COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@ -75,13 +75,6 @@ _hostnamectl_commands() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
(( $+functions[_hostnamectl_get_json] )) || _hostnamectl_get_json()
|
|
||||||
{
|
|
||||||
local -a _json_forms
|
|
||||||
_json_forms=( $(hostnamectl --json=help 2>/dev/null) )
|
|
||||||
_values 'format' $_json_forms
|
|
||||||
}
|
|
||||||
|
|
||||||
_arguments -s \
|
_arguments -s \
|
||||||
{-h,--help}'[Show this help]' \
|
{-h,--help}'[Show this help]' \
|
||||||
'--version[Show package version]' \
|
'--version[Show package version]' \
|
||||||
@ -91,5 +84,4 @@ _arguments -s \
|
|||||||
'--no-ask-password[Do not prompt for password]' \
|
'--no-ask-password[Do not prompt for password]' \
|
||||||
{-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
|
{-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
|
||||||
{-M+,--machine=}'[Operate on local container]:machines:_sd_machines' \
|
{-M+,--machine=}'[Operate on local container]:machines:_sd_machines' \
|
||||||
'--json[Shows output formatted as JSON]:format:_hostnamectl_get_json' \
|
|
||||||
'*::hostnamectl commands:_hostnamectl_commands'
|
'*::hostnamectl commands:_hostnamectl_commands'
|
||||||
|
|||||||
@ -39,18 +39,10 @@
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
(( $+functions[_networkctl_get_json] )) || _networkctl_get_json()
|
|
||||||
{
|
|
||||||
local -a _json_forms
|
|
||||||
_json_forms=( $(networkctl --json=help 2>/dev/null) )
|
|
||||||
_values 'format' $_json_forms
|
|
||||||
}
|
|
||||||
|
|
||||||
_arguments \
|
_arguments \
|
||||||
{-a,--all}'[Show all links with status]' \
|
{-a,--all}'[Show all links with status]' \
|
||||||
'--no-pager[Do not pipe output into a pager]' \
|
'--no-pager[Do not pipe output into a pager]' \
|
||||||
'--no-legend[Do not print the column headers]' \
|
'--no-legend[Do not print the column headers]' \
|
||||||
{-h,--help}'[Show this help]' \
|
{-h,--help}'[Show this help]' \
|
||||||
'--version[Show package version]' \
|
'--version[Show package version]' \
|
||||||
'--json[Shows output formatted as JSON]:format:_networkctl_get_json' \
|
|
||||||
'*::networkctl commands:_networkctl_commands'
|
'*::networkctl commands:_networkctl_commands'
|
||||||
|
|||||||
@ -119,31 +119,24 @@ int parse_operational_state_range(const char *str, LinkOperationalStateRange *ou
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int link_get_type_string(sd_device *device, unsigned short iftype, char **ret) {
|
char *link_get_type_string(sd_device *device, unsigned short iftype) {
|
||||||
const char *t;
|
const char *t;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if (device &&
|
if (device &&
|
||||||
sd_device_get_devtype(device, &t) >= 0 &&
|
sd_device_get_devtype(device, &t) >= 0 &&
|
||||||
!isempty(t)) {
|
!isempty(t))
|
||||||
p = strdup(t);
|
return strdup(t);
|
||||||
if (!p)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*ret = p;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = arphrd_to_name(iftype);
|
t = arphrd_to_name(iftype);
|
||||||
if (!t)
|
if (!t)
|
||||||
return -ENOENT;
|
return NULL;
|
||||||
|
|
||||||
p = strdup(t);
|
p = strdup(t);
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return NULL;
|
||||||
|
|
||||||
*ret = ascii_strlower(p);
|
return ascii_strlower(p);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *net_get_name_persistent(sd_device *device) {
|
const char *net_get_name_persistent(sd_device *device) {
|
||||||
|
|||||||
@ -76,6 +76,6 @@ typedef struct LinkOperationalStateRange {
|
|||||||
|
|
||||||
int parse_operational_state_range(const char *str, LinkOperationalStateRange *out);
|
int parse_operational_state_range(const char *str, LinkOperationalStateRange *out);
|
||||||
|
|
||||||
int link_get_type_string(sd_device *device, unsigned short iftype, char **ret);
|
char *link_get_type_string(sd_device *device, unsigned short iftype);
|
||||||
int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result);
|
int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result);
|
||||||
const char *net_get_name_persistent(sd_device *device);
|
const char *net_get_name_persistent(sd_device *device);
|
||||||
|
|||||||
@ -79,8 +79,6 @@ sources = files('''
|
|||||||
networkd-ipv4ll.h
|
networkd-ipv4ll.h
|
||||||
networkd-ipv6-proxy-ndp.c
|
networkd-ipv6-proxy-ndp.c
|
||||||
networkd-ipv6-proxy-ndp.h
|
networkd-ipv6-proxy-ndp.h
|
||||||
networkd-json.c
|
|
||||||
networkd-json.h
|
|
||||||
networkd-link-bus.c
|
networkd-link-bus.c
|
||||||
networkd-link-bus.h
|
networkd-link-bus.h
|
||||||
networkd-link.c
|
networkd-link.c
|
||||||
|
|||||||
@ -46,7 +46,6 @@
|
|||||||
#include "network-internal.h"
|
#include "network-internal.h"
|
||||||
#include "network-util.h"
|
#include "network-util.h"
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
#include "parse-argument.h"
|
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
@ -76,110 +75,6 @@ static bool arg_all = false;
|
|||||||
static bool arg_stats = false;
|
static bool arg_stats = false;
|
||||||
static bool arg_full = false;
|
static bool arg_full = false;
|
||||||
static unsigned arg_lines = 10;
|
static unsigned arg_lines = 10;
|
||||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
|
||||||
|
|
||||||
static int get_description(JsonVariant **ret) {
|
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
|
||||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
|
||||||
const char *text = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = sd_bus_open_system(&bus);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to connect system bus: %m");
|
|
||||||
|
|
||||||
r = bus_call_method(bus, bus_network_mgr, "Describe", &error, &reply, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to get description: %s", bus_error_message(&error, r));
|
|
||||||
|
|
||||||
r = sd_bus_message_read(reply, "s", &text);
|
|
||||||
if (r < 0)
|
|
||||||
return bus_log_parse_error(r);
|
|
||||||
|
|
||||||
r = json_parse(text, 0, ret, NULL, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to parse JSON: %m");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dump_manager_description(void) {
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = get_description(&v);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
json_variant_dump(v, arg_json_format_flags, NULL, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dump_link_description(char **patterns) {
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
|
||||||
_cleanup_free_ bool *matched_patterns = NULL;
|
|
||||||
JsonVariant *i;
|
|
||||||
size_t c = 0;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = get_description(&v);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
matched_patterns = new0(bool, strv_length(patterns));
|
|
||||||
if (!matched_patterns)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
JSON_VARIANT_ARRAY_FOREACH(i, json_variant_by_key(v, "Interfaces")) {
|
|
||||||
char ifindex_str[DECIMAL_STR_MAX(intmax_t)];
|
|
||||||
const char *name;
|
|
||||||
intmax_t index;
|
|
||||||
size_t pos;
|
|
||||||
|
|
||||||
name = json_variant_string(json_variant_by_key(i, "Name"));
|
|
||||||
index = json_variant_integer(json_variant_by_key(i, "Index"));
|
|
||||||
xsprintf(ifindex_str, "%ji", index);
|
|
||||||
|
|
||||||
if (!strv_fnmatch_full(patterns, ifindex_str, 0, &pos) &&
|
|
||||||
!strv_fnmatch_full(patterns, name, 0, &pos)) {
|
|
||||||
bool match = false;
|
|
||||||
JsonVariant *a;
|
|
||||||
|
|
||||||
JSON_VARIANT_ARRAY_FOREACH(a, json_variant_by_key(i, "AlternativeNames"))
|
|
||||||
if (strv_fnmatch_full(patterns, json_variant_string(a), 0, &pos)) {
|
|
||||||
match = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!match)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
matched_patterns[pos] = true;
|
|
||||||
json_variant_dump(i, arg_json_format_flags, NULL, NULL);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look if we matched all our arguments that are not globs. It is OK for a glob to match
|
|
||||||
* nothing, but not for an exact argument. */
|
|
||||||
for (size_t pos = 0; pos < strv_length(patterns); pos++) {
|
|
||||||
if (matched_patterns[pos])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (string_is_glob(patterns[pos]))
|
|
||||||
log_debug("Pattern \"%s\" doesn't match any interface, ignoring.",
|
|
||||||
patterns[pos]);
|
|
||||||
else
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENODEV),
|
|
||||||
"Interface \"%s\" not found.", patterns[pos]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == 0)
|
|
||||||
log_warning("No interfaces matched.");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void operational_state_to_color(const char *name, const char *state, const char **on, const char **off) {
|
static void operational_state_to_color(const char *name, const char *state, const char **on, const char **off) {
|
||||||
if (STRPTR_IN_SET(state, "routable", "enslaved") ||
|
if (STRPTR_IN_SET(state, "routable", "enslaved") ||
|
||||||
@ -779,13 +674,6 @@ static int list_links(int argc, char *argv[], void *userdata) {
|
|||||||
TableCell *cell;
|
TableCell *cell;
|
||||||
int c, r;
|
int c, r;
|
||||||
|
|
||||||
if (arg_json_format_flags != JSON_FORMAT_OFF) {
|
|
||||||
if (arg_all || argc <= 1)
|
|
||||||
return dump_manager_description();
|
|
||||||
else
|
|
||||||
return dump_link_description(strv_skip(argv, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_netlink_open(&rtnl);
|
r = sd_netlink_open(&rtnl);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to connect to netlink: %m");
|
return log_error_errno(r, "Failed to connect to netlink: %m");
|
||||||
@ -804,8 +692,6 @@ static int list_links(int argc, char *argv[], void *userdata) {
|
|||||||
table_set_width(table, 0);
|
table_set_width(table, 0);
|
||||||
|
|
||||||
table_set_header(table, arg_legend);
|
table_set_header(table, arg_legend);
|
||||||
if (table_set_empty_string(table, "n/a") < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
assert_se(cell = table_get_cell(table, 0, 0));
|
assert_se(cell = table_get_cell(table, 0, 0));
|
||||||
(void) table_set_minimum_width(table, cell, 3);
|
(void) table_set_minimum_width(table, cell, 3);
|
||||||
@ -829,17 +715,15 @@ static int list_links(int argc, char *argv[], void *userdata) {
|
|||||||
setup_state = strdup("unmanaged");
|
setup_state = strdup("unmanaged");
|
||||||
setup_state_to_color(setup_state, &on_color_setup, NULL);
|
setup_state_to_color(setup_state, &on_color_setup, NULL);
|
||||||
|
|
||||||
r = link_get_type_string(links[i].sd_device, links[i].iftype, &t);
|
t = link_get_type_string(links[i].sd_device, links[i].iftype);
|
||||||
if (r == -ENOMEM)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
r = table_add_many(table,
|
r = table_add_many(table,
|
||||||
TABLE_INT, links[i].ifindex,
|
TABLE_INT, links[i].ifindex,
|
||||||
TABLE_STRING, links[i].name,
|
TABLE_STRING, links[i].name,
|
||||||
TABLE_STRING, t,
|
TABLE_STRING, strna(t),
|
||||||
TABLE_STRING, operational_state,
|
TABLE_STRING, strna(operational_state),
|
||||||
TABLE_SET_COLOR, on_color_operational,
|
TABLE_SET_COLOR, on_color_operational,
|
||||||
TABLE_STRING, setup_state,
|
TABLE_STRING, strna(setup_state),
|
||||||
TABLE_SET_COLOR, on_color_setup);
|
TABLE_SET_COLOR, on_color_setup);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return table_log_add_error(r);
|
return table_log_add_error(r);
|
||||||
@ -1552,9 +1436,7 @@ static int link_status_one(
|
|||||||
(void) sd_device_get_property_value(info->sd_device, "ID_MODEL", &model);
|
(void) sd_device_get_property_value(info->sd_device, "ID_MODEL", &model);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = link_get_type_string(info->sd_device, info->iftype, &t);
|
t = link_get_type_string(info->sd_device, info->iftype);
|
||||||
if (r == -ENOMEM)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
(void) sd_network_link_get_network_file(info->ifindex, &network);
|
(void) sd_network_link_get_network_file(info->ifindex, &network);
|
||||||
|
|
||||||
@ -2350,13 +2232,6 @@ static int link_status(int argc, char *argv[], void *userdata) {
|
|||||||
_cleanup_(link_info_array_freep) LinkInfo *links = NULL;
|
_cleanup_(link_info_array_freep) LinkInfo *links = NULL;
|
||||||
int r, c;
|
int r, c;
|
||||||
|
|
||||||
if (arg_json_format_flags != JSON_FORMAT_OFF) {
|
|
||||||
if (arg_all || argc <= 1)
|
|
||||||
return dump_manager_description();
|
|
||||||
else
|
|
||||||
return dump_link_description(strv_skip(argv, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) pager_open(arg_pager_flags);
|
(void) pager_open(arg_pager_flags);
|
||||||
|
|
||||||
r = sd_bus_open_system(&bus);
|
r = sd_bus_open_system(&bus);
|
||||||
@ -2847,8 +2722,6 @@ static int help(void) {
|
|||||||
" -s --stats Show detailed link statics\n"
|
" -s --stats Show detailed link statics\n"
|
||||||
" -l --full Do not ellipsize output\n"
|
" -l --full Do not ellipsize output\n"
|
||||||
" -n --lines=INTEGER Number of journal entries to show\n"
|
" -n --lines=INTEGER Number of journal entries to show\n"
|
||||||
" --json=pretty|short|off\n"
|
|
||||||
" Generate JSON output\n"
|
|
||||||
"\nSee the %s for details.\n",
|
"\nSee the %s for details.\n",
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
ansi_highlight(),
|
ansi_highlight(),
|
||||||
@ -2864,7 +2737,6 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_VERSION = 0x100,
|
ARG_VERSION = 0x100,
|
||||||
ARG_NO_PAGER,
|
ARG_NO_PAGER,
|
||||||
ARG_NO_LEGEND,
|
ARG_NO_LEGEND,
|
||||||
ARG_JSON,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
@ -2876,11 +2748,10 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "stats", no_argument, NULL, 's' },
|
{ "stats", no_argument, NULL, 's' },
|
||||||
{ "full", no_argument, NULL, 'l' },
|
{ "full", no_argument, NULL, 'l' },
|
||||||
{ "lines", required_argument, NULL, 'n' },
|
{ "lines", required_argument, NULL, 'n' },
|
||||||
{ "json", required_argument, NULL, ARG_JSON },
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
int c, r;
|
int c;
|
||||||
|
|
||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
@ -2921,12 +2792,6 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
"Failed to parse lines '%s'", optarg);
|
"Failed to parse lines '%s'", optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_JSON:
|
|
||||||
r = parse_json_argument(optarg, &arg_json_format_flags);
|
|
||||||
if (r <= 0)
|
|
||||||
return r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|||||||
@ -1,135 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
|
|
||||||
#include "network-util.h"
|
|
||||||
#include "networkd-json.h"
|
|
||||||
#include "networkd-link.h"
|
|
||||||
#include "networkd-manager.h"
|
|
||||||
#include "networkd-network.h"
|
|
||||||
#include "sort-util.h"
|
|
||||||
|
|
||||||
static int network_build_json(Network *network, JsonVariant **ret) {
|
|
||||||
assert(network);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
return json_build(ret, JSON_BUILD_OBJECT(
|
|
||||||
JSON_BUILD_PAIR("NetworkFile", JSON_BUILD_STRING(network->filename))));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int device_build_json(sd_device *device, JsonVariant **ret) {
|
|
||||||
const char *link = NULL, *path = NULL, *vendor = NULL, *model = NULL;
|
|
||||||
|
|
||||||
assert(device);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
(void) sd_device_get_property_value(device, "ID_NET_LINK_FILE", &link);
|
|
||||||
(void) sd_device_get_property_value(device, "ID_PATH", &path);
|
|
||||||
|
|
||||||
if (sd_device_get_property_value(device, "ID_VENDOR_FROM_DATABASE", &vendor) < 0)
|
|
||||||
(void) sd_device_get_property_value(device, "ID_VENDOR", &vendor);
|
|
||||||
|
|
||||||
if (sd_device_get_property_value(device, "ID_MODEL_FROM_DATABASE", &model) < 0)
|
|
||||||
(void) sd_device_get_property_value(device, "ID_MODEL", &model);
|
|
||||||
|
|
||||||
return json_build(ret, JSON_BUILD_OBJECT(
|
|
||||||
JSON_BUILD_PAIR("LinkFile", JSON_BUILD_STRING(link)),
|
|
||||||
JSON_BUILD_PAIR("Path", JSON_BUILD_STRING(path)),
|
|
||||||
JSON_BUILD_PAIR("Vendor", JSON_BUILD_STRING(vendor)),
|
|
||||||
JSON_BUILD_PAIR("Model", JSON_BUILD_STRING(model))));
|
|
||||||
}
|
|
||||||
|
|
||||||
int link_build_json(Link *link, JsonVariant **ret) {
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
|
||||||
_cleanup_free_ char *type = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
r = link_get_type_string(link->sd_device, link->iftype, &type);
|
|
||||||
if (r == -ENOMEM)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = json_build(&v, JSON_BUILD_OBJECT(
|
|
||||||
JSON_BUILD_PAIR("Index", JSON_BUILD_INTEGER(link->ifindex)),
|
|
||||||
JSON_BUILD_PAIR("Name", JSON_BUILD_STRING(link->ifname)),
|
|
||||||
JSON_BUILD_PAIR("AlternativeNames", JSON_BUILD_STRV(link->alternative_names)),
|
|
||||||
JSON_BUILD_PAIR("Type", JSON_BUILD_STRING(type)),
|
|
||||||
JSON_BUILD_PAIR("Driver", JSON_BUILD_STRING(link->driver)),
|
|
||||||
JSON_BUILD_PAIR("SetupState", JSON_BUILD_STRING(link_state_to_string(link->state))),
|
|
||||||
JSON_BUILD_PAIR("OperationalState", JSON_BUILD_STRING(link_operstate_to_string(link->operstate))),
|
|
||||||
JSON_BUILD_PAIR("CarrierState", JSON_BUILD_STRING(link_carrier_state_to_string(link->carrier_state))),
|
|
||||||
JSON_BUILD_PAIR("AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->address_state))),
|
|
||||||
JSON_BUILD_PAIR("IPv4AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->ipv4_address_state))),
|
|
||||||
JSON_BUILD_PAIR("IPv6AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->ipv6_address_state)))));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (link->network) {
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
|
|
||||||
|
|
||||||
r = network_build_json(link->network, &w);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = json_variant_merge(&v, w);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (link->sd_device) {
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
|
|
||||||
|
|
||||||
r = device_build_json(link->sd_device, &w);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = json_variant_merge(&v, w);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(v);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_json_compare(JsonVariant * const *a, JsonVariant * const *b) {
|
|
||||||
intmax_t index_a, index_b;
|
|
||||||
|
|
||||||
assert(a && *a);
|
|
||||||
assert(b && *b);
|
|
||||||
|
|
||||||
index_a = json_variant_integer(json_variant_by_key(*a, "Index"));
|
|
||||||
index_b = json_variant_integer(json_variant_by_key(*b, "Index"));
|
|
||||||
|
|
||||||
return CMP(index_a, index_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
int manager_build_json(Manager *manager, JsonVariant **ret) {
|
|
||||||
JsonVariant **elements;
|
|
||||||
Link *link;
|
|
||||||
size_t n = 0;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(manager);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
elements = new(JsonVariant*, hashmap_size(manager->links));
|
|
||||||
if (!elements)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
HASHMAP_FOREACH(link, manager->links) {
|
|
||||||
r = link_build_json(link, elements + n);
|
|
||||||
if (r < 0)
|
|
||||||
goto finalize;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
typesafe_qsort(elements, n, link_json_compare);
|
|
||||||
|
|
||||||
r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Interfaces", JSON_BUILD_VARIANT_ARRAY(elements, n))));
|
|
||||||
|
|
||||||
finalize:
|
|
||||||
json_variant_unref_many(elements, n);
|
|
||||||
free(elements);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "json.h"
|
|
||||||
|
|
||||||
typedef struct Link Link;
|
|
||||||
typedef struct Manager Manager;
|
|
||||||
|
|
||||||
int link_build_json(Link *link, JsonVariant **ret);
|
|
||||||
int manager_build_json(Manager *manager, JsonVariant **ret);
|
|
||||||
@ -10,7 +10,6 @@
|
|||||||
#include "bus-message-util.h"
|
#include "bus-message-util.h"
|
||||||
#include "bus-polkit.h"
|
#include "bus-polkit.h"
|
||||||
#include "dns-domain.h"
|
#include "dns-domain.h"
|
||||||
#include "networkd-json.h"
|
|
||||||
#include "networkd-link-bus.h"
|
#include "networkd-link-bus.h"
|
||||||
#include "networkd-link.h"
|
#include "networkd-link.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
@ -679,35 +678,6 @@ int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_
|
|||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bus_link_method_describe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
|
||||||
_cleanup_free_ char *text = NULL;
|
|
||||||
Link *link = userdata;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(message);
|
|
||||||
assert(link);
|
|
||||||
|
|
||||||
r = link_build_json(link, &v);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Failed to build JSON data: %m");
|
|
||||||
|
|
||||||
r = json_variant_format(v, 0, &text);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Failed to format JSON data: %m");
|
|
||||||
|
|
||||||
r = sd_bus_message_new_method_return(message, &reply);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_bus_message_append(reply, "s", text);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return sd_bus_send(NULL, reply, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sd_bus_vtable link_vtable[] = {
|
const sd_bus_vtable link_vtable[] = {
|
||||||
SD_BUS_VTABLE_START(0),
|
SD_BUS_VTABLE_START(0),
|
||||||
|
|
||||||
@ -794,11 +764,6 @@ const sd_bus_vtable link_vtable[] = {
|
|||||||
SD_BUS_NO_RESULT,
|
SD_BUS_NO_RESULT,
|
||||||
bus_link_method_reconfigure,
|
bus_link_method_reconfigure,
|
||||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD_WITH_ARGS("Describe",
|
|
||||||
SD_BUS_NO_ARGS,
|
|
||||||
SD_BUS_RESULT("s", json),
|
|
||||||
bus_link_method_describe,
|
|
||||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
|
||||||
|
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END
|
||||||
};
|
};
|
||||||
|
|||||||
@ -34,4 +34,3 @@ int bus_link_method_revert_dns(sd_bus_message *message, void *userdata, sd_bus_e
|
|||||||
int bus_link_method_renew(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
int bus_link_method_renew(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
int bus_link_method_force_renew(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
int bus_link_method_force_renew(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
int bus_link_method_describe(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
|
||||||
|
|||||||
@ -2226,59 +2226,6 @@ static int link_configure_continue(Link *link) {
|
|||||||
return link_enter_join_netdev(link);
|
return link_enter_join_netdev(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int link_get_network(Link *link, Network **ret) {
|
|
||||||
Network *network;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(link->manager);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
ORDERED_HASHMAP_FOREACH(network, link->manager->networks) {
|
|
||||||
bool warn = false;
|
|
||||||
|
|
||||||
r = net_match_config(
|
|
||||||
&network->match,
|
|
||||||
link->sd_device,
|
|
||||||
&link->hw_addr.addr.ether,
|
|
||||||
&link->permanent_mac,
|
|
||||||
link->driver,
|
|
||||||
link->iftype,
|
|
||||||
link->ifname,
|
|
||||||
link->alternative_names,
|
|
||||||
link->wlan_iftype,
|
|
||||||
link->ssid,
|
|
||||||
&link->bssid);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
if (r == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (network->match.ifname && link->sd_device) {
|
|
||||||
uint8_t name_assign_type = NET_NAME_UNKNOWN;
|
|
||||||
const char *attr;
|
|
||||||
|
|
||||||
if (sd_device_get_sysattr_value(link->sd_device, "name_assign_type", &attr) >= 0)
|
|
||||||
(void) safe_atou8(attr, &name_assign_type);
|
|
||||||
|
|
||||||
warn = name_assign_type == NET_NAME_ENUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_link_full(link, warn ? LOG_WARNING : LOG_DEBUG,
|
|
||||||
"found matching network '%s'%s.",
|
|
||||||
network->filename,
|
|
||||||
warn ? ", based on potentially unpredictable interface name" : "");
|
|
||||||
|
|
||||||
if (network->unmanaged)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
*ret = network;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) {
|
static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) {
|
||||||
_cleanup_strv_free_ char **s = NULL;
|
_cleanup_strv_free_ char **s = NULL;
|
||||||
Network *network;
|
Network *network;
|
||||||
@ -2296,12 +2243,17 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
|
|||||||
|
|
||||||
strv_free_and_replace(link->alternative_names, s);
|
strv_free_and_replace(link->alternative_names, s);
|
||||||
|
|
||||||
r = link_get_network(link, &network);
|
r = network_get(link->manager, link->iftype, link->sd_device,
|
||||||
|
link->ifname, link->alternative_names, link->driver,
|
||||||
|
&link->hw_addr.addr.ether, &link->permanent_mac,
|
||||||
|
link->wlan_iftype, link->ssid, &link->bssid, &network);
|
||||||
if (r == -ENOENT) {
|
if (r == -ENOENT) {
|
||||||
link_enter_unmanaged(link);
|
link_enter_unmanaged(link);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (r == 0 && network->unmanaged) {
|
||||||
if (r < 0)
|
link_enter_unmanaged(link);
|
||||||
|
return 0;
|
||||||
|
} else if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (link->network == network && !force)
|
if (link->network == network && !force)
|
||||||
@ -2425,12 +2377,17 @@ static int link_initialized_and_synced(Link *link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = link_get_network(link, &network);
|
r = network_get(link->manager, link->iftype, link->sd_device,
|
||||||
|
link->ifname, link->alternative_names, link->driver,
|
||||||
|
&link->hw_addr.addr.ether, &link->permanent_mac,
|
||||||
|
link->wlan_iftype, link->ssid, &link->bssid, &network);
|
||||||
if (r == -ENOENT) {
|
if (r == -ENOENT) {
|
||||||
link_enter_unmanaged(link);
|
link_enter_unmanaged(link);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (r == 0 && network->unmanaged) {
|
||||||
if (r < 0)
|
link_enter_unmanaged(link);
|
||||||
|
return 0;
|
||||||
|
} else if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (link->flags & IFF_LOOPBACK) {
|
if (link->flags & IFF_LOOPBACK) {
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
#include "bus-common-errors.h"
|
#include "bus-common-errors.h"
|
||||||
#include "bus-message-util.h"
|
#include "bus-message-util.h"
|
||||||
#include "bus-polkit.h"
|
#include "bus-polkit.h"
|
||||||
#include "networkd-json.h"
|
|
||||||
#include "networkd-link-bus.h"
|
#include "networkd-link-bus.h"
|
||||||
#include "networkd-link.h"
|
#include "networkd-link.h"
|
||||||
#include "networkd-manager-bus.h"
|
#include "networkd-manager-bus.h"
|
||||||
@ -230,39 +229,6 @@ static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_err
|
|||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bus_method_describe_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
||||||
return call_link_method(userdata, message, bus_link_method_describe, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bus_method_describe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
|
||||||
_cleanup_free_ char *text = NULL;
|
|
||||||
Manager *manager = userdata;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(message);
|
|
||||||
assert(manager);
|
|
||||||
|
|
||||||
r = manager_build_json(manager, &v);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to build JSON data: %m");
|
|
||||||
|
|
||||||
r = json_variant_format(v, 0, &text);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to format JSON data: %m");
|
|
||||||
|
|
||||||
r = sd_bus_message_new_method_return(message, &reply);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_bus_message_append(reply, "s", text);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return sd_bus_send(NULL, reply, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sd_bus_vtable manager_vtable[] = {
|
const sd_bus_vtable manager_vtable[] = {
|
||||||
SD_BUS_VTABLE_START(0),
|
SD_BUS_VTABLE_START(0),
|
||||||
|
|
||||||
@ -367,16 +333,6 @@ const sd_bus_vtable manager_vtable[] = {
|
|||||||
SD_BUS_NO_RESULT,
|
SD_BUS_NO_RESULT,
|
||||||
bus_method_reload,
|
bus_method_reload,
|
||||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD_WITH_ARGS("DescribeLink",
|
|
||||||
SD_BUS_ARGS("i", ifindex),
|
|
||||||
SD_BUS_RESULT("s", json),
|
|
||||||
bus_method_describe_link,
|
|
||||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
|
||||||
SD_BUS_METHOD_WITH_ARGS("Describe",
|
|
||||||
SD_BUS_NO_ARGS,
|
|
||||||
SD_BUS_RESULT("s", json),
|
|
||||||
bus_method_describe,
|
|
||||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
|
||||||
|
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END
|
||||||
};
|
};
|
||||||
|
|||||||
@ -646,6 +646,43 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int network_get(Manager *manager, unsigned short iftype, sd_device *device,
|
||||||
|
const char *ifname, char * const *alternative_names, const char *driver,
|
||||||
|
const struct ether_addr *mac, const struct ether_addr *permanent_mac,
|
||||||
|
enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
|
||||||
|
Network **ret) {
|
||||||
|
Network *network;
|
||||||
|
|
||||||
|
assert(manager);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
ORDERED_HASHMAP_FOREACH(network, manager->networks)
|
||||||
|
if (net_match_config(&network->match, device, mac, permanent_mac, driver, iftype,
|
||||||
|
ifname, alternative_names, wlan_iftype, ssid, bssid)) {
|
||||||
|
if (network->match.ifname && device) {
|
||||||
|
const char *attr;
|
||||||
|
uint8_t name_assign_type = NET_NAME_UNKNOWN;
|
||||||
|
|
||||||
|
if (sd_device_get_sysattr_value(device, "name_assign_type", &attr) >= 0)
|
||||||
|
(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",
|
||||||
|
ifname, network->filename);
|
||||||
|
else
|
||||||
|
log_debug("%s: found matching network '%s'", ifname, network->filename);
|
||||||
|
} else
|
||||||
|
log_debug("%s: found matching network '%s'", ifname, network->filename);
|
||||||
|
|
||||||
|
*ret = network;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = NULL;
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
bool network_has_static_ipv6_configurations(Network *network) {
|
bool network_has_static_ipv6_configurations(Network *network) {
|
||||||
Address *address;
|
Address *address;
|
||||||
Route *route;
|
Route *route;
|
||||||
|
|||||||
@ -341,6 +341,11 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||||||
int network_verify(Network *network);
|
int network_verify(Network *network);
|
||||||
|
|
||||||
int network_get_by_name(Manager *manager, const char *name, Network **ret);
|
int network_get_by_name(Manager *manager, const char *name, Network **ret);
|
||||||
|
int network_get(Manager *manager, unsigned short iftype, sd_device *device,
|
||||||
|
const char *ifname, char * const *alternative_names, const char *driver,
|
||||||
|
const struct ether_addr *mac, const struct ether_addr *permanent_mac,
|
||||||
|
enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
|
||||||
|
Network **ret);
|
||||||
void network_apply_anonymize_if_set(Network *network);
|
void network_apply_anonymize_if_set(Network *network);
|
||||||
|
|
||||||
bool network_has_static_ipv6_configurations(Network *network);
|
bool network_has_static_ipv6_configurations(Network *network);
|
||||||
|
|||||||
@ -1317,14 +1317,19 @@ int config_parse_routing_policy_rule_device(
|
|||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
if (!ifname_valid(rvalue)) {
|
if (!ifname_valid(rvalue)) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
log_syntax(unit, LOG_WARNING, filename, line, 0, "Failed to parse '%s' interface name, ignoring: %s", lvalue, rvalue);
|
||||||
"Invalid interface name '%s' in %s=, ignoring assignment.", rvalue, lvalue);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = free_and_strdup(streq(lvalue, "IncomingInterface") ? &n->iif : &n->oif, rvalue);
|
if (streq(lvalue, "IncomingInterface")) {
|
||||||
if (r < 0)
|
r = free_and_strdup(&n->iif, rvalue);
|
||||||
return log_oom();
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
} else {
|
||||||
|
r = free_and_strdup(&n->oif, rvalue);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
TAKE_PTR(n);
|
TAKE_PTR(n);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1341,7 +1346,6 @@ int config_parse_routing_policy_rule_port_range(
|
|||||||
const char *rvalue,
|
const char *rvalue,
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
_cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
|
_cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
|
||||||
Network *network = userdata;
|
Network *network = userdata;
|
||||||
uint16_t low, high;
|
uint16_t low, high;
|
||||||
|
|||||||
@ -168,6 +168,23 @@ static int test_load_config(Manager *manager) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_network_get(Manager *manager, sd_device *loopback) {
|
||||||
|
Network *network;
|
||||||
|
const struct ether_addr mac = ETHER_ADDR_NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Let's hope that the test machine does not have a .network file that applies to loopback device…
|
||||||
|
* But it is still possible, so let's allow that case too. */
|
||||||
|
r = network_get(manager, 0, loopback, "lo", NULL, NULL, &mac, &mac, 0, NULL, NULL, &network);
|
||||||
|
if (r == -ENOENT)
|
||||||
|
/* The expected case */
|
||||||
|
assert_se(!network);
|
||||||
|
else if (r >= 0)
|
||||||
|
assert_se(network);
|
||||||
|
else
|
||||||
|
assert_not_reached("bad error!");
|
||||||
|
}
|
||||||
|
|
||||||
static void test_address_equality(void) {
|
static void test_address_equality(void) {
|
||||||
_cleanup_(address_freep) Address *a1 = NULL, *a2 = NULL;
|
_cleanup_(address_freep) Address *a1 = NULL, *a2 = NULL;
|
||||||
|
|
||||||
@ -260,7 +277,8 @@ static void test_dhcp_hostname_shorten_overlong(void) {
|
|||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
_cleanup_(manager_freep) Manager *manager = NULL;
|
_cleanup_(manager_freep) Manager *manager = NULL;
|
||||||
int r;
|
_cleanup_(sd_device_unrefp) sd_device *loopback = NULL;
|
||||||
|
int ifindex, r;
|
||||||
|
|
||||||
test_setup_logging(LOG_INFO);
|
test_setup_logging(LOG_INFO);
|
||||||
|
|
||||||
@ -275,9 +293,15 @@ int main(void) {
|
|||||||
|
|
||||||
r = test_load_config(manager);
|
r = test_load_config(manager);
|
||||||
if (r == -EPERM)
|
if (r == -EPERM)
|
||||||
log_debug("Cannot load configuration, ignoring.");
|
return log_tests_skipped("Cannot load configuration");
|
||||||
else
|
assert_se(r == 0);
|
||||||
assert_se(r == 0);
|
|
||||||
|
assert_se(sd_device_new_from_syspath(&loopback, "/sys/class/net/lo") >= 0);
|
||||||
|
assert_se(loopback);
|
||||||
|
assert_se(sd_device_get_ifindex(loopback, &ifindex) >= 0);
|
||||||
|
assert_se(ifindex == 1);
|
||||||
|
|
||||||
|
test_network_get(manager, loopback);
|
||||||
|
|
||||||
assert_se(manager_enumerate(manager) >= 0);
|
assert_se(manager_enumerate(manager) >= 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -146,26 +146,22 @@ struct json_variant_foreach_state {
|
|||||||
size_t idx;
|
size_t idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define _JSON_VARIANT_ARRAY_FOREACH(i, v, state) \
|
|
||||||
for (struct json_variant_foreach_state state = { (v), 0 }; \
|
|
||||||
json_variant_is_array(state.variant) && \
|
|
||||||
state.idx < json_variant_elements(state.variant) && \
|
|
||||||
({ i = json_variant_by_index(state.variant, state.idx); \
|
|
||||||
true; }); \
|
|
||||||
state.idx++)
|
|
||||||
#define JSON_VARIANT_ARRAY_FOREACH(i, v) \
|
#define JSON_VARIANT_ARRAY_FOREACH(i, v) \
|
||||||
_JSON_VARIANT_ARRAY_FOREACH(i, v, UNIQ_T(state, UNIQ))
|
for (struct json_variant_foreach_state _state = { (v), 0 }; \
|
||||||
|
json_variant_is_array(_state.variant) && \
|
||||||
#define _JSON_VARIANT_OBJECT_FOREACH(k, e, v, state) \
|
_state.idx < json_variant_elements(_state.variant) && \
|
||||||
for (struct json_variant_foreach_state state = { (v), 0 }; \
|
({ i = json_variant_by_index(_state.variant, _state.idx); \
|
||||||
json_variant_is_object(state.variant) && \
|
|
||||||
state.idx < json_variant_elements(state.variant) && \
|
|
||||||
({ k = json_variant_string(json_variant_by_index(state.variant, state.idx)); \
|
|
||||||
e = json_variant_by_index(state.variant, state.idx + 1); \
|
|
||||||
true; }); \
|
true; }); \
|
||||||
state.idx += 2)
|
_state.idx++)
|
||||||
|
|
||||||
#define JSON_VARIANT_OBJECT_FOREACH(k, e, v) \
|
#define JSON_VARIANT_OBJECT_FOREACH(k, e, v) \
|
||||||
_JSON_VARIANT_OBJECT_FOREACH(k, e, v, UNIQ_T(state, UNIQ))
|
for (struct json_variant_foreach_state _state = { (v), 0 }; \
|
||||||
|
json_variant_is_object(_state.variant) && \
|
||||||
|
_state.idx < json_variant_elements(_state.variant) && \
|
||||||
|
({ k = json_variant_string(json_variant_by_index(_state.variant, _state.idx)); \
|
||||||
|
e = json_variant_by_index(_state.variant, _state.idx + 1); \
|
||||||
|
true; }); \
|
||||||
|
_state.idx += 2)
|
||||||
|
|
||||||
int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column);
|
int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column);
|
||||||
|
|
||||||
|
|||||||
@ -134,7 +134,7 @@ static const char *const wifi_iftype_table[NL80211_IFTYPE_MAX+1] = {
|
|||||||
|
|
||||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(wifi_iftype, enum nl80211_iftype);
|
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(wifi_iftype, enum nl80211_iftype);
|
||||||
|
|
||||||
int net_match_config(
|
bool net_match_config(
|
||||||
const NetMatch *match,
|
const NetMatch *match,
|
||||||
sd_device *device,
|
sd_device *device,
|
||||||
const struct ether_addr *mac,
|
const struct ether_addr *mac,
|
||||||
@ -149,13 +149,10 @@ int net_match_config(
|
|||||||
|
|
||||||
_cleanup_free_ char *iftype_str = NULL;
|
_cleanup_free_ char *iftype_str = NULL;
|
||||||
const char *path = NULL;
|
const char *path = NULL;
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(match);
|
assert(match);
|
||||||
|
|
||||||
r = link_get_type_string(device, iftype, &iftype_str);
|
iftype_str = link_get_type_string(device, iftype);
|
||||||
if (r == -ENOMEM)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (device) {
|
if (device) {
|
||||||
const char *mac_str;
|
const char *mac_str;
|
||||||
|
|||||||
@ -26,7 +26,7 @@ typedef struct NetMatch {
|
|||||||
void net_match_clear(NetMatch *match);
|
void net_match_clear(NetMatch *match);
|
||||||
bool net_match_is_empty(const NetMatch *match);
|
bool net_match_is_empty(const NetMatch *match);
|
||||||
|
|
||||||
int net_match_config(
|
bool net_match_config(
|
||||||
const NetMatch *match,
|
const NetMatch *match,
|
||||||
sd_device *device,
|
sd_device *device,
|
||||||
const struct ether_addr *mac,
|
const struct ether_addr *mac,
|
||||||
|
|||||||
@ -273,20 +273,16 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
|
|||||||
(void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type);
|
(void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type);
|
||||||
|
|
||||||
LIST_FOREACH(links, link, ctx->links) {
|
LIST_FOREACH(links, link, ctx->links) {
|
||||||
r = net_match_config(&link->match, device, NULL, &permanent_mac, NULL, iftype, NULL, NULL, 0, NULL, NULL);
|
if (net_match_config(&link->match, device, NULL, &permanent_mac, NULL, iftype, NULL, NULL, 0, NULL, NULL)) {
|
||||||
if (r < 0)
|
if (link->match.ifname && !strv_contains(link->match.ifname, "*") && name_assign_type == NET_NAME_ENUM)
|
||||||
return r;
|
log_device_warning(device, "Config file %s is applied to device based on potentially unpredictable interface name.",
|
||||||
if (r == 0)
|
link->filename);
|
||||||
continue;
|
else
|
||||||
|
log_device_debug(device, "Config file %s is applied", link->filename);
|
||||||
|
|
||||||
if (link->match.ifname && !strv_contains(link->match.ifname, "*") && name_assign_type == NET_NAME_ENUM)
|
*ret = link;
|
||||||
log_device_warning(device, "Config file %s is applied to device based on potentially unpredictable interface name.",
|
return 0;
|
||||||
link->filename);
|
}
|
||||||
else
|
|
||||||
log_device_debug(device, "Config file %s is applied", link->filename);
|
|
||||||
|
|
||||||
*ret = link;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user