networkctl: accept wildcards to specify links

Closes #10840.
This commit is contained in:
Yu Watanabe 2019-02-15 13:32:51 +09:00
parent 93e4163e91
commit a696290474

View file

@ -107,10 +107,10 @@ static int link_info_compare(const LinkInfo *a, const LinkInfo *b) {
return CMP(a->ifindex, b->ifindex);
}
static int decode_link(sd_netlink_message *m, LinkInfo *info) {
static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns) {
const char *name;
uint16_t type;
int r;
int ifindex, r;
assert(m);
assert(info);
@ -122,7 +122,7 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info) {
if (type != RTM_NEWLINK)
return 0;
r = sd_rtnl_message_link_get_ifindex(m, &info->ifindex);
r = sd_rtnl_message_link_get_ifindex(m, &ifindex);
if (r < 0)
return r;
@ -130,11 +130,21 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info) {
if (r < 0)
return r;
if (patterns) {
char str[DECIMAL_STR_MAX(int)];
xsprintf(str, "%i", ifindex);
if (!strv_fnmatch(patterns, str, 0) && !strv_fnmatch(patterns, name, 0))
return 0;
}
r = sd_rtnl_message_link_get_type(m, &info->iftype);
if (r < 0)
return r;
strscpy(info->name, sizeof info->name, name);
info->ifindex = ifindex;
info->has_mac_address =
sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &info->mac_address) >= 0 &&
@ -147,54 +157,7 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info) {
return 1;
}
static int acquire_link_info_strv(sd_netlink *rtnl, char **l, LinkInfo **ret) {
_cleanup_free_ LinkInfo *links = NULL;
char **i;
size_t c = 0;
int r;
assert(rtnl);
assert(ret);
links = new(LinkInfo, strv_length(l));
if (!links)
return log_oom();
STRV_FOREACH(i, l) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
int ifindex;
if (parse_ifindex(*i, &ifindex) >= 0)
r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
else {
r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
if (r < 0)
return rtnl_log_create_error(r);
r = sd_netlink_message_append_string(req, IFLA_IFNAME, *i);
}
if (r < 0)
return rtnl_log_create_error(r);
r = sd_netlink_call(rtnl, req, 0, &reply);
if (r < 0)
return log_error_errno(r, "Failed to request link: %m");
r = decode_link(reply, links + c);
if (r < 0)
return r;
if (r > 0)
c++;
}
typesafe_qsort(links, c, link_info_compare);
*ret = TAKE_PTR(links);
return (int) c;
}
static int acquire_link_info_all(sd_netlink *rtnl, LinkInfo **ret) {
static int acquire_link_info(sd_netlink *rtnl, char **patterns, LinkInfo **ret) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
_cleanup_free_ LinkInfo *links = NULL;
size_t allocated = 0, c = 0;
@ -220,7 +183,7 @@ static int acquire_link_info_all(sd_netlink *rtnl, LinkInfo **ret) {
if (!GREEDY_REALLOC(links, allocated, c+1))
return -ENOMEM;
r = decode_link(i, links + c);
r = decode_link(i, links + c, patterns);
if (r < 0)
return r;
if (r > 0)
@ -243,10 +206,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to connect to netlink: %m");
if (argc > 1)
c = acquire_link_info_strv(rtnl, argv + 1, &links);
else
c = acquire_link_info_all(rtnl, &links);
c = acquire_link_info(rtnl, argc > 1 ? argv + 1 : NULL, &links);
if (c < 0)
return c;
@ -887,11 +847,11 @@ static int link_status(int argc, char *argv[], void *userdata) {
log_debug_errno(r, "Failed to open hardware database: %m");
if (arg_all)
c = acquire_link_info_all(rtnl, &links);
c = acquire_link_info(rtnl, NULL, &links);
else if (argc <= 1)
return system_status(rtnl, hwdb);
else
c = acquire_link_info_strv(rtnl, argv + 1, &links);
c = acquire_link_info(rtnl, argv + 1, &links);
if (c < 0)
return c;
@ -965,10 +925,7 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to connect to netlink: %m");
if (argc > 1)
c = acquire_link_info_strv(rtnl, argv + 1, &links);
else
c = acquire_link_info_all(rtnl, &links);
c = acquire_link_info(rtnl, argc > 1 ? argv + 1 : NULL, &links);
if (c < 0)
return c;
@ -1078,9 +1035,9 @@ static int help(void) {
" --no-legend Do not show the headers and footers\n"
" -a --all Show status for all links\n\n"
"Commands:\n"
" list [LINK...] List links\n"
" status [LINK...] Show link status\n"
" lldp [LINK...] Show LLDP neighbors\n"
" list [PATTERN...] List links\n"
" status [PATTERN...] Show link status\n"
" lldp [PATTERN...] Show LLDP neighbors\n"
" label Show current address label entries in the kernel\n"
"\nSee the %s for details.\n"
, program_invocation_short_name