Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src ifconfig: Report link state even if media is not supported
details: https://anonhg.NetBSD.org/src/rev/3747f0c5f789
branches: trunk
changeset: 938974:3747f0c5f789
user: roy <roy%NetBSD.org@localhost>
date: Tue Sep 22 14:14:17 2020 +0000
description:
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.
diffstat:
sbin/ifconfig/ifconfig.c | 22 +++++-----
sbin/ifconfig/media.c | 89 ++++++++++++++++++++++++++++++-----------------
sbin/ifconfig/media.h | 4 +-
sys/net/if.h | 27 ++++++++++++++-
4 files changed, 96 insertions(+), 46 deletions(-)
diffs (270 lines):
diff -r 88e29edb1128 -r 3747f0c5f789 sbin/ifconfig/ifconfig.c
--- a/sbin/ifconfig/ifconfig.c Tue Sep 22 12:21:11 2020 +0000
+++ b/sbin/ifconfig/ifconfig.c Tue Sep 22 14:14:17 2020 +0000
@@ -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 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 @@
{
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 @@
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 @@
#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 @@
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 @@
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)
diff -r 88e29edb1128 -r 3747f0c5f789 sbin/ifconfig/media.c
--- a/sbin/ifconfig/media.c Tue Sep 22 12:21:11 2020 +0000
+++ b/sbin/ifconfig/media.c Tue Sep 22 14:14:17 2020 +0000
@@ -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 @@
#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 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 @@
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 @@
/*
* 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 @@
} 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;
diff -r 88e29edb1128 -r 3747f0c5f789 sbin/ifconfig/media.h
--- a/sbin/ifconfig/media.h Tue Sep 22 12:21:11 2020 +0000
+++ b/sbin/ifconfig/media.h Tue Sep 22 14:14:17 2020 +0000
@@ -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 @@
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 */
diff -r 88e29edb1128 -r 3747f0c5f789 sys/net/if.h
--- a/sys/net/if.h Tue Sep 22 12:21:11 2020 +0000
+++ b/sys/net/if.h Tue Sep 22 14:14:17 2020 +0000
@@ -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 @@
#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 {
Home |
Main Index |
Thread Index |
Old Index