diff options
Diffstat (limited to 'sbin/ifconfig/ifconfig_netlink.c')
-rw-r--r-- | sbin/ifconfig/ifconfig_netlink.c | 79 |
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) { |