Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Introduce new sysctls for obtaining interface-specific addre...
details: https://anonhg.NetBSD.org/src/rev/608a54301520
branches: trunk
changeset: 796561:608a54301520
user: joerg <joerg%NetBSD.org@localhost>
date: Tue Jun 10 09:38:30 2014 +0000
description:
Introduce new sysctls for obtaining interface-specific addresses:
- net.sdl for the active link-layer adddress (the MAC)
- net.ether.multicast for the Ethernet multicast addresses
- net.inet6.multicast for the IPv6 multicast groups
- net.inet6.multicast_kludge for temporarily removed multicast groups
Use this sysctls for replacing the kmem grovelling in ifmcstat(8).
diffstat:
sys/net/if.c | 45 ++++++-
sys/net/if_ether.h | 8 +-
sys/net/if_ethersubr.c | 72 ++++++++++-
sys/netinet6/mld6.c | 147 ++++++++++++++++++++-
usr.sbin/ifmcstat/Makefile | 6 +-
usr.sbin/ifmcstat/ifmcstat.c | 301 ++++++++++++++++++++++--------------------
6 files changed, 423 insertions(+), 156 deletions(-)
diffs (truncated from 739 to 300 lines):
diff -r 8d5136b1f058 -r 608a54301520 sys/net/if.c
--- a/sys/net/if.c Tue Jun 10 07:26:19 2014 +0000
+++ b/sys/net/if.c Tue Jun 10 09:38:30 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.279 2014/06/09 12:57:04 rmind Exp $ */
+/* $NetBSD: if.c,v 1.280 2014/06/10 09:38:30 joerg Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.279 2014/06/09 12:57:04 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.280 2014/06/10 09:38:30 joerg Exp $");
#include "opt_inet.h"
@@ -2457,3 +2457,44 @@
CTL_NET, pf, ipn, qid, IFQCTL_DROPS, CTL_EOL);
}
#endif /* INET || INET6 */
+
+static int
+if_sdl_sysctl(SYSCTLFN_ARGS)
+{
+ struct ifnet *ifp;
+ const struct sockaddr_dl *sdl;
+
+ if (namelen != 1)
+ return EINVAL;
+
+ ifp = if_byindex(name[0]);
+ if (ifp == NULL)
+ return ENODEV;
+
+ sdl = ifp->if_sadl;
+ if (sdl == NULL) {
+ *oldlenp = 0;
+ return 0;
+ }
+
+ if (oldp == NULL) {
+ *oldlenp = sdl->sdl_alen;
+ return 0;
+ }
+
+ if (*oldlenp >= sdl->sdl_alen)
+ *oldlenp = sdl->sdl_alen;
+ return sysctl_copyout(l, &sdl->sdl_data[sdl->sdl_nlen], oldp, *oldlenp);
+}
+
+SYSCTL_SETUP(sysctl_net_sdl_setup, "sysctl net.sdl subtree setup")
+{
+ const struct sysctlnode *rnode = NULL;
+
+ sysctl_createv(clog, 0, NULL, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "sdl",
+ SYSCTL_DESCR("Get active link-layer address"),
+ if_sdl_sysctl, 0, NULL, 0,
+ CTL_NET, CTL_CREATE, CTL_EOL);
+}
diff -r 8d5136b1f058 -r 608a54301520 sys/net/if_ether.h
--- a/sys/net/if_ether.h Tue Jun 10 07:26:19 2014 +0000
+++ b/sys/net/if_ether.h Tue Jun 10 09:38:30 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ether.h,v 1.62 2014/04/23 23:17:22 pooka Exp $ */
+/* $NetBSD: if_ether.h,v 1.63 2014/06/10 09:38:30 joerg Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@@ -228,6 +228,12 @@
LIST_ENTRY(ether_multi) enm_list;
};
+struct ether_multi_sysctl {
+ u_int enm_refcount;
+ uint8_t enm_addrlo[ETHER_ADDR_LEN];
+ uint8_t enm_addrhi[ETHER_ADDR_LEN];
+};
+
/*
* Structure used by macros below to remember position when stepping through
* all of the ether_multi records.
diff -r 8d5136b1f058 -r 608a54301520 sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c Tue Jun 10 07:26:19 2014 +0000
+++ b/sys/net/if_ethersubr.c Tue Jun 10 09:38:30 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.199 2014/06/05 23:48:16 rmind Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.200 2014/06/10 09:38:30 joerg Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.199 2014/06/05 23:48:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.200 2014/06/10 09:38:30 joerg Exp $");
#include "opt_inet.h"
#include "opt_atalk.h"
@@ -78,6 +78,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/sysctl.h>
#include <sys/kernel.h>
#include <sys/callout.h>
#include <sys/malloc.h>
@@ -1489,3 +1490,70 @@
}
return 0;
}
+
+static int
+ether_multicast_sysctl(SYSCTLFN_ARGS)
+{
+ struct ether_multi *enm;
+ struct ether_multi_sysctl addr;
+ struct ifnet *ifp;
+ struct ethercom *ec;
+ int error;
+ size_t written;
+
+ if (namelen != 1)
+ return EINVAL;
+
+ ifp = if_byindex(name[0]);
+ if (ifp == NULL)
+ return ENODEV;
+ if (ifp->if_type != IFT_ETHER) {
+ *oldlenp = 0;
+ return 0;
+ }
+ ec = (struct ethercom *)ifp;
+
+ if (oldp == NULL) {
+ *oldlenp = ec->ec_multicnt * sizeof(addr);
+ return 0;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ error = 0;
+ written = 0;
+
+ LIST_FOREACH(enm, &ec->ec_multiaddrs, enm_list) {
+ if (written + sizeof(addr) > *oldlenp)
+ break;
+ addr.enm_refcount = enm->enm_refcount;
+ memcpy(addr.enm_addrlo, enm->enm_addrlo, ETHER_ADDR_LEN);
+ memcpy(addr.enm_addrhi, enm->enm_addrhi, ETHER_ADDR_LEN);
+ error = sysctl_copyout(l, &addr, oldp, sizeof(addr));
+ if (error)
+ break;
+ written += sizeof(addr);
+ oldp = (char *)oldp + sizeof(addr);
+ }
+
+ *oldlenp = written;
+ return error;
+}
+
+SYSCTL_SETUP(sysctl_net_ether_setup, "sysctl net.ether subtree setup")
+{
+ const struct sysctlnode *rnode = NULL;
+
+ sysctl_createv(clog, 0, NULL, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "ether",
+ SYSCTL_DESCR("Ethernet-specific information"),
+ NULL, 0, NULL, 0,
+ CTL_NET, CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "multicast",
+ SYSCTL_DESCR("multicast addresses"),
+ ether_multicast_sysctl, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+}
diff -r 8d5136b1f058 -r 608a54301520 sys/netinet6/mld6.c
--- a/sys/netinet6/mld6.c Tue Jun 10 07:26:19 2014 +0000
+++ b/sys/netinet6/mld6.c Tue Jun 10 09:38:30 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mld6.c,v 1.56 2014/06/02 11:02:20 joerg Exp $ */
+/* $NetBSD: mld6.c,v 1.57 2014/06/10 09:38:30 joerg Exp $ */
/* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */
/*
@@ -102,7 +102,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.56 2014/06/02 11:02:20 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.57 2014/06/10 09:38:30 joerg Exp $");
#include "opt_inet.h"
@@ -897,3 +897,146 @@
LIST_REMOVE(mk, mk_entry);
free(mk, M_IPMADDR);
}
+
+static int
+in6_mkludge_sysctl(SYSCTLFN_ARGS)
+{
+ struct multi6_kludge *mk;
+ struct in6_multi *in6m;
+ int error;
+ uint32_t tmp;
+ size_t written;
+
+ if (namelen != 1)
+ return EINVAL;
+
+ if (oldp == NULL) {
+ *oldlenp = 0;
+ LIST_FOREACH(mk, &in6_mk, mk_entry) {
+ if (mk->mk_ifp->if_index == name[0])
+ continue;
+ LIST_FOREACH(in6m, &mk->mk_head, in6m_entry) {
+ *oldlenp += sizeof(struct in6_addr) +
+ sizeof(uint32_t);
+ }
+ }
+ return 0;
+ }
+
+ error = 0;
+ written = 0;
+ LIST_FOREACH(mk, &in6_mk, mk_entry) {
+ if (mk->mk_ifp->if_index == name[0])
+ continue;
+ LIST_FOREACH(in6m, &mk->mk_head, in6m_entry) {
+ if (written + sizeof(struct in6_addr) +
+ sizeof(uint32_t) > *oldlenp)
+ goto done;
+ error = sysctl_copyout(l, &in6m->in6m_addr,
+ oldp, sizeof(struct in6_addr));
+ if (error)
+ goto done;
+ oldp = (char *)oldp + sizeof(struct in6_addr);
+ written += sizeof(struct in6_addr);
+ tmp = in6m->in6m_refcount;
+ error = sysctl_copyout(l, &tmp, oldp, sizeof(tmp));
+ if (error)
+ goto done;
+ oldp = (char *)oldp + sizeof(tmp);
+ written += sizeof(tmp);
+ }
+ }
+
+done:
+ *oldlenp = written;
+ return error;
+}
+
+static int
+in6_multicast_sysctl(SYSCTLFN_ARGS)
+{
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+ struct in6_ifaddr *ifa6;
+ struct in6_multi *in6m;
+ uint32_t tmp;
+ int error;
+ size_t written;
+
+ if (namelen != 1)
+ return EINVAL;
+
+ ifp = if_byindex(name[0]);
+ if (ifp == NULL)
+ return ENODEV;
+
+ if (oldp == NULL) {
+ *oldlenp = 0;
+ TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
+ ifa6 = (struct in6_ifaddr *)ifa;
+ LIST_FOREACH(in6m, &ifa6->ia6_multiaddrs, in6m_entry) {
+ *oldlenp += 2 * sizeof(struct in6_addr) +
+ sizeof(uint32_t);
+ }
+ }
+ return 0;
+ }
+
+ error = 0;
+ written = 0;
+ TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
Home |
Main Index |
Thread Index |
Old Index