summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-11-26 10:36:21 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-11-26 10:36:21 +0000
commitb627e540fea13696d82ffac81beab90cf7417be3 (patch)
tree55bdaceb1a6fe4a1a3090e3d81ab5bd43f67ec84 /sys
parentd4bdc5a860b36975c9eedb8aa2f15216e47d0e6d (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.c24
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: