diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-11-26 10:36:21 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-11-26 10:36:21 +0000 |
commit | b627e540fea13696d82ffac81beab90cf7417be3 (patch) | |
tree | 55bdaceb1a6fe4a1a3090e3d81ab5bd43f67ec84 /sys | |
parent | d4bdc5a860b36975c9eedb8aa2f15216e47d0e6d (diff) |
Use rtalloc(9) to look for a local address (RTF_LOCAL) in ip_setmoptions().
This simplifies the if_get()/if_put() dance.
Tested by jasper@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/ip_output.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2b5fde7cd6c..e32b87b8e28 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.307 2015/11/19 13:40:46 mpi Exp $ */ +/* $OpenBSD: ip_output.c,v 1.308 2015/11/26 10:36:20 mpi Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -1445,27 +1445,33 @@ ip_setmoptions(int optname, struct ip_moptions **imop, struct mbuf *m, sin.sin_addr = mreq->imr_multiaddr; rt = rtalloc(sintosa(&sin), RT_REPORT|RT_RESOLVE, rtableid); - if (rt == NULL) { + if (!rtisvalid(rt)) { + rtfree(rt); error = EADDRNOTAVAIL; break; } - ifp = rt->rt_ifp; - rtfree(rt); } else { memset(&sin, 0, sizeof(sin)); sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; sin.sin_addr = mreq->imr_interface; - ia = ifatoia(ifa_ifwithaddr(sintosa(&sin), rtableid)); - if (ia && in_hosteq(sin.sin_addr, ia->ia_addr.sin_addr)) - ifp = ia->ia_ifp; + rt = rtalloc(sintosa(&sin), RT_REPORT, rtableid); + if (!rtisvalid(rt) || !ISSET(rt->rt_flags, RTF_LOCAL)) { + rtfree(rt); + error = EADDRNOTAVAIL; + break; + } } + ifp = if_get(rt->rt_ifidx); + rtfree(rt); + /* * See if we found an interface, and confirm that it * supports multicast. */ if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { error = EADDRNOTAVAIL; + if_put(ifp); break; } /* @@ -1481,6 +1487,7 @@ ip_setmoptions(int optname, struct ip_moptions **imop, struct mbuf *m, } if (i < imo->imo_num_memberships) { error = EADDRINUSE; + if_put(ifp); break; } if (imo->imo_num_memberships == imo->imo_max_memberships) { @@ -1511,6 +1518,7 @@ ip_setmoptions(int optname, struct ip_moptions **imop, struct mbuf *m, } if (nmships == NULL) { error = ETOOMANYREFS; + if_put(ifp); break; } } @@ -1521,9 +1529,11 @@ ip_setmoptions(int optname, struct ip_moptions **imop, struct mbuf *m, if ((imo->imo_membership[i] = in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) { error = ENOBUFS; + if_put(ifp); break; } ++imo->imo_num_memberships; + if_put(ifp); break; case IP_DROP_MEMBERSHIP: |