From 9be5a92778d20a28277219de0503e8681fe31933 Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Wed, 20 Mar 2013 10:34:13 +0000 Subject: Introduce if_get() to retrieve an interface descriptor pointer given an interface index and replace all the redondant checks and accesses to a global array by a call to this function. With imputs from and ok bluhm@, mikeb@ --- sys/netinet6/in6_src.c | 45 ++++++++++++++++++++------------------------- sys/netinet6/ip6_mroute.c | 4 +--- sys/netinet6/ip6_output.c | 37 ++++++++++++------------------------- 3 files changed, 33 insertions(+), 53 deletions(-) (limited to 'sys/netinet6') diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index e46678d79b0..3068833ac18 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.28 2013/03/04 14:42:25 bluhm Exp $ */ +/* $OpenBSD: in6_src.c,v 1.29 2013/03/20 10:34:12 mpi Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -103,6 +103,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, struct ip6_moptions *mopts, struct route_in6 *ro, struct in6_addr *laddr, int *errorp, u_int rtableid) { + struct ifnet *ifp = NULL; struct in6_addr *dst; struct in6_ifaddr *ia6 = NULL; struct in6_pktinfo *pi = NULL; @@ -118,7 +119,6 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, */ if (opts && (pi = opts->ip6po_pktinfo) && !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr)) { - struct ifnet *ifp = NULL; struct sockaddr_in6 sa6; /* get the outgoing interface */ @@ -160,9 +160,12 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, * the interface. */ if (pi && pi->ipi6_ifindex) { - /* XXX boundary check is assumed to be already done. */ - ia6 = in6_ifawithscope(ifindex2ifnet[pi->ipi6_ifindex], - dst, rtableid); + ifp = if_get(pi->ipi6_ifindex); + if (ifp == NULL) { + *errorp = ENXIO; /* XXX: better error? */ + return (0); + } + ia6 = in6_ifawithscope(ifp, dst, rtableid); if (ia6 == 0) { *errorp = EADDRNOTAVAIL; return (0); @@ -181,18 +184,12 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, */ if ((IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MC_LINKLOCAL(dst) || IN6_IS_ADDR_MC_INTFACELOCAL(dst)) && dstsock->sin6_scope_id) { - /* - * I'm not sure if boundary check for scope_id is done - * somewhere... - */ - if (dstsock->sin6_scope_id < 0 || - if_indexlim <= dstsock->sin6_scope_id || - !ifindex2ifnet[dstsock->sin6_scope_id]) { + ifp = if_get(dstsock->sin6_scope_id); + if (ifp == NULL) { *errorp = ENXIO; /* XXX: better error? */ return (0); } - ia6 = in6_ifawithscope(ifindex2ifnet[dstsock->sin6_scope_id], - dst, rtableid); + ia6 = in6_ifawithscope(ifp, dst, rtableid); if (ia6 == 0) { *errorp = EADDRNOTAVAIL; return (0); @@ -208,10 +205,10 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, * choose a loopback interface as the outgoing interface. */ if (IN6_IS_ADDR_MULTICAST(dst)) { - struct ifnet *ifp = mopts ? mopts->im6o_multicast_ifp : NULL; + ifp = mopts ? mopts->im6o_multicast_ifp : NULL; if (!ifp && dstsock->sin6_scope_id) - ifp = ifindex2ifnet[htons(dstsock->sin6_scope_id)]; + ifp = if_get(htons(dstsock->sin6_scope_id)); if (ifp) { ia6 = in6_ifawithscope(ifp, dst, rtableid); @@ -349,8 +346,7 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, /* If the caller specify the outgoing interface explicitly, use it. */ if (opts && (pi = opts->ip6po_pktinfo) != NULL && pi->ipi6_ifindex) { - /* XXX boundary check is assumed to be already done. */ - ifp = ifindex2ifnet[pi->ipi6_ifindex]; + ifp = if_get(pi->ipi6_ifindex); if (ifp != NULL && (norouteok || retrt == NULL || IN6_IS_ADDR_MULTICAST(dst))) { @@ -640,7 +636,9 @@ in6_embedscope(in6, sin6, in6p, ifpp) if (in6p && in6p->in6p_outputopts && (pi = in6p->in6p_outputopts->ip6po_pktinfo) && pi->ipi6_ifindex) { - ifp = ifindex2ifnet[pi->ipi6_ifindex]; + ifp = if_get(pi->ipi6_ifindex); + if (ifp == NULL) + return ENXIO; /* XXX EINVAL? */ in6->s6_addr16[1] = htons(pi->ipi6_ifindex); } else if (in6p && IN6_IS_ADDR_MULTICAST(in6) && in6p->in6p_moptions && @@ -648,11 +646,9 @@ in6_embedscope(in6, sin6, in6p, ifpp) ifp = in6p->in6p_moptions->im6o_multicast_ifp; in6->s6_addr16[1] = htons(ifp->if_index); } else if (scopeid) { - /* boundary check */ - if (scopeid < 0 || if_indexlim <= scopeid || - !ifindex2ifnet[scopeid]) + ifp = if_get(scopeid); + if (ifp == NULL) return ENXIO; /* XXX EINVAL? */ - ifp = ifindex2ifnet[scopeid]; /*XXX assignment to 16bit from 32bit variable */ in6->s6_addr16[1] = htons(scopeid & 0xffff); } @@ -694,8 +690,7 @@ in6_recoverscope(struct sockaddr_in6 *sin6, const struct in6_addr *in6, scopeid = ntohs(sin6->sin6_addr.s6_addr16[1]); if (scopeid) { /* sanity check */ - if (scopeid < 0 || if_indexlim <= scopeid || - !ifindex2ifnet[scopeid]) + if (if_get(scopeid) == NULL) return ENXIO; if (ifp && ifp->if_index != scopeid) return ENXIO; diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 762bcff38d5..35f50677523 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -584,9 +584,7 @@ add_m6if(struct mif6ctl *mifcp) mifp = mif6table + mifcp->mif6c_mifi; if (mifp->m6_ifp) return EADDRINUSE; /* XXX: is it appropriate? */ - if (mifcp->mif6c_pifi == 0 || mifcp->mif6c_pifi >= if_indexlim) - return ENXIO; - ifp = ifindex2ifnet[mifcp->mif6c_pifi]; + ifp = if_get(mifcp->mif6c_pifi); if (!ifp) return ENXIO; diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 5ab27a5b0ef..9ec2f19239d 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.134 2013/03/14 11:18:37 mpi Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.135 2013/03/20 10:34:12 mpi Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -742,9 +742,9 @@ reroute: */ origifp = NULL; if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) - origifp = ifindex2ifnet[ntohs(ip6->ip6_src.s6_addr16[1])]; + origifp = if_get(ntohs(ip6->ip6_src.s6_addr16[1])); else if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) - origifp = ifindex2ifnet[ntohs(ip6->ip6_dst.s6_addr16[1])]; + origifp = if_get(ntohs(ip6->ip6_dst.s6_addr16[1])); /* * XXX: origifp can be NULL even in those two cases above. * For example, if we remove the (only) link-local address @@ -2380,14 +2380,12 @@ ip6_setmoptions(int optname, struct ip6_moptions **im6op, struct mbuf *m) if (ifindex == 0) ifp = NULL; else { - if (ifindex < 0 || if_indexlim <= ifindex || - !ifindex2ifnet[ifindex]) { + ifp = if_get(ifindex); + if (ifp == NULL) { error = ENXIO; /* XXX EINVAL? */ break; } - ifp = ifindex2ifnet[ifindex]; - if (ifp == NULL || - (ifp->if_flags & IFF_MULTICAST) == 0) { + if ((ifp->if_flags & IFF_MULTICAST) == 0) { error = EADDRNOTAVAIL; break; } @@ -2484,13 +2482,11 @@ ip6_setmoptions(int optname, struct ip6_moptions **im6op, struct mbuf *m) /* * If the interface is specified, validate it. */ - if (mreq->ipv6mr_interface < 0 || - if_indexlim <= mreq->ipv6mr_interface || - !ifindex2ifnet[mreq->ipv6mr_interface]) { + ifp = if_get(mreq->ipv6mr_interface); + if (ifp == NULL) { error = ENXIO; /* XXX EINVAL? */ break; } - ifp = ifindex2ifnet[mreq->ipv6mr_interface]; } /* @@ -2558,13 +2554,11 @@ ip6_setmoptions(int optname, struct ip6_moptions **im6op, struct mbuf *m) if (mreq->ipv6mr_interface == 0) ifp = NULL; else { - if (mreq->ipv6mr_interface < 0 || - if_indexlim <= mreq->ipv6mr_interface || - !ifindex2ifnet[mreq->ipv6mr_interface]) { + ifp = if_get(mreq->ipv6mr_interface); + if (ifp == NULL) { error = ENXIO; /* XXX EINVAL? */ break; } - ifp = ifindex2ifnet[mreq->ipv6mr_interface]; } /* @@ -2827,13 +2821,8 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, return (EINVAL); } - /* validate the interface index if specified. */ - if (pktinfo->ipi6_ifindex >= if_indexlim || - pktinfo->ipi6_ifindex < 0) { - return (ENXIO); - } if (pktinfo->ipi6_ifindex) { - ifp = ifindex2ifnet[pktinfo->ipi6_ifindex]; + ifp = if_get(pktinfo->ipi6_ifindex); if (ifp == NULL) return (ENXIO); } @@ -2921,9 +2910,7 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, return (EINVAL); } if (IN6_IS_SCOPE_EMBED(&sa6->sin6_addr)) { - if (sa6->sin6_scope_id < 0 || - if_indexlim <= sa6->sin6_scope_id || - !ifindex2ifnet[sa6->sin6_scope_id]) + if (if_get(sa6->sin6_scope_id) == NULL) return (EINVAL); sa6->sin6_addr.s6_addr16[1] = htonl(sa6->sin6_scope_id); -- cgit v1.2.3