summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2015-02-09 12:23:22 +0000
committerclaudio <claudio@openbsd.org>2015-02-09 12:23:22 +0000
commit719a30917cb5366bf6af1d18b3d949004ed829ca (patch)
treec43c22755d3b9981fcc06dda677f50c522dd1601
parentImplement 2 sysctl to retrieve the multicast forwarding cache (mfc) and the (diff)
downloadwireguard-openbsd-719a30917cb5366bf6af1d18b3d949004ed829ca.tar.xz
wireguard-openbsd-719a30917cb5366bf6af1d18b3d949004ed829ca.zip
Implement 2 sysctl to retrieve the multicast forwarding cache (mf6c) and the
multicast interface table (mif6). Will be used by netstat soon. Looked over by guenther@
-rw-r--r--sys/netinet6/in6.h11
-rw-r--r--sys/netinet6/ip6_input.c20
-rw-r--r--sys/netinet6/ip6_mroute.c95
-rw-r--r--sys/netinet6/ip6_mroute.h33
4 files changed, 148 insertions, 11 deletions
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h
index ab263276b35..66559187492 100644
--- a/sys/netinet6/in6.h
+++ b/sys/netinet6/in6.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6.h,v 1.79 2015/02/09 12:04:27 dlg Exp $ */
+/* $OpenBSD: in6.h,v 1.80 2015/02/09 12:23:22 claudio Exp $ */
/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
/*
@@ -607,7 +607,9 @@ ifatoia6(struct ifaddr *ifa)
#define IPV6CTL_DAD_PENDING 49
#define IPV6CTL_MTUDISCTIMEOUT 50
#define IPV6CTL_IFQUEUE 51
-#define IPV6CTL_MAXID 52
+#define IPV6CTL_MRTMIF 52
+#define IPV6CTL_MRTMFC 53
+#define IPV6CTL_MAXID 54
/* New entries should be added here from current IPV6CTL_MAXID value. */
/* to define items, should talk with KAME guys first, for *BSD compatibility */
@@ -665,6 +667,8 @@ ifatoia6(struct ifaddr *ifa)
{ "dad_pending", CTLTYPE_INT }, \
{ "mtudisctimeout", CTLTYPE_INT }, \
{ "ifq", CTLTYPE_NODE }, \
+ { "mrtmif", CTLTYPE_STRUCT }, \
+ { "mrtmfc", CTLTYPE_STRUCT }, \
}
#define IPV6CTL_VARS { \
@@ -719,6 +723,9 @@ ifatoia6(struct ifaddr *ifa)
&ip6_maxdynroutes, \
NULL, \
NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
}
__BEGIN_DECLS
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index a3bec2816f5..08e86fb8c1a 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.138 2015/02/09 12:04:27 dlg Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.139 2015/02/09 12:23:22 claudio Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -1419,19 +1419,27 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
return (EPERM);
return (sysctl_struct(oldp, oldlenp, newp, newlen,
&ip6stat, sizeof(ip6stat)));
- case IPV6CTL_MRTSTATS:
#ifdef MROUTING
+ case IPV6CTL_MRTSTATS:
if (newp != NULL)
return (EPERM);
return (sysctl_struct(oldp, oldlenp, newp, newlen,
&mrt6stat, sizeof(mrt6stat)));
-#else
- return (EOPNOTSUPP);
-#endif
case IPV6CTL_MRTPROTO:
-#ifdef MROUTING
return sysctl_rdint(oldp, oldlenp, newp, ip6_mrtproto);
+ case IPV6CTL_MRTMIF:
+ if (newp)
+ return (EPERM);
+ return mrt6_sysctl_mif(oldp, oldlenp);
+ case IPV6CTL_MRTMFC:
+ if (newp)
+ return (EPERM);
+ return mrt6_sysctl_mfc(oldp, oldlenp);
#else
+ case IPV6CTL_MRTSTATS:
+ case IPV6CTL_MRTPROTO:
+ case IPV6CTL_MRTMIF:
+ case IPV6CTL_MRTMFC:
return (EOPNOTSUPP);
#endif
case IPV6CTL_MTUDISCTIMEOUT:
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
index d00273c7593..b360e0125ed 100644
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -361,6 +361,101 @@ get_mif6_cnt(struct sioc_mif_req6 *req)
return 0;
}
+int
+mrt6_sysctl_mif(void *oldp, size_t *oldlenp)
+{
+ caddr_t where = oldp;
+ size_t needed, given;
+ struct mif6 *mifp;
+ mifi_t mifi;
+ struct mif6info minfo;
+
+ given = *oldlenp;
+ needed = 0;
+ for (mifi = 0; mifi < nummifs; mifi++) {
+ mifp = &mif6table[mifi];
+ if (mifp->m6_ifp == NULL)
+ continue;
+
+ minfo.m6_mifi = mifi;
+ minfo.m6_flags = mifp->m6_flags;
+ minfo.m6_lcl_addr = mifp->m6_lcl_addr;
+ minfo.m6_ifindex = mifp->m6_ifp->if_index;
+ minfo.m6_pkt_in = mifp->m6_pkt_in;
+ minfo.m6_pkt_out = mifp->m6_pkt_out;
+ minfo.m6_bytes_in = mifp->m6_bytes_in;
+ minfo.m6_bytes_out = mifp->m6_bytes_out;
+ minfo.m6_rate_limit = mifp->m6_rate_limit;
+
+ needed += sizeof(minfo);
+ if (where && needed <= given) {
+ int error;
+
+ error = copyout(&minfo, where, sizeof(minfo));
+ if (error)
+ return (error);
+ where += sizeof(minfo);
+ }
+ }
+ if (where) {
+ *oldlenp = needed;
+ if (given < needed)
+ return (ENOMEM);
+ } else
+ *oldlenp = (11 * needed) / 10;
+
+ return (0);
+}
+
+int
+mrt6_sysctl_mfc(void *oldp, size_t *oldlenp)
+{
+ caddr_t where = oldp;
+ size_t needed, given;
+ u_long i;
+ u_int64_t waitings;
+ struct mf6c *m;
+ struct mf6cinfo minfo;
+ struct rtdetq *r;
+
+ given = *oldlenp;
+ needed = 0;
+ for (i = 0; i < MF6CTBLSIZ; ++i) {
+ m = mf6ctable[i];
+ while (m) {
+ minfo.mf6c_origin = m->mf6c_origin;
+ minfo.mf6c_mcastgrp = m->mf6c_mcastgrp;
+ minfo.mf6c_parent = m->mf6c_parent;
+ minfo.mf6c_ifset = m->mf6c_ifset;
+ minfo.mf6c_pkt_cnt = m->mf6c_pkt_cnt;
+ minfo.mf6c_byte_cnt = m->mf6c_byte_cnt;
+
+ for (waitings = 0, r = m->mf6c_stall; r; r = r->next)
+ waitings++;
+ minfo.mf6c_stall_cnt = waitings;
+
+ needed += sizeof(minfo);
+ if (where && needed <= given) {
+ int error;
+
+ error = copyout(&minfo, where, sizeof(minfo));
+ if (error)
+ return (error);
+ where += sizeof(minfo);
+ }
+ m = m->mf6c_next;
+ }
+ }
+ if (where) {
+ *oldlenp = needed;
+ if (given < needed)
+ return (ENOMEM);
+ } else
+ *oldlenp = (11 * needed) / 10;
+
+ return (0);
+}
+
/*
* Get PIM processiong global
*/
diff --git a/sys/netinet6/ip6_mroute.h b/sys/netinet6/ip6_mroute.h
index 184ebae2bb0..35e79af0812 100644
--- a/sys/netinet6/ip6_mroute.h
+++ b/sys/netinet6/ip6_mroute.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_mroute.h,v 1.14 2014/07/09 15:35:53 mpi Exp $ */
+/* $OpenBSD: ip6_mroute.h,v 1.15 2015/02/09 12:23:22 claudio Exp $ */
/* $KAME: ip6_mroute.h,v 1.17 2001/02/10 02:05:52 itojun Exp $ */
/*
@@ -93,6 +93,8 @@ struct mif6ctl {
#define MIFF_REGISTER 0x1 /* mif represents a register end-point */
+#define MF6C_INCOMPLETE_PARENT ((mifi_t)-1)
+
/*
* Argument structure for MRT6_ADD_MFC and MRT6_DEL_MFC
*/
@@ -103,6 +105,31 @@ struct mf6cctl {
struct if_set mf6cc_ifset; /* set of forwarding ifs */
};
+/* structure used to get all the mif entries via sysctl */
+struct mif6info {
+ struct in6_addr m6_lcl_addr; /* local interface address */
+ u_int16_t m6_ifindex; /* interface index */
+ u_int64_t m6_pkt_in; /* # pkts in on interface */
+ u_int64_t m6_pkt_out; /* # pkts out on interface */
+ u_int64_t m6_bytes_in; /* # bytes in on interface */
+ u_int64_t m6_bytes_out; /* # bytes out on interface */
+ u_int m6_rate_limit; /* max rate */
+ mifi_t m6_mifi;
+ u_char m6_flags; /* MIFF_ flags defined above */
+};
+
+/* structure used to get all the mf6c entries via sysctl */
+struct mf6cinfo {
+ struct sockaddr_in6 mf6c_origin; /* IPv6 origin of mcasts */
+ struct sockaddr_in6 mf6c_mcastgrp; /* multicast group associated*/
+ mifi_t mf6c_parent; /* incoming IF */
+ struct if_set mf6c_ifset; /* set of outgoing IFs */
+
+ u_int64_t mf6c_pkt_cnt; /* pkt count for src-grp */
+ u_int64_t mf6c_byte_cnt; /* byte count for src-grp */
+ u_int64_t mf6c_stall_cnt; /* pkt-cnt waiting for route */
+};
+
/*
* The kernel's multicast routing statistics.
*/
@@ -200,8 +227,6 @@ struct mf6c {
struct mf6c *mf6c_next; /* hash table linkage */
};
-#define MF6C_INCOMPLETE_PARENT ((mifi_t)-1)
-
/*
* Argument structure used for pkt info. while upcall is made
*/
@@ -227,6 +252,8 @@ int ip6_mrouter_get(int, struct socket *, struct mbuf **);
int ip6_mrouter_done(void);
void ip6_mrouter_detach(struct ifnet *);
int mrt6_ioctl(u_long, caddr_t);
+int mrt6_sysctl_mif(void *, size_t *);
+int mrt6_sysctl_mfc(void *, size_t *);
#endif /* _KERNEL */
#endif /* !_NETINET6_IP6_MROUTE_H_ */