Module Name: src Committed By: roy Date: Tue Sep 22 14:14:17 UTC 2020
Modified Files: src/sbin/ifconfig: ifconfig.c media.c media.h src/sys/net: if.h Log Message: ifconfig: Report link state even if media is not supported For AF_LINK addrs from getifaddrs(2), ifa_data is struct if_data. This in turn holds ifi_link_state which we can use to report link status if the interface does not support media where it's normally reported. Based on OpenBSD. To generate a diff of this commit: cvs rdiff -u -r1.242 -r1.243 src/sbin/ifconfig/ifconfig.c cvs rdiff -u -r1.9 -r1.10 src/sbin/ifconfig/media.c cvs rdiff -u -r1.1 -r1.2 src/sbin/ifconfig/media.h cvs rdiff -u -r1.284 -r1.285 src/sys/net/if.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/ifconfig/ifconfig.c diff -u src/sbin/ifconfig/ifconfig.c:1.242 src/sbin/ifconfig/ifconfig.c:1.243 --- src/sbin/ifconfig/ifconfig.c:1.242 Sun Jun 7 06:02:58 2020 +++ src/sbin/ifconfig/ifconfig.c Tue Sep 22 14:14:17 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ifconfig.c,v 1.242 2020/06/07 06:02:58 thorpej Exp $ */ +/* $NetBSD: ifconfig.c,v 1.243 2020/09/22 14:14:17 roy Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ #ifndef lint __COPYRIGHT("@(#) Copyright (c) 1983, 1993\ The Regents of the University of California. All rights reserved."); -__RCSID("$NetBSD: ifconfig.c,v 1.242 2020/06/07 06:02:58 thorpej Exp $"); +__RCSID("$NetBSD: ifconfig.c,v 1.243 2020/09/22 14:14:17 roy Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -135,7 +135,7 @@ static int setlinkstr(prop_dictionary_t, static int unsetlinkstr(prop_dictionary_t, prop_dictionary_t); static int setifdescr(prop_dictionary_t, prop_dictionary_t); static int unsetifdescr(prop_dictionary_t, prop_dictionary_t); -static void status(const struct sockaddr *, prop_dictionary_t, +static void status(const struct sockaddr_dl *, prop_dictionary_t, prop_dictionary_t); __dead static void usage(void); @@ -851,7 +851,7 @@ printall(const char *ifname, prop_dictio { struct ifaddrs *ifap, *ifa; struct ifreq ifr; - const struct sockaddr *sdl = NULL; + const struct sockaddr_dl *sdl = NULL; prop_dictionary_t env, oenv; int idx; char *p; @@ -881,7 +881,7 @@ printall(const char *ifname, prop_dictio if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) continue; if (ifa->ifa_addr->sa_family == AF_LINK) - sdl = ifa->ifa_addr; + sdl = (const struct sockaddr_dl *)ifa->ifa_addr; if (p && strcmp(p, ifa->ifa_name) == 0) continue; if (!prop_dictionary_set_string(env, "if", ifa->ifa_name)) @@ -1265,7 +1265,7 @@ print_human_bytes(bool humanize, uint64_ #define MAX_PRINT_LEN 58 /* XXX need a better way to determine this! */ void -status(const struct sockaddr *sdl, prop_dictionary_t env, +status(const struct sockaddr_dl *sdl, prop_dictionary_t env, prop_dictionary_t oenv) { const struct if_data *ifi; @@ -1360,11 +1360,6 @@ status(const struct sockaddr *sdl, prop_ free(p); } - media_status(env, oenv); - - if (!vflag && !zflag) - goto proto_status; - estrlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name)); if (prog_ioctl(s, zflag ? SIOCZIFDATA : SIOCGIFDATA, &ifdr) == -1) @@ -1372,6 +1367,11 @@ status(const struct sockaddr *sdl, prop_ ifi = &ifdr.ifdr_data; + media_status(sdl->sdl_type, ifi->ifi_link_state, env, oenv); + + if (!vflag && !zflag) + goto proto_status; + print_plural("\tinput: ", ifi->ifi_ipackets, "packet"); print_human_bytes(hflag, ifi->ifi_ibytes); if (ifi->ifi_imcasts) Index: src/sbin/ifconfig/media.c diff -u src/sbin/ifconfig/media.c:1.9 src/sbin/ifconfig/media.c:1.10 --- src/sbin/ifconfig/media.c:1.9 Sun Jun 7 06:02:58 2020 +++ src/sbin/ifconfig/media.c Tue Sep 22 14:14:17 2020 @@ -1,6 +1,6 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: media.c,v 1.9 2020/06/07 06:02:58 thorpej Exp $"); +__RCSID("$NetBSD: media.c,v 1.10 2020/09/22 14:14:17 roy Exp $"); #endif /* not lint */ #include <assert.h> @@ -16,6 +16,7 @@ __RCSID("$NetBSD: media.c,v 1.9 2020/06/ #include <net/if.h> #include <net/if_dl.h> #include <net/if_media.h> +#include <net/if_types.h> #include <prop/proplib.h> @@ -52,6 +53,9 @@ static const int ifm_status_valid_list[] static const struct ifmedia_status_description ifm_status_descriptions[] = IFM_STATUS_DESCRIPTIONS; +const struct if_status_description if_status_descriptions[] = + LINK_STATE_DESCRIPTIONS; + static struct pstr mediamode = PSTR_INITIALIZER1(&mediamode, "mediamode", setmediamode, "mediamode", false, &command_root.pb_parser); @@ -344,8 +348,55 @@ print_media_word(int ifmw, const char *o printf(" instance %d", IFM_INST(ifmw)); } +static void +print_link_status(int media_type, int link_state) +{ + const struct if_status_description *p; + + printf("\tstatus: "); + for (p = if_status_descriptions; p->ifs_string != NULL; p++) { + if (LINK_STATE_DESC_MATCH(p, media_type, link_state)) { + printf("%s\n", p->ifs_string); + return; + } + } + printf("[#%d]\n", link_state); +} + +static void +print_media_status(int media_type, int media_status) +{ + const struct ifmedia_status_description *ifms; + int bitno, found = 0; + + printf("\tstatus: "); + for (bitno = 0; ifm_status_valid_list[bitno] != 0; bitno++) { + for (ifms = ifm_status_descriptions; + ifms->ifms_valid != 0; ifms++) { + if (ifms->ifms_type != media_type || + ifms->ifms_valid != ifm_status_valid_list[bitno]) + continue; + printf("%s%s", found ? ", " : "", + IFM_STATUS_DESC(ifms, media_status)); + found = 1; + + /* + * For each valid indicator bit, there's + * only one entry for each media type, so + * terminate the inner loop now. + */ + break; + } + } + + if (found == 0) + printf("unknown"); + printf("\n"); +} + void -media_status(prop_dictionary_t env, prop_dictionary_t oenv) +media_status(int media_type, int link_state, + prop_dictionary_t env, prop_dictionary_t oenv) { struct ifmediareq ifmr; int af, i, s; @@ -368,6 +419,8 @@ media_status(prop_dictionary_t env, prop /* * Interface doesn't support SIOC{G,S}IFMEDIA. */ + if (link_state != LINK_STATE_UNKNOWN) + print_link_status(media_type, link_state); return; } @@ -393,36 +446,8 @@ media_status(prop_dictionary_t env, prop } else media_list = NULL; - if (ifmr.ifm_status & IFM_STATUS_VALID) { - const struct ifmedia_status_description *ifms; - int bitno, found = 0; - - printf("\tstatus: "); - for (bitno = 0; ifm_status_valid_list[bitno] != 0; bitno++) { - for (ifms = ifm_status_descriptions; - ifms->ifms_valid != 0; ifms++) { - if (ifms->ifms_type != - IFM_TYPE(ifmr.ifm_current) || - ifms->ifms_valid != - ifm_status_valid_list[bitno]) - continue; - printf("%s%s", found ? ", " : "", - IFM_STATUS_DESC(ifms, ifmr.ifm_status)); - found = 1; - - /* - * For each valid indicator bit, there's - * only one entry for each media type, so - * terminate the inner loop now. - */ - break; - } - } - - if (found == 0) - printf("unknown"); - printf("\n"); - } + if (ifmr.ifm_status & IFM_STATUS_VALID) + print_media_status(IFM_TYPE(ifmr.ifm_current), ifmr.ifm_status); if (get_flag('m')) { int type, printed_type; Index: src/sbin/ifconfig/media.h diff -u src/sbin/ifconfig/media.h:1.1 src/sbin/ifconfig/media.h:1.2 --- src/sbin/ifconfig/media.h:1.1 Wed Jul 2 07:44:15 2008 +++ src/sbin/ifconfig/media.h Tue Sep 22 14:14:17 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: media.h,v 1.1 2008/07/02 07:44:15 dyoung Exp $ */ +/* $NetBSD: media.h,v 1.2 2020/09/22 14:14:17 roy Exp $ */ #ifndef _IFCONFIG_MEDIA_H #define _IFCONFIG_MEDIA_H @@ -11,6 +11,6 @@ extern struct pkw kwmedia; void print_media_word(int, const char *); void process_media_commands(prop_dictionary_t); -void media_status(prop_dictionary_t, prop_dictionary_t); +void media_status(int, int, prop_dictionary_t, prop_dictionary_t); #endif /* _IFCONFIG_MEDIA_H */ Index: src/sys/net/if.h diff -u src/sys/net/if.h:1.284 src/sys/net/if.h:1.285 --- src/sys/net/if.h:1.284 Fri Aug 28 06:23:42 2020 +++ src/sys/net/if.h Tue Sep 22 14:14:17 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if.h,v 1.284 2020/08/28 06:23:42 ozaki-r Exp $ */ +/* $NetBSD: if.h,v 1.285 2020/09/22 14:14:17 roy Exp $ */ /*- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -208,6 +208,31 @@ struct if_data { #define LINK_STATE_UP 2 /* link is up */ /* + * Status bit descriptions for the various interface types. + */ +struct if_status_description { + unsigned char ifs_type; + unsigned char ifs_state; + const char *ifs_string; +}; + +#define LINK_STATE_DESC_MATCH(_ifs, _t, _s) \ + (((_ifs)->ifs_type == (_t) || (_ifs)->ifs_type == 0) && \ + (_ifs)->ifs_state == (_s)) + +#define LINK_STATE_DESCRIPTIONS { \ + { IFT_ETHER, LINK_STATE_DOWN, "no carrier" }, \ + { IFT_IEEE80211, LINK_STATE_DOWN, "no network" }, \ + { IFT_PPP, LINK_STATE_DOWN, "no carrier" }, \ + { IFT_CARP, LINK_STATE_DOWN, "backup" }, \ + { IFT_CARP, LINK_STATE_UP, "master" }, \ + { 0, LINK_STATE_UP, "active" }, \ + { 0, LINK_STATE_UNKNOWN, "unknown" }, \ + { 0, LINK_STATE_DOWN, "down" }, \ + { 0, 0, NULL } \ +} + +/* * Structure defining a queue for a network interface. */ struct ifqueue {