Diff below replaces the INADDR_TO_IFP() macro that iterates over the
global list of IPv4 by a call to in_iawithaddr() that uses the global
tree of addresses. Since these two structures are now always coherent
it is safe to replace one by the other and this removes one more usage
of the global list.
Tested here with ping -I with a multicast address, ok?
Index: netinet/ip_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.250
diff -u -p -r1.250 ip_output.c
--- netinet/ip_output.c 25 Oct 2013 18:44:36 -0000 1.250
+++ netinet/ip_output.c 26 Nov 2013 11:34:18 -0000
@@ -1702,6 +1702,7 @@ ip_setmoptions(int optname, struct ip_mo
u_char loop;
int i;
struct in_addr addr;
+ struct in_ifaddr *ia;
struct ip_mreq *mreq;
struct ifnet *ifp;
struct ip_moptions *imo = *imop;
@@ -1753,7 +1754,9 @@ ip_setmoptions(int optname, struct ip_mo
* IP address. Find the interface and confirm that
* it supports multicasting.
*/
- INADDR_TO_IFP(addr, ifp, rtableid);
+ ia = in_iawithaddr(addr, rtableid);
+ if (ia)
+ ifp = ia->ia_ifp;
if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
error = EADDRNOTAVAIL;
break;
@@ -1820,7 +1823,9 @@ ip_setmoptions(int optname, struct ip_mo
ifp = ro.ro_rt->rt_ifp;
rtfree(ro.ro_rt);
} else {
- INADDR_TO_IFP(mreq->imr_interface, ifp, rtableid);
+ ia = in_iawithaddr(mreq->imr_interface, rtableid);
+ if (ia)
+ ifp = ia->ia_ifp;
}
/*
* See if we found an interface, and confirm that it
@@ -1906,11 +1911,12 @@ ip_setmoptions(int optname, struct ip_mo
if (mreq->imr_interface.s_addr == INADDR_ANY)
ifp = NULL;
else {
- INADDR_TO_IFP(mreq->imr_interface, ifp, rtableid);
- if (ifp == NULL) {
+ ia = in_iawithaddr(mreq->imr_interface, rtableid);
+ if (ia == NULL) {
error = EADDRNOTAVAIL;
break;
}
+ ifp = ia->ia_ifp;
}
/*
* Find the membership in the membership array.
Index: netinet/in_var.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_var.h,v
retrieving revision 1.28
diff -u -p -r1.28 in_var.h
--- netinet/in_var.h 21 Nov 2013 16:34:33 -0000 1.28
+++ netinet/in_var.h 26 Nov 2013 11:34:18 -0000
@@ -82,23 +82,6 @@ TAILQ_HEAD(in_ifaddrhead, in_ifaddr);
extern struct in_ifaddrhead in_ifaddr;
/*
- * Macro for finding the interface (ifnet structure) corresponding to one
- * of our IP addresses.
- */
-#define INADDR_TO_IFP(addr, ifp, rtableid) \
- /* struct in_addr addr; */ \
- /* struct ifnet *ifp; */ \
-do { \
- struct in_ifaddr *ia; \
- \
- TAILQ_FOREACH(ia, &in_ifaddr, ia_list) \
- if (ia->ia_ifp->if_rdomain == rtable_l2(rtableid) && \
- ia->ia_addr.sin_addr.s_addr == (addr).s_addr) \
- break; \
- (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
-} while (/* CONSTCOND */ 0)
-
-/*
* Macro for finding the internet address structure (in_ifaddr) corresponding
* to a given interface (ifnet structure).
*/