diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2015-02-09 12:18:20 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2015-02-09 12:18:20 +0000 |
commit | 7ecefaf9c3d8ee666eca332904eba63861a311a6 (patch) | |
tree | f77b476bd743238fb9ac25a92cea0f87aeca4625 /sys/netinet | |
parent | 382123eead0dbfa25431f5f9ee2b211a35a21f59 (diff) |
Implement 2 sysctl to retrieve the multicast forwarding cache (mfc) and the
virtual interface table (vif). Will be used by netstat soon.
Looked over by guenther@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in.h | 12 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 20 | ||||
-rw-r--r-- | sys/netinet/ip_mroute.c | 89 | ||||
-rw-r--r-- | sys/netinet/ip_mroute.h | 27 |
4 files changed, 137 insertions, 11 deletions
diff --git a/sys/netinet/in.h b/sys/netinet/in.h index dd333ce913d..1319d89fa49 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in.h,v 1.111 2014/12/05 15:50:04 mpi Exp $ */ +/* $OpenBSD: in.h,v 1.112 2015/02/09 12:18:19 claudio Exp $ */ /* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */ /* @@ -679,7 +679,9 @@ struct ip_mreq { #define IPCTL_MRTPROTO 34 /* type of multicast */ #define IPCTL_MRTSTATS 35 #define IPCTL_ARPQUEUED 36 -#define IPCTL_MAXID 37 +#define IPCTL_MRTMFC 37 +#define IPCTL_MRTVIF 38 +#define IPCTL_MAXID 39 #define IPCTL_NAMES { \ { 0, 0 }, \ @@ -719,6 +721,8 @@ struct ip_mreq { { "mrtproto", CTLTYPE_INT }, \ { "mrtstats", CTLTYPE_STRUCT }, \ { "arpqueued", CTLTYPE_INT }, \ + { "mrtmfc", CTLTYPE_STRUCT }, \ + { "mrtvif", CTLTYPE_STRUCT }, \ } #define IPCTL_VARS { \ NULL, \ @@ -757,7 +761,9 @@ struct ip_mreq { NULL, \ NULL, \ NULL, \ - &la_hold_total \ + &la_hold_total, \ + NULL, \ + NULL, \ } #endif /* __BSD_VISIBLE */ diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 3bfa7848b88..72c9029ea24 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.245 2015/02/08 04:14:47 claudio Exp $ */ +/* $OpenBSD: ip_input.c,v 1.246 2015/02/09 12:18:19 claudio Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -1622,17 +1622,25 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, case IPCTL_STATS: return (sysctl_rdstruct(oldp, oldlenp, newp, &ipstat, sizeof(ipstat))); - case IPCTL_MRTSTATS: #ifdef MROUTING + case IPCTL_MRTSTATS: return (sysctl_rdstruct(oldp, oldlenp, newp, &mrtstat, sizeof(mrtstat))); -#else - return (EOPNOTSUPP); -#endif case IPCTL_MRTPROTO: -#ifdef MROUTING return (sysctl_rdint(oldp, oldlenp, newp, ip_mrtproto)); + case IPCTL_MRTMFC: + if (newp) + return (EPERM); + return mrt_sysctl_mfc(oldp, oldlenp); + case IPCTL_MRTVIF: + if (newp) + return (EPERM); + return mrt_sysctl_vif(oldp, oldlenp); #else + case IPCTL_MRTPROTO: + case IPCTL_MRTSTATS: + case IPCTL_MRTMFC: + case IPCTL_MRTVIF: return (EOPNOTSUPP); #endif default: diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 4268aff4ab9..876b7ee745b 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_mroute.c,v 1.76 2015/02/08 03:42:24 claudio Exp $ */ +/* $OpenBSD: ip_mroute.c,v 1.77 2015/02/09 12:18:19 claudio Exp $ */ /* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */ /* @@ -475,6 +475,93 @@ get_vif_cnt(struct sioc_vif_req *req) return (0); } +int +mrt_sysctl_vif(void *oldp, size_t *oldlenp) +{ + caddr_t where = oldp; + size_t needed, given; + struct vif *vifp; + vifi_t vifi; + struct vifinfo vinfo; + + given = *oldlenp; + needed = 0; + for (vifi = 0; vifi < numvifs; vifi++) { + vifp = &viftable[vifi]; + if (in_nullhost(vifp->v_lcl_addr)) + continue; + + vinfo.v_vifi = vifi; + vinfo.v_flags = vifp->v_flags; + vinfo.v_threshold = vifp->v_threshold; + vinfo.v_lcl_addr = vifp->v_lcl_addr; + vinfo.v_rmt_addr = vifp->v_rmt_addr; + vinfo.v_pkt_in = vifp->v_pkt_in; + vinfo.v_pkt_out = vifp->v_pkt_out; + vinfo.v_bytes_in = vifp->v_bytes_in; + vinfo.v_bytes_out = vifp->v_bytes_out; + + needed += sizeof(vinfo); + if (where && needed <= given) { + int error; + + error = copyout(&vinfo, where, sizeof(vinfo)); + if (error) + return (error); + where += sizeof(vinfo); + } + } + if (where) { + *oldlenp = needed; + if (given < needed) + return (ENOMEM); + } else + *oldlenp = (11 * needed) / 10; + + return (0); +} + +int +mrt_sysctl_mfc(void *oldp, size_t *oldlenp) +{ + caddr_t where = oldp; + size_t needed, given; + u_long i; + struct mfc *m; + struct mfcinfo minfo; + + given = *oldlenp; + needed = 0; + for (i = 0; mfchashtbl && i < MFCTBLSIZ; ++i) { + LIST_FOREACH(m, &mfchashtbl[i], mfc_hash) { + minfo.mfc_origin = m->mfc_origin; + minfo.mfc_mcastgrp = m->mfc_mcastgrp; + minfo.mfc_parent = m->mfc_parent; + minfo.mfc_pkt_cnt = m->mfc_pkt_cnt; + minfo.mfc_byte_cnt = m->mfc_byte_cnt; + memcpy(minfo.mfc_ttls, m->mfc_ttls, MAXVIFS); + + 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); +} + /* * Enable multicast routing */ diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h index e5cfd0f7a88..c706d6f0ef7 100644 --- a/sys/netinet/ip_mroute.h +++ b/sys/netinet/ip_mroute.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_mroute.h,v 1.18 2014/08/14 08:22:38 mpi Exp $ */ +/* $OpenBSD: ip_mroute.h,v 1.19 2015/02/09 12:18:19 claudio Exp $ */ /* $NetBSD: ip_mroute.h,v 1.23 2004/04/21 17:49:46 itojun Exp $ */ #ifndef _NETINET_IP_MROUTE_H_ @@ -112,6 +112,29 @@ struct mfcctl2 { MRT_MFC_RP | \ MRT_MFC_BW_UPCALL) +/* structure used to get all the mfc entries */ +struct mfcinfo { + struct in_addr mfc_origin; /* ip origin of mcasts */ + struct in_addr mfc_mcastgrp; /* multicast group associated */ + vifi_t mfc_parent; /* incoming vif */ + u_long mfc_pkt_cnt; /* pkt count for src-grp */ + u_long mfc_byte_cnt; /* byte count for src-grp */ + u_int8_t mfc_ttls[MAXVIFS]; /* forwarding ttls on vifs */ +}; + +/* structure used to get all the vif entries */ +struct vifinfo { + vifi_t v_vifi; /* the index of the vif to be added */ + u_int8_t v_flags; /* VIFF_ flags defined above */ + u_int8_t v_threshold; /* min ttl required to forward on vif */ + struct in_addr v_lcl_addr; /* local interface address */ + struct in_addr v_rmt_addr; /* remote address (tunnels only) */ + u_long v_pkt_in; /* # pkts in on interface */ + u_long v_pkt_out; /* # pkts out on interface */ + u_long v_bytes_in; /* # bytes in on interface */ + u_long v_bytes_out; /* # bytes out on interface */ +}; + /* * Structure for installing or delivering an upcall if the * measured bandwidth is above or below a threshold. @@ -285,6 +308,8 @@ struct rtdetq { int ip_mrouter_set(struct socket *, int, struct mbuf **); int ip_mrouter_get(struct socket *, int, struct mbuf **); int mrt_ioctl(struct socket *, u_long, caddr_t); +int mrt_sysctl_vif(void *, size_t *); +int mrt_sysctl_mfc(void *, size_t *); int ip_mrouter_done(void); void ip_mrouter_detach(struct ifnet *); void reset_vif(struct vif *); |