mirror of
https://github.com/systemd/systemd.git
synced 2025-03-21 02:50:18 +03:00
Merge pull request #13201 from yuwata/networkctl-merge-table_add_cell
networkctl cleanups and improvements
This commit is contained in:
commit
0f7dfea171
@ -1414,8 +1414,8 @@ struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) {
|
||||
return utc ? gmtime_r(t, tm) : localtime_r(t, tm);
|
||||
}
|
||||
|
||||
unsigned long usec_to_jiffies(usec_t u) {
|
||||
static thread_local unsigned long hz = 0;
|
||||
static uint32_t sysconf_clock_ticks_cached(void) {
|
||||
static thread_local uint32_t hz = 0;
|
||||
long r;
|
||||
|
||||
if (hz == 0) {
|
||||
@ -1425,7 +1425,17 @@ unsigned long usec_to_jiffies(usec_t u) {
|
||||
hz = r;
|
||||
}
|
||||
|
||||
return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
|
||||
return hz;
|
||||
}
|
||||
|
||||
uint32_t usec_to_jiffies(usec_t u) {
|
||||
uint32_t hz = sysconf_clock_ticks_cached();
|
||||
return DIV_ROUND_UP(u, USEC_PER_SEC / hz);
|
||||
}
|
||||
|
||||
usec_t jiffies_to_usec(uint32_t j) {
|
||||
uint32_t hz = sysconf_clock_ticks_cached();
|
||||
return DIV_ROUND_UP(j * USEC_PER_SEC, hz);
|
||||
}
|
||||
|
||||
usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
|
||||
|
@ -136,7 +136,8 @@ int get_timezone(char **timezone);
|
||||
time_t mktime_or_timegm(struct tm *tm, bool utc);
|
||||
struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
|
||||
|
||||
unsigned long usec_to_jiffies(usec_t usec);
|
||||
uint32_t usec_to_jiffies(usec_t usec);
|
||||
usec_t jiffies_to_usec(uint32_t jiffies);
|
||||
|
||||
bool in_utc_timezone(void);
|
||||
|
||||
|
@ -47,6 +47,9 @@
|
||||
#include "terminal-util.h"
|
||||
#include "verbs.h"
|
||||
|
||||
/* Kernel defines MODULE_NAME_LEN as 64 - sizeof(unsigned long). So, 64 is enough. */
|
||||
#define NETDEV_KIND_MAX 64
|
||||
|
||||
static PagerFlags arg_pager_flags = 0;
|
||||
static bool arg_legend = true;
|
||||
static bool arg_all = false;
|
||||
@ -104,8 +107,23 @@ static void setup_state_to_color(const char *state, const char **on, const char
|
||||
*on = *off = "";
|
||||
}
|
||||
|
||||
typedef struct VxLanInfo {
|
||||
uint32_t vni;
|
||||
uint32_t link;
|
||||
|
||||
int local_family;
|
||||
int group_family;
|
||||
|
||||
union in_addr_union local;
|
||||
union in_addr_union group;
|
||||
|
||||
uint16_t dest_port;
|
||||
|
||||
} VxLanInfo;
|
||||
|
||||
typedef struct LinkInfo {
|
||||
char name[IFNAMSIZ+1];
|
||||
char netdev_kind[NETDEV_KIND_MAX];
|
||||
int ifindex;
|
||||
unsigned short iftype;
|
||||
struct ether_addr mac_address;
|
||||
@ -123,6 +141,18 @@ typedef struct LinkInfo {
|
||||
uint64_t tx_bitrate;
|
||||
uint64_t rx_bitrate;
|
||||
|
||||
/* bridge info */
|
||||
uint32_t forward_delay;
|
||||
uint32_t hello_time;
|
||||
uint32_t max_age;
|
||||
uint32_t ageing_time;
|
||||
uint32_t stp_state;
|
||||
uint16_t priority;
|
||||
uint8_t mcast_igmp_version;
|
||||
|
||||
/* vxlan info */
|
||||
VxLanInfo vxlan_info;
|
||||
|
||||
/* ethtool info */
|
||||
int autonegotiation;
|
||||
size_t speed;
|
||||
@ -142,10 +172,71 @@ static int link_info_compare(const LinkInfo *a, const LinkInfo *b) {
|
||||
return CMP(a->ifindex, b->ifindex);
|
||||
}
|
||||
|
||||
static int decode_netdev(sd_netlink_message *m, LinkInfo *info) {
|
||||
const char *received_kind;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(info);
|
||||
|
||||
r = sd_netlink_message_enter_container(m, IFLA_LINKINFO);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_read_string(m, IFLA_INFO_KIND, &received_kind);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_enter_container(m, IFLA_INFO_DATA);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (streq(received_kind, "bridge")) {
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_BR_FORWARD_DELAY, &info->forward_delay);
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_BR_HELLO_TIME, &info->hello_time);
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_BR_MAX_AGE, &info->max_age);
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_BR_AGEING_TIME, &info->ageing_time);
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_BR_STP_STATE, &info->stp_state);
|
||||
(void) sd_netlink_message_read_u16(m, IFLA_BR_PRIORITY, &info->priority);
|
||||
(void) sd_netlink_message_read_u8(m, IFLA_BR_MCAST_IGMP_VERSION, &info->mcast_igmp_version);
|
||||
|
||||
} else if (streq(received_kind, "vxlan")) {
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_VXLAN_ID, &info->vxlan_info.vni);
|
||||
|
||||
r = sd_netlink_message_read_in_addr(m, IFLA_VXLAN_GROUP, &info->vxlan_info.group.in);
|
||||
if (r >= 0)
|
||||
info->vxlan_info.group_family = AF_INET;
|
||||
else {
|
||||
r = sd_netlink_message_read_in6_addr(m, IFLA_VXLAN_GROUP6, &info->vxlan_info.group.in6);
|
||||
if (r >= 0)
|
||||
info->vxlan_info.group_family = AF_INET6;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_read_in_addr(m, IFLA_VXLAN_LOCAL, &info->vxlan_info.local.in);
|
||||
if (r >= 0)
|
||||
info->vxlan_info.local_family = AF_INET;
|
||||
else {
|
||||
r = sd_netlink_message_read_in6_addr(m, IFLA_VXLAN_LOCAL6, &info->vxlan_info.local.in6);
|
||||
if (r >= 0)
|
||||
info->vxlan_info.local_family = AF_INET6;
|
||||
}
|
||||
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_VXLAN_LINK, &info->vxlan_info.link);
|
||||
(void) sd_netlink_message_read_u16(m, IFLA_VXLAN_PORT, &info->vxlan_info.dest_port);
|
||||
}
|
||||
|
||||
strncpy(info->netdev_kind, received_kind, IFNAMSIZ);
|
||||
|
||||
(void) sd_netlink_message_exit_container(m);
|
||||
(void) sd_netlink_message_exit_container(m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns) {
|
||||
const char *name;
|
||||
uint16_t type;
|
||||
int ifindex, r;
|
||||
uint16_t type;
|
||||
|
||||
assert(m);
|
||||
assert(info);
|
||||
@ -202,6 +293,9 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns) {
|
||||
else if (sd_netlink_message_read(m, IFLA_STATS, sizeof info->stats, &info->stats) >= 0)
|
||||
info->has_stats = true;
|
||||
|
||||
/* fill kind info */
|
||||
(void) decode_netdev(m, info);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -360,27 +454,16 @@ static int list_links(int argc, char *argv[], void *userdata) {
|
||||
|
||||
t = link_get_type_string(links[i].iftype, d);
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_INT, &links[i].ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_INT, links[i].ifindex,
|
||||
TABLE_STRING, links[i].name,
|
||||
TABLE_STRING, strna(t));
|
||||
TABLE_STRING, strna(t),
|
||||
TABLE_STRING, strna(operational_state),
|
||||
TABLE_SET_COLOR, on_color_operational,
|
||||
TABLE_STRING, strna(setup_state),
|
||||
TABLE_SET_COLOR, on_color_setup);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, &cell, TABLE_STRING, strna(operational_state));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) table_set_color(table, cell, on_color_operational);
|
||||
|
||||
r = table_add_cell(table, &cell, TABLE_STRING, strna(setup_state));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) table_set_color(table, cell, on_color_setup);
|
||||
}
|
||||
|
||||
r = table_print(table, NULL);
|
||||
@ -551,11 +634,9 @@ static int dump_gateways(
|
||||
for (i = 0; i < n; i++) {
|
||||
_cleanup_free_ char *gateway = NULL, *description = NULL, *with_description = NULL;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, i == 0 ? "Gateway:" : "");
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, i == 0 ? "Gateway:" : "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -609,11 +690,9 @@ static int dump_addresses(
|
||||
for (i = 0; i < n; i++) {
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, i == 0 ? "Address:" : "");
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, i == 0 ? "Address:" : "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -707,7 +786,7 @@ static int dump_address_labels(sd_netlink *rtnl) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell_stringf(table, &cell, "%s/%u", pretty, prefixlen);
|
||||
r = table_add_cell_stringf(table, NULL, "%s/%u", pretty, prefixlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -793,7 +872,6 @@ static int dump_lldp_neighbors(Table *table, const char *prefix, int ifindex) {
|
||||
for (;;) {
|
||||
const char *system_name = NULL, *port_id = NULL, *port_description = NULL;
|
||||
_cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
|
||||
_cleanup_free_ char *str = NULL;
|
||||
|
||||
r = next_lldp_neighbor(f, &n);
|
||||
if (r < 0)
|
||||
@ -801,11 +879,9 @@ static int dump_lldp_neighbors(Table *table, const char *prefix, int ifindex) {
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, c == 0 ? prefix : "");
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, c == 0 ? prefix : "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -813,14 +889,12 @@ static int dump_lldp_neighbors(Table *table, const char *prefix, int ifindex) {
|
||||
(void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id);
|
||||
(void) sd_lldp_neighbor_get_port_description(n, &port_description);
|
||||
|
||||
if (asprintf(&str, "%s on port %s%s%s%s",
|
||||
strna(system_name), strna(port_id),
|
||||
isempty(port_description) ? "" : " (",
|
||||
port_description,
|
||||
isempty(port_description) ? "" : ")") < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, str);
|
||||
r = table_add_cell_stringf(table, NULL,
|
||||
"%s on port %s%s%s%s",
|
||||
strna(system_name), strna(port_id),
|
||||
isempty(port_description) ? "" : " (",
|
||||
port_description,
|
||||
isempty(port_description) ? "" : ")");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -840,15 +914,10 @@ static int dump_ifindexes(Table *table, const char *prefix, const int *ifindexes
|
||||
return 0;
|
||||
|
||||
for (c = 0; ifindexes[c] > 0; c++) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, c == 0 ? prefix : "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_IFINDEX, ifindexes + c);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, c == 0 ? prefix : "",
|
||||
TABLE_IFINDEX, ifindexes[c]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -864,15 +933,10 @@ static int dump_list(Table *table, const char *prefix, char **l) {
|
||||
return 0;
|
||||
|
||||
STRV_FOREACH(i, l) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, i == l ? prefix : "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, *i);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, i == l ? prefix : "",
|
||||
TABLE_STRING, *i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -881,13 +945,13 @@ static int dump_list(Table *table, const char *prefix, char **l) {
|
||||
}
|
||||
|
||||
#define DUMP_STATS_ONE(name, val_name) \
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL); \
|
||||
r = table_add_many(table, \
|
||||
TABLE_EMPTY, \
|
||||
TABLE_STRING, name ":"); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, name ":"); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
r = table_add_cell(table, NULL, info->has_stats64 ? TABLE_UINT64 : TABLE_UINT32, \
|
||||
r = table_add_cell(table, NULL, \
|
||||
info->has_stats64 ? TABLE_UINT64 : TABLE_UINT32, \
|
||||
info->has_stats64 ? (void*) &info->stats64.val_name : (void*) &info->stats.val_name); \
|
||||
if (r < 0) \
|
||||
return r;
|
||||
@ -984,53 +1048,30 @@ static int link_status_one(
|
||||
|
||||
table_set_header(table, false);
|
||||
|
||||
r = table_add_cell(table, &cell, TABLE_STRING, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE));
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE),
|
||||
TABLE_SET_COLOR, on_color_operational);
|
||||
if (r < 0)
|
||||
return r;
|
||||
(void) table_set_color(table, cell, on_color_operational);
|
||||
r = table_add_cell_stringf(table, &cell, "%i: %s", info->ifindex, info->name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
(void) table_set_align_percent(table, cell, 0);
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, &cell, TABLE_STRING, "Link File:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
(void) table_set_align_percent(table, cell, 100);
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, strna(link));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Network File:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, strna(network));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Type:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, strna(t));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "State:");
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Link File:",
|
||||
TABLE_SET_ALIGN_PERCENT, 100,
|
||||
TABLE_STRING, strna(link),
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Network File:",
|
||||
TABLE_STRING, strna(network),
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Type:",
|
||||
TABLE_STRING, strna(t),
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "State:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell_stringf(table, NULL, "%s%s%s (%s%s%s)",
|
||||
@ -1040,46 +1081,34 @@ static int link_status_one(
|
||||
return r;
|
||||
|
||||
if (path) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Path:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, path);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Path:",
|
||||
TABLE_STRING, path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (driver) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Driver:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, driver);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Driver:",
|
||||
TABLE_STRING, driver);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (vendor) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Vendor:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, vendor);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Vendor:",
|
||||
TABLE_STRING, vendor);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (model) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Model:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, model);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Model:",
|
||||
TABLE_STRING, model);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1090,10 +1119,9 @@ static int link_status_one(
|
||||
|
||||
(void) ieee_oui(hwdb, &info->mac_address, &description);
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "HW Address:");
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "HW Address:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell_stringf(table, NULL, "%s%s%s%s",
|
||||
@ -1111,10 +1139,9 @@ static int link_status_one(
|
||||
xsprintf(min_str, "%" PRIu32, info->min_mtu);
|
||||
xsprintf(max_str, "%" PRIu32, info->max_mtu);
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "MTU:");
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "MTU:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell_stringf(table, NULL, "%" PRIu32 "%s%s%s%s%s%s%s",
|
||||
@ -1130,16 +1157,89 @@ static int link_status_one(
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq_ptr(info->netdev_kind, "bridge")) {
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Forward Delay:",
|
||||
TABLE_TIMESPAN_MSEC, jiffies_to_usec(info->forward_delay),
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Hello Time:",
|
||||
TABLE_TIMESPAN_MSEC, jiffies_to_usec(info->hello_time),
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Max Age:",
|
||||
TABLE_TIMESPAN_MSEC, jiffies_to_usec(info->max_age),
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Ageing Time:",
|
||||
TABLE_TIMESPAN_MSEC, jiffies_to_usec(info->ageing_time),
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Priority:",
|
||||
TABLE_UINT16, info->priority,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "STP:",
|
||||
TABLE_BOOLEAN, info->stp_state > 0,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Multicast IGMP Version:",
|
||||
TABLE_UINT8, info->mcast_igmp_version);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
} else if (streq_ptr(info->netdev_kind, "vxlan")) {
|
||||
if (info->vxlan_info.vni > 0) {
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "VNI:",
|
||||
TABLE_UINT32, info->vxlan_info.vni);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (IN_SET(info->vxlan_info.group_family, AF_INET, AF_INET6)) {
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Group:",
|
||||
info->vxlan_info.group_family == AF_INET ? TABLE_IN_ADDR : TABLE_IN6_ADDR,
|
||||
&info->vxlan_info.group);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (IN_SET(info->vxlan_info.local_family, AF_INET, AF_INET6)) {
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Local:",
|
||||
info->vxlan_info.local_family == AF_INET ? TABLE_IN_ADDR : TABLE_IN6_ADDR,
|
||||
&info->vxlan_info.local);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (info->vxlan_info.dest_port > 0) {
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Destination Port:",
|
||||
TABLE_UINT16, be16toh(info->vxlan_info.dest_port));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (info->vxlan_info.link > 0) {
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Underlying Device:",
|
||||
TABLE_IFINDEX, info->vxlan_info.link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->has_bitrates) {
|
||||
char tx[FORMAT_BYTES_MAX], rx[FORMAT_BYTES_MAX];
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Bit Rate (Tx/Rx):");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Bit Rate (Tx/Rx):");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell_stringf(table, NULL, "%sbps/%sbps",
|
||||
format_bytes_full(tx, sizeof tx, info->tx_bitrate, 0),
|
||||
format_bytes_full(rx, sizeof rx, info->rx_bitrate, 0));
|
||||
@ -1148,10 +1248,9 @@ static int link_status_one(
|
||||
}
|
||||
|
||||
if (info->has_tx_queues || info->has_rx_queues) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Queue Length (Tx/Rx):");
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Queue Length (Tx/Rx):");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell_stringf(table, NULL, "%" PRIu32 "/%" PRIu32, info->tx_queues, info->rx_queues);
|
||||
@ -1164,49 +1263,37 @@ static int link_status_one(
|
||||
const char *port = port_to_string(info->port);
|
||||
|
||||
if (IN_SET(info->autonegotiation, AUTONEG_DISABLE, AUTONEG_ENABLE)) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Auto negotiation:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_BOOLEAN, &info->autonegotiation);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Auto negotiation:",
|
||||
TABLE_BOOLEAN, info->autonegotiation == AUTONEG_ENABLE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (info->speed > 0) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Speed:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_BPS, &info->speed);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Speed:",
|
||||
TABLE_BPS, info->speed);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (duplex) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Duplex:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, duplex);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Duplex:",
|
||||
TABLE_STRING, duplex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (port) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Port:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, port);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Port:",
|
||||
TABLE_STRING, port);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1239,13 +1326,10 @@ static int link_status_one(
|
||||
|
||||
(void) sd_network_link_get_timezone(info->ifindex, &tz);
|
||||
if (tz) {
|
||||
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "Time Zone:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, tz);
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Time Zone:",
|
||||
TABLE_STRING, tz);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1287,19 +1371,12 @@ static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
|
||||
|
||||
table_set_header(table, false);
|
||||
|
||||
r = table_add_cell(table, &cell, TABLE_STRING, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE));
|
||||
if (r < 0)
|
||||
return r;
|
||||
(void) table_set_color(table, cell, on_color_operational);
|
||||
|
||||
r = table_add_cell(table, NULL, TABLE_STRING, "State:");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_cell(table, &cell, TABLE_STRING, strna(operational_state));
|
||||
if (r < 0)
|
||||
return r;
|
||||
(void) table_set_color(table, cell, on_color_operational);
|
||||
r = table_add_many(table,
|
||||
TABLE_STRING, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE),
|
||||
TABLE_SET_COLOR, on_color_operational,
|
||||
TABLE_STRING, "State:",
|
||||
TABLE_STRING, strna(operational_state),
|
||||
TABLE_SET_COLOR, on_color_operational);
|
||||
|
||||
r = dump_addresses(rtnl, table, 0);
|
||||
if (r < 0)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "format-table.h"
|
||||
#include "format-util.h"
|
||||
#include "gunicode.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "memory-util.h"
|
||||
#include "pager.h"
|
||||
#include "parse-util.h"
|
||||
@ -77,13 +78,18 @@ typedef struct TableData {
|
||||
uint64_t size;
|
||||
char string[0];
|
||||
int int_val;
|
||||
int8_t int8;
|
||||
int16_t int16;
|
||||
int32_t int32;
|
||||
int64_t int64;
|
||||
unsigned uint_val;
|
||||
uint8_t uint8;
|
||||
uint16_t uint16;
|
||||
uint32_t uint32;
|
||||
uint64_t uint64;
|
||||
int percent; /* we use 'int' as datatype for percent values in order to match the result of parse_percent() */
|
||||
int ifindex;
|
||||
union in_addr_union address;
|
||||
/* … add more here as we start supporting more cell data types … */
|
||||
};
|
||||
} TableData;
|
||||
@ -246,12 +252,26 @@ static size_t table_data_size(TableDataType type, const void *data) {
|
||||
case TABLE_UINT32:
|
||||
return sizeof(uint32_t);
|
||||
|
||||
case TABLE_INT16:
|
||||
case TABLE_UINT16:
|
||||
return sizeof(uint16_t);
|
||||
|
||||
case TABLE_INT8:
|
||||
case TABLE_UINT8:
|
||||
return sizeof(uint8_t);
|
||||
|
||||
case TABLE_INT:
|
||||
case TABLE_UINT:
|
||||
case TABLE_PERCENT:
|
||||
case TABLE_IFINDEX:
|
||||
return sizeof(int);
|
||||
|
||||
case TABLE_IN_ADDR:
|
||||
return sizeof(struct in_addr);
|
||||
|
||||
case TABLE_IN6_ADDR:
|
||||
return sizeof(struct in6_addr);
|
||||
|
||||
default:
|
||||
assert_not_reached("Uh? Unexpected cell type");
|
||||
}
|
||||
@ -697,14 +717,19 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
|
||||
uint64_t size;
|
||||
usec_t usec;
|
||||
int int_val;
|
||||
int8_t int8;
|
||||
int16_t int16;
|
||||
int32_t int32;
|
||||
int64_t int64;
|
||||
unsigned uint_val;
|
||||
uint8_t uint8;
|
||||
uint16_t uint16;
|
||||
uint32_t uint32;
|
||||
uint64_t uint64;
|
||||
int percent;
|
||||
int ifindex;
|
||||
bool b;
|
||||
union in_addr_union address;
|
||||
} buffer;
|
||||
|
||||
switch (type) {
|
||||
@ -742,6 +767,24 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
|
||||
data = &buffer.int_val;
|
||||
break;
|
||||
|
||||
case TABLE_INT8: {
|
||||
int x = va_arg(ap, int);
|
||||
assert(x >= INT8_MIN && x <= INT8_MAX);
|
||||
|
||||
buffer.int8 = x;
|
||||
data = &buffer.int8;
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_INT16: {
|
||||
int x = va_arg(ap, int);
|
||||
assert(x >= INT16_MIN && x <= INT16_MAX);
|
||||
|
||||
buffer.int16 = x;
|
||||
data = &buffer.int16;
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_INT32:
|
||||
buffer.int32 = va_arg(ap, int32_t);
|
||||
data = &buffer.int32;
|
||||
@ -757,6 +800,24 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
|
||||
data = &buffer.uint_val;
|
||||
break;
|
||||
|
||||
case TABLE_UINT8: {
|
||||
unsigned x = va_arg(ap, unsigned);
|
||||
assert(x <= UINT8_MAX);
|
||||
|
||||
buffer.uint8 = x;
|
||||
data = &buffer.uint8;
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_UINT16: {
|
||||
unsigned x = va_arg(ap, unsigned);
|
||||
assert(x <= UINT16_MAX);
|
||||
|
||||
buffer.uint16 = x;
|
||||
data = &buffer.uint16;
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_UINT32:
|
||||
buffer.uint32 = va_arg(ap, uint32_t);
|
||||
data = &buffer.uint32;
|
||||
@ -777,6 +838,16 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
|
||||
data = &buffer.ifindex;
|
||||
break;
|
||||
|
||||
case TABLE_IN_ADDR:
|
||||
buffer.address = *va_arg(ap, union in_addr_union *);
|
||||
data = &buffer.address.in;
|
||||
break;
|
||||
|
||||
case TABLE_IN6_ADDR:
|
||||
buffer.address = *va_arg(ap, union in_addr_union *);
|
||||
data = &buffer.address.in6;
|
||||
break;
|
||||
|
||||
case TABLE_SET_MINIMUM_WIDTH: {
|
||||
size_t w = va_arg(ap, size_t);
|
||||
|
||||
@ -955,6 +1026,12 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
|
||||
case TABLE_INT:
|
||||
return CMP(a->int_val, b->int_val);
|
||||
|
||||
case TABLE_INT8:
|
||||
return CMP(a->int8, b->int8);
|
||||
|
||||
case TABLE_INT16:
|
||||
return CMP(a->int16, b->int16);
|
||||
|
||||
case TABLE_INT32:
|
||||
return CMP(a->int32, b->int32);
|
||||
|
||||
@ -964,6 +1041,12 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
|
||||
case TABLE_UINT:
|
||||
return CMP(a->uint_val, b->uint_val);
|
||||
|
||||
case TABLE_UINT8:
|
||||
return CMP(a->uint8, b->uint8);
|
||||
|
||||
case TABLE_UINT16:
|
||||
return CMP(a->uint16, b->uint16);
|
||||
|
||||
case TABLE_UINT32:
|
||||
return CMP(a->uint32, b->uint32);
|
||||
|
||||
@ -976,6 +1059,12 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
|
||||
case TABLE_IFINDEX:
|
||||
return CMP(a->ifindex, b->ifindex);
|
||||
|
||||
case TABLE_IN_ADDR:
|
||||
return CMP(a->address.in.s_addr, b->address.in.s_addr);
|
||||
|
||||
case TABLE_IN6_ADDR:
|
||||
return memcmp(&a->address.in6, &b->address.in6, FAMILY_ADDRESS_SIZE(AF_INET6));
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
@ -1129,6 +1218,30 @@ static const char *table_data_format(TableData *d) {
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_INT8: {
|
||||
_cleanup_free_ char *p;
|
||||
|
||||
p = new(char, DECIMAL_STR_WIDTH(d->int8) + 1);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
sprintf(p, "%" PRIi8, d->int8);
|
||||
d->formatted = TAKE_PTR(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_INT16: {
|
||||
_cleanup_free_ char *p;
|
||||
|
||||
p = new(char, DECIMAL_STR_WIDTH(d->int16) + 1);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
sprintf(p, "%" PRIi16, d->int16);
|
||||
d->formatted = TAKE_PTR(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_INT32: {
|
||||
_cleanup_free_ char *p;
|
||||
|
||||
@ -1165,6 +1278,30 @@ static const char *table_data_format(TableData *d) {
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_UINT8: {
|
||||
_cleanup_free_ char *p;
|
||||
|
||||
p = new(char, DECIMAL_STR_WIDTH(d->uint8) + 1);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
sprintf(p, "%" PRIu8, d->uint8);
|
||||
d->formatted = TAKE_PTR(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_UINT16: {
|
||||
_cleanup_free_ char *p;
|
||||
|
||||
p = new(char, DECIMAL_STR_WIDTH(d->uint16) + 1);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
sprintf(p, "%" PRIu16, d->uint16);
|
||||
d->formatted = TAKE_PTR(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_UINT32: {
|
||||
_cleanup_free_ char *p;
|
||||
|
||||
@ -1202,7 +1339,7 @@ static const char *table_data_format(TableData *d) {
|
||||
}
|
||||
|
||||
case TABLE_IFINDEX: {
|
||||
_cleanup_free_ char *p;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
char name[IF_NAMESIZE + 1];
|
||||
|
||||
if (format_ifname(d->ifindex, name)) {
|
||||
@ -1218,6 +1355,18 @@ static const char *table_data_format(TableData *d) {
|
||||
break;
|
||||
}
|
||||
|
||||
case TABLE_IN_ADDR:
|
||||
case TABLE_IN6_ADDR: {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
if (in_addr_to_string(d->type == TABLE_IN_ADDR ? AF_INET : AF_INET6,
|
||||
&d->address, &p) < 0)
|
||||
return NULL;
|
||||
|
||||
d->formatted = TAKE_PTR(p);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert_not_reached("Unexpected type?");
|
||||
}
|
||||
@ -1728,6 +1877,12 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
|
||||
case TABLE_INT:
|
||||
return json_variant_new_integer(ret, d->int_val);
|
||||
|
||||
case TABLE_INT8:
|
||||
return json_variant_new_integer(ret, d->int8);
|
||||
|
||||
case TABLE_INT16:
|
||||
return json_variant_new_integer(ret, d->int16);
|
||||
|
||||
case TABLE_INT32:
|
||||
return json_variant_new_integer(ret, d->int32);
|
||||
|
||||
@ -1737,6 +1892,12 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
|
||||
case TABLE_UINT:
|
||||
return json_variant_new_unsigned(ret, d->uint_val);
|
||||
|
||||
case TABLE_UINT8:
|
||||
return json_variant_new_unsigned(ret, d->uint8);
|
||||
|
||||
case TABLE_UINT16:
|
||||
return json_variant_new_unsigned(ret, d->uint16);
|
||||
|
||||
case TABLE_UINT32:
|
||||
return json_variant_new_unsigned(ret, d->uint32);
|
||||
|
||||
@ -1749,6 +1910,12 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
|
||||
case TABLE_IFINDEX:
|
||||
return json_variant_new_integer(ret, d->ifindex);
|
||||
|
||||
case TABLE_IN_ADDR:
|
||||
return json_variant_new_array_bytes(ret, &d->address, FAMILY_ADDRESS_SIZE(AF_INET));
|
||||
|
||||
case TABLE_IN6_ADDR:
|
||||
return json_variant_new_array_bytes(ret, &d->address, FAMILY_ADDRESS_SIZE(AF_INET6));
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -20,13 +20,19 @@ typedef enum TableDataType {
|
||||
TABLE_SIZE,
|
||||
TABLE_BPS,
|
||||
TABLE_INT,
|
||||
TABLE_INT8,
|
||||
TABLE_INT16,
|
||||
TABLE_INT32,
|
||||
TABLE_INT64,
|
||||
TABLE_UINT,
|
||||
TABLE_UINT8,
|
||||
TABLE_UINT16,
|
||||
TABLE_UINT32,
|
||||
TABLE_UINT64,
|
||||
TABLE_PERCENT,
|
||||
TABLE_IFINDEX,
|
||||
TABLE_IN_ADDR, /* Takes a union in_addr_union (or a struct in_addr) */
|
||||
TABLE_IN6_ADDR, /* Takes a union in_addr_union (or a struct in6_addr) */
|
||||
_TABLE_DATA_TYPE_MAX,
|
||||
|
||||
/* The following are not really data types, but commands for table_add_cell_many() to make changes to
|
||||
|
@ -705,6 +705,12 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'stp_state')))
|
||||
self.assertEqual(3, int(read_link_attr('bridge99', 'bridge', 'multicast_igmp_version')))
|
||||
|
||||
output = check_output(*networkctl_cmd, 'status', 'bridge99')
|
||||
print(output)
|
||||
self.assertRegex(output, 'Priority: 9')
|
||||
self.assertRegex(output, 'STP: yes')
|
||||
self.assertRegex(output, 'Multicast IGMP Version: 3')
|
||||
|
||||
def test_bond(self):
|
||||
copy_unit_to_networkd_unit_path('25-bond.netdev', '25-bond-balanced-tlb.netdev')
|
||||
start_networkd()
|
||||
@ -1266,6 +1272,12 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, '00:11:22:33:44:66 dst 10.0.0.6 self permanent')
|
||||
self.assertRegex(output, '00:11:22:33:44:77 dst 10.0.0.7 self permanent')
|
||||
|
||||
output = check_output(*networkctl_cmd, 'status', 'vxlan99')
|
||||
print(output)
|
||||
self.assertRegex(output, 'VNI: 999')
|
||||
self.assertRegex(output, 'Destination Port: 5555')
|
||||
self.assertRegex(output, 'Underlying Device: test1')
|
||||
|
||||
def test_macsec(self):
|
||||
copy_unit_to_networkd_unit_path('25-macsec.netdev', '25-macsec.network', '25-macsec.key',
|
||||
'macsec.network', '12-dummy.netdev')
|
||||
|
Loading…
x
Reference in New Issue
Block a user