aboutsummaryrefslogtreecommitdiff
path: root/sbin/ifconfig/ifconfig_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/ifconfig/ifconfig_netlink.c')
-rw-r--r--sbin/ifconfig/ifconfig_netlink.c79
1 files changed, 48 insertions, 31 deletions
diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c
index 76dd99307f31..b5badfd585b8 100644
--- a/sbin/ifconfig/ifconfig_netlink.c
+++ b/sbin/ifconfig/ifconfig_netlink.c
@@ -25,6 +25,8 @@
* SUCH DAMAGE.
*/
+#define _WANT_IFCAP_BIT_NAMES
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -77,34 +79,11 @@ static const char *IFFBITS[] = {
"STICKYARP", /* 20:0x100000 IFF_STICKYARP*/
"DYING", /* 21:0x200000 IFF_DYING*/
"RENAMING", /* 22:0x400000 IFF_RENAMING*/
- "NOGROUP", /* 23:0x800000 IFF_NOGROUP*/
+ "PALLMULTI", /* 23:0x800000 IFF_PALLMULTI*/
"LOWER_UP", /* 24:0x1000000 IFF_NETLINK_1*/
};
static void
-print_bits(const char *btype, uint32_t *v, const int v_count,
- const char **names, const int n_count)
-{
- int num = 0;
-
- for (int i = 0; i < v_count * 32; i++) {
- bool is_set = v[i / 32] & (1U << (i % 32));
- if (is_set) {
- if (num++ == 0)
- printf("<");
- if (num != 1)
- printf(",");
- if (i < n_count)
- printf("%s", names[i]);
- else
- printf("%s_%d", btype, i);
- }
- }
- if (num > 0)
- printf(">");
-}
-
-static void
nl_init_socket(struct snl_state *ss)
{
if (snl_init(ss, NETLINK_ROUTE))
@@ -162,7 +141,7 @@ struct ifmap {
* Memory is allocated using snl temporary buffers
*/
static struct ifmap *
-prepare_ifmap(struct snl_state *ss)
+prepare_ifmap(struct snl_state *ss, const char *ifname)
{
struct snl_writer nw = {};
@@ -170,8 +149,10 @@ prepare_ifmap(struct snl_state *ss)
struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETLINK);
hdr->nlmsg_flags |= NLM_F_DUMP;
snl_reserve_msg_object(&nw, struct ifinfomsg);
+ if (ifname != NULL)
+ snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname);
- if (!snl_finalize_msg(&nw) || !snl_send_message(ss, hdr))
+ if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr))
return (NULL);
uint32_t nlmsg_seq = hdr->nlmsg_seq;
@@ -212,7 +193,7 @@ if_nametoindex_nl(struct snl_state *ss, const char *ifname)
snl_reserve_msg_object(&nw, struct ifinfomsg);
snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname);
- if (!snl_finalize_msg(&nw) || !snl_send_message(ss, hdr))
+ if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr))
return (0);
hdr = snl_read_reply(ss, hdr->nlmsg_seq);
@@ -224,6 +205,19 @@ if_nametoindex_nl(struct snl_state *ss, const char *ifname)
return (link.ifi_index);
}
+ifType
+convert_iftype(ifType iftype)
+{
+ switch (iftype) {
+ case IFT_IEEE8023ADLAG:
+ return (IFT_ETHER);
+ case IFT_INFINIBANDLAG:
+ return (IFT_INFINIBAND);
+ default:
+ return (iftype);
+ }
+}
+
static void
prepare_ifaddrs(struct snl_state *ss, struct ifmap *ifmap)
{
@@ -234,7 +228,7 @@ prepare_ifaddrs(struct snl_state *ss, struct ifmap *ifmap)
hdr->nlmsg_flags |= NLM_F_DUMP;
snl_reserve_msg_object(&nw, struct ifaddrmsg);
- if (!snl_finalize_msg(&nw) || !snl_send_message(ss, hdr))
+ if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr))
return;
uint32_t nlmsg_seq = hdr->nlmsg_seq;
@@ -282,11 +276,17 @@ match_iface(struct ifconfig_args *args, struct iface *iface)
struct sockaddr_dl sdl = {
.sdl_len = sizeof(struct sockaddr_dl),
.sdl_family = AF_LINK,
- .sdl_type = link->ifi_type,
+ .sdl_type = convert_iftype(link->ifi_type),
.sdl_alen = NLA_DATA_LEN(link->ifla_address),
};
return (match_ether(&sdl));
- }
+ } else if (args->afp->af_af == AF_LINK)
+ /*
+ * The rtnetlink(4) RTM_GETADDR does not list link level
+ * addresses, so latter cycle won't match anything. Short
+ * circuit on RTM_GETLINK has provided us an address.
+ */
+ return (link->ifla_address != NULL);
for (struct ifa *ifa = iface->ifa; ifa != NULL; ifa = ifa->next) {
if (args->afp->af_af == ifa->addr.ifa_family)
@@ -369,6 +369,7 @@ status_nl(if_ctx *ctx, struct iface *iface)
{
if_link_t *link = &iface->link;
struct ifconfig_args *args = ctx->args;
+ char *drivername = NULL;
printf("%s: ", link->ifla_ifname);
@@ -413,6 +414,22 @@ status_nl(if_ctx *ctx, struct iface *iface)
args->afp->af_other_status(ctx);
print_ifstatus(ctx);
+ if (args->drivername || args->verbose) {
+ if (ifconfig_get_orig_name(lifh, link->ifla_ifname,
+ &drivername) != 0) {
+ if (ifconfig_err_errtype(lifh) == OTHER)
+ fprintf(stderr, "get original name: %s\n",
+ strerror(ifconfig_err_errno(lifh)));
+ else
+ fprintf(stderr,
+ "get original name: error type %d\n",
+ ifconfig_err_errtype(lifh));
+ exit_code = 1;
+ }
+ if (drivername != NULL)
+ printf("\tdrivername: %s\n", drivername);
+ free(drivername);
+ }
if (args->verbose > 0)
sfp_status(ctx);
}
@@ -440,7 +457,7 @@ list_interfaces_nl(struct ifconfig_args *args)
nl_init_socket(&ss);
- struct ifmap *ifmap = prepare_ifmap(&ss);
+ struct ifmap *ifmap = prepare_ifmap(&ss, args->ifname);
struct iface **sorted_ifaces = snl_allocz(&ss, ifmap->count * sizeof(void *));
for (uint32_t i = 0, num = 0; i < ifmap->size; i++) {
if (ifmap->ifaces[i] != NULL) {