diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-09-15 05:20:04 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-10-06 09:39:52 +0200 |
commit | 6ebc6a45602966e32c48643fba17a03e0f8dc569 (patch) | |
tree | 1e86349f135c71d0f60bc736e91e4b9285e4e365 /src/udev/udev-netlink.c | |
parent | ether-addr-util: make hw_addr_to_string() return valid string even if hardwar... (diff) | |
download | systemd-6ebc6a45602966e32c48643fba17a03e0f8dc569.tar.xz systemd-6ebc6a45602966e32c48643fba17a03e0f8dc569.zip |
udev: rename udev-builtin-net_id-netlink.[ch]
Diffstat (limited to 'src/udev/udev-netlink.c')
-rw-r--r-- | src/udev/udev-netlink.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/udev/udev-netlink.c b/src/udev/udev-netlink.c new file mode 100644 index 0000000000..4c93934e3e --- /dev/null +++ b/src/udev/udev-netlink.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "netlink-util.h" +#include "udev-netlink.h" + +void link_info_clear(LinkInfo *info) { + if (!info) + return; + + info->ifname = mfree(info->ifname); + info->phys_port_name = mfree(info->phys_port_name); +} + +int link_info_get(sd_netlink **rtnl, int ifindex, LinkInfo *ret) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; + _cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL; + uint16_t nlmsg_type; + int r; + + assert(rtnl); + assert(ifindex > 0); + assert(ret); + + if (!*rtnl) { + r = sd_netlink_open(rtnl); + if (r < 0) + return r; + } + + r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex); + if (r < 0) + return r; + + r = sd_netlink_call(*rtnl, message, 0, &reply); + if (r == -EINVAL) + return -ENODEV; /* The device does not exist */ + if (r < 0) + return r; + + r = sd_netlink_message_get_type(reply, &nlmsg_type); + if (r < 0) + return r; + if (nlmsg_type != RTM_NEWLINK) + return -ENXIO; + + r = sd_rtnl_message_link_get_ifindex(reply, &info.ifindex); + if (r < 0) + return r; + if (info.ifindex != ifindex) + return -ENXIO; + + r = sd_rtnl_message_link_get_type(reply, &info.iftype); + if (r < 0) + return r; + + r = netlink_message_read_hw_addr(reply, IFLA_ADDRESS, &info.hw_addr); + if (r < 0 && r != -ENODATA) + return r; + + r = sd_netlink_message_read_string_strdup(reply, IFLA_IFNAME, &info.ifname); + if (r < 0) + return r; + + r = sd_netlink_message_read_u32(reply, IFLA_LINK, &info.iflink); + if (r == -ENODATA) + info.iflink = info.ifindex; + else if (r < 0) + return r; + + r = sd_netlink_message_read_string_strdup(reply, IFLA_PHYS_PORT_NAME, &info.phys_port_name); + if (r == -ENODATA) { + uint16_t max_attr; + + r = sd_netlink_message_get_max_attribute(reply, &max_attr); + if (r < 0) + return r; + + info.support_phys_port_name = max_attr >= IFLA_PHYS_PORT_NAME; + } else if (r >= 0) + info.support_phys_port_name = true; + else + return r; + + *ret = info; + info = LINK_INFO_NULL; + return 0; +} |