typedef struct LinkInfo {
char name[IFNAMSIZ+1];
char netdev_kind[NETDEV_KIND_MAX];
+ sd_device *sd_device;
int ifindex;
unsigned short iftype;
struct ether_addr mac_address;
bool has_stats:1;
bool has_bitrates:1;
bool has_ethtool_link_info:1;
+
+ bool needs_freeing:1;
} LinkInfo;
static int link_info_compare(const LinkInfo *a, const LinkInfo *b) {
return CMP(a->ifindex, b->ifindex);
}
+static const LinkInfo* link_info_array_free(LinkInfo *array) {
+ for (unsigned i = 0; array && array[i].needs_freeing; i++) {
+ sd_device_unref(array[i].sd_device);
+ }
+
+ return mfree(array);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(LinkInfo*, link_info_array_free);
+
static int decode_netdev(sd_netlink_message *m, LinkInfo *info) {
const char *received_kind;
int r;
static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, LinkInfo **ret) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
- _cleanup_free_ LinkInfo *links = NULL;
+ _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
_cleanup_close_ int fd = -1;
size_t allocated = 0, c = 0, j;
sd_netlink_message *i;
return log_error_errno(r, "Failed to enumerate links: %m");
for (i = reply; i; i = sd_netlink_message_next(i)) {
- if (!GREEDY_REALLOC0(links, allocated, c+1))
+ if (!GREEDY_REALLOC0(links, allocated, c + 2)) /* We keep one trailing one as marker */
return -ENOMEM;
r = decode_link(i, links + c, patterns);
if (r == 0)
continue;
+ links[c].needs_freeing = true;
+
+ char devid[2 + DECIMAL_STR_MAX(int)];
+ xsprintf(devid, "n%i", links[c].ifindex);
+ (void) sd_device_new_from_device_id(&links[c].sd_device, devid);
+
acquire_ether_link_info(&fd, &links[c]);
c++;
static int list_links(int argc, char *argv[], void *userdata) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
- _cleanup_free_ LinkInfo *links = NULL;
+ _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
TableCell *cell;
int c, i, r;
for (i = 0; i < c; i++) {
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
- _cleanup_(sd_device_unrefp) sd_device *d = NULL;
const char *on_color_operational, *off_color_operational,
*on_color_setup, *off_color_setup;
- char devid[2 + DECIMAL_STR_MAX(int)];
_cleanup_free_ char *t = NULL;
(void) sd_network_link_get_operational_state(links[i].ifindex, &operational_state);
setup_state = strdup("unmanaged");
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
- xsprintf(devid, "n%i", links[i].ifindex);
- (void) sd_device_new_from_device_id(&d, devid);
-
- t = link_get_type_string(links[i].iftype, d);
+ t = link_get_type_string(links[i].iftype, links[i].sd_device);
r = table_add_many(table,
TABLE_INT, links[i].ifindex,
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
- _cleanup_(sd_device_unrefp) sd_device *d = NULL;
- char devid[2 + DECIMAL_STR_MAX(int)];
_cleanup_free_ char *t = NULL, *network = NULL;
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
const char *on_color_operational, *off_color_operational,
(void) sd_network_link_get_route_domains(info->ifindex, &route_domains);
(void) sd_network_link_get_ntp(info->ifindex, &ntp);
- xsprintf(devid, "n%i", info->ifindex);
-
- (void) sd_device_new_from_device_id(&d, devid);
-
- if (d) {
- (void) sd_device_get_property_value(d, "ID_NET_LINK_FILE", &link);
- (void) sd_device_get_property_value(d, "ID_NET_DRIVER", &driver);
- (void) sd_device_get_property_value(d, "ID_PATH", &path);
+ if (info->sd_device) {
+ (void) sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE", &link);
+ (void) sd_device_get_property_value(info->sd_device, "ID_NET_DRIVER", &driver);
+ (void) sd_device_get_property_value(info->sd_device, "ID_PATH", &path);
- if (sd_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE", &vendor) < 0)
- (void) sd_device_get_property_value(d, "ID_VENDOR", &vendor);
+ if (sd_device_get_property_value(info->sd_device, "ID_VENDOR_FROM_DATABASE", &vendor) < 0)
+ (void) sd_device_get_property_value(info->sd_device, "ID_VENDOR", &vendor);
- if (sd_device_get_property_value(d, "ID_MODEL_FROM_DATABASE", &model) < 0)
- (void) sd_device_get_property_value(d, "ID_MODEL", &model);
+ if (sd_device_get_property_value(info->sd_device, "ID_MODEL_FROM_DATABASE", &model) < 0)
+ (void) sd_device_get_property_value(info->sd_device, "ID_MODEL", &model);
}
- t = link_get_type_string(info->iftype, d);
+ t = link_get_type_string(info->iftype, info->sd_device);
(void) sd_network_link_get_network_file(info->ifindex, &network);
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
_cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
- _cleanup_free_ LinkInfo *links = NULL;
+ _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
int r, c, i;
(void) pager_open(arg_pager_flags);
static int link_lldp_status(int argc, char *argv[], void *userdata) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
- _cleanup_free_ LinkInfo *links = NULL;
+ _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
int i, r, c, m = 0;
uint16_t all = 0;