diff options
author | 2015-02-09 12:23:22 +0000 | |
---|---|---|
committer | 2015-02-09 12:23:22 +0000 | |
commit | 719a30917cb5366bf6af1d18b3d949004ed829ca (patch) | |
tree | c43c22755d3b9981fcc06dda677f50c522dd1601 | |
parent | Implement 2 sysctl to retrieve the multicast forwarding cache (mfc) and the (diff) | |
download | wireguard-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.h | 11 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 20 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 95 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.h | 33 |
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_ */ |