diff options
-rw-r--r-- | sys/net/if.c | 42 | ||||
-rw-r--r-- | sys/net/if_var.h | 24 |
2 files changed, 64 insertions, 2 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 0d1c51d0ad8..864bc23d833 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.568 2018/11/29 00:11:49 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.569 2018/12/11 22:08:57 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -84,6 +84,7 @@ #include <sys/domain.h> #include <sys/task.h> #include <sys/atomic.h> +#include <sys/percpu.h> #include <sys/proc.h> #include <dev/rndvar.h> @@ -1103,6 +1104,9 @@ if_detach(struct ifnet *ifp) splx(s); NET_UNLOCK(); + if (ifp->if_counters != NULL) + if_counters_free(ifp); + for (i = 0; i < ifp->if_nifqs; i++) ifq_destroy(ifp->if_ifqs[i]); if (ifp->if_ifqs != ifp->if_snd.ifq_ifqs) { @@ -2362,12 +2366,48 @@ ifconf(caddr_t data) } void +if_counters_alloc(struct ifnet *ifp) +{ + KASSERT(ifp->if_counters == NULL); + + ifp->if_counters = counters_alloc(ifc_ncounters); +} + +void +if_counters_free(struct ifnet *ifp) +{ + KASSERT(ifp->if_counters != NULL); + + counters_free(ifp->if_counters, ifc_ncounters); + ifp->if_counters = NULL; +} + +void if_getdata(struct ifnet *ifp, struct if_data *data) { unsigned int i; *data = ifp->if_data; + if (ifp->if_counters != NULL) { + uint64_t counters[ifc_ncounters]; + + counters_read(ifp->if_counters, counters, nitems(counters)); + + data->ifi_ipackets += counters[ifc_ipackets]; + data->ifi_ierrors += counters[ifc_ierrors]; + data->ifi_opackets += counters[ifc_opackets]; + data->ifi_oerrors += counters[ifc_oerrors]; + data->ifi_collisions += counters[ifc_collisions]; + data->ifi_ibytes += counters[ifc_ibytes]; + data->ifi_obytes += counters[ifc_obytes]; + data->ifi_imcasts += counters[ifc_imcasts]; + data->ifi_omcasts += counters[ifc_omcasts]; + data->ifi_iqdrops += counters[ifc_iqdrops]; + data->ifi_oqdrops += counters[ifc_oqdrops]; + data->ifi_noproto += counters[ifc_noproto]; + } + for (i = 0; i < ifp->if_nifqs; i++) { struct ifqueue *ifq = ifp->if_ifqs[i]; diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 564b59037fd..f1deddb3994 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.90 2018/09/10 16:18:34 sashan Exp $ */ +/* $OpenBSD: if_var.h,v 1.91 2018/12/11 22:08:57 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -76,6 +76,7 @@ struct rtentry; struct ifnet; struct task; +struct cpumem; /* * Structure describing a `cloning' interface. @@ -144,6 +145,7 @@ struct ifnet { /* and the entries */ unsigned short if_flags; /* [N] up/down, broadcast, etc. */ int if_xflags; /* [N] extra softnet flags */ struct if_data if_data; /* stats and other data about if */ + struct cpumem *if_counters; /* per cpu stats */ uint32_t if_hardmtu; /* [d] maximum MTU device supports */ char if_description[IFDESCRSIZE]; /* [c] interface description */ u_short if_rtlabelid; /* [c] next route label */ @@ -202,6 +204,23 @@ struct ifnet { /* and the entries */ #define if_capabilities if_data.ifi_capabilities #define if_rdomain if_data.ifi_rdomain +enum if_counters { + ifc_ipackets, /* packets received on interface */ + ifc_ierrors, /* input errors on interface */ + ifc_opackets, /* packets sent on interface */ + ifc_oerrors, /* output errors on interface */ + ifc_collisions, /* collisions on csma interfaces */ + ifc_ibytes, /* total number of octets received */ + ifc_obytes, /* total number of octets sent */ + ifc_imcasts, /* packets received via multicast */ + ifc_omcasts, /* packets sent via multicast */ + ifc_iqdrops, /* dropped on input, this interface */ + ifc_oqdrops, /* dropped on output, this interface */ + ifc_noproto, /* destined for unsupported protocol */ + + ifc_ncounters +}; + /* * The ifaddr structure contains information about one address * of an interface. They are maintained by the different address families, @@ -357,6 +376,9 @@ int if_rxr_info_ioctl(struct if_rxrinfo *, u_int, struct if_rxring_info *); int if_rxr_ioctl(struct if_rxrinfo *, const char *, u_int, struct if_rxring *); +void if_counters_alloc(struct ifnet *); +void if_counters_free(struct ifnet *); + #endif /* _KERNEL */ #endif /* _NET_IF_VAR_H_ */ |