Here's a diff to stop dealing with AF_LINK addresses in ifa_ifwithnet(9).
                                                                  ^^^
The only place where such thing happens is when ifa_ifwithroute() do its
magic to find an address for a route.  So in this case, it does the check
directly and get the corresponding ifa.

ifa_ifwithnet(9) is mostly used by the routine code to find an appropriate
address, hopefully with might get rid of it.  But for the moment I'd
like to remove the AF_LINK case because it is unintuitive and does not
iterate on the global list of interfaces.

While here, rename a rdomain -> rtableid, this is what you want!

As a bonus, this diff comes with a manual.

ok?


Index: share/man/man9/Makefile
===================================================================
RCS file: /cvs/src/share/man/man9/Makefile,v
retrieving revision 1.208
diff -u -p -r1.208 Makefile
--- share/man/man9/Makefile     10 Apr 2014 13:47:21 -0000      1.208
+++ share/man/man9/Makefile     10 Apr 2014 13:59:39 -0000
@@ -16,7 +16,7 @@ MAN=  altq.9 aml_evalnode.9 atomic_add_in
        hardclock.9 hook_establish.9 hz.9 hzto.9 idgen32.9 \
        ieee80211.9 ieee80211_crypto.9 ieee80211_input.9 ieee80211_ioctl.9 \
        ieee80211_node.9 ieee80211_output.9 ieee80211_proto.9 \
-       ieee80211_radiotap.9 \
+       ieee80211_radiotap.9 ifa_ifwithnet.9 \
        iic.9 intro.9 inittodr.9 \
        kern.9 km_alloc.9 knote.9 kthread.9 ktrace.9 \
        loadfirmware.9 lock.9 log.9 \
Index: share/man/man9/ifa_ifwithnet.9
===================================================================
RCS file: share/man/man9/ifa_ifwithnet.9
diff -N share/man/man9/ifa_ifwithnet.9
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ share/man/man9/ifa_ifwithnet.9      10 Apr 2014 13:59:39 -0000
@@ -0,0 +1,46 @@
+.\"    $OpenBSD$
+.\"
+.\" Copyright (c) 2014 Martin Pieuchot 
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate$
+.Dt IFA_IFWITHNET 9
+.Os
+.Sh NAME
+.Nm ifa_ifwithnet
+.Nd find an address on a specific network
+.Sh SYNOPSIS
+.In sys/socket.h
+.In net/if.h
+.Ft "struct ifaddr *"
+.Fn ifa_ifwithnet "struct sockaddr *sa" "u_int rtableid"
+.Sh DESCRIPTION
+.Fn ifa_ifwithnet
+iterates on all the address of all the interfaces in the routing domain of
+routing table
+.Fa rtableid
+and returns the most specific address matching
+.Fa sa .
+.Sh CONTEXT
+.Fn ifa_ifwithnet
+can be called during autoconf, from process context, or from interrupt context.
+.Sh RETURN VALUES
+.Fn ifa_ifwithnet
+will return the most specific configured address matching
+.Fa sa
+on success
+.Dv NULL
+otherwise.
+.Sh SEE ALSO
+.Xr rtable_l2 9
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.283
diff -u -p -r1.283 if.c
--- sys/net/if.c        10 Apr 2014 13:47:21 -0000      1.283
+++ sys/net/if.c        10 Apr 2014 13:59:48 -0000
@@ -904,27 +904,21 @@ ifa_ifwithdstaddr(struct sockaddr *addr,
  * is most specific found.
  */
 struct ifaddr *
-ifa_ifwithnet(struct sockaddr *addr, u_int rdomain)
+ifa_ifwithnet(struct sockaddr *sa, u_int rtableid)
 {
        struct ifnet *ifp;
-       struct ifaddr *ifa;
-       struct ifaddr *ifa_maybe = 0;
-       u_int af = addr->sa_family;
-       char *addr_data = addr->sa_data, *cplim;
+       struct ifaddr *ifa, *ifa_maybe = NULL;
+       char *cplim, *addr_data = sa->sa_data;
+       u_int rdomain;
 
-       rdomain = rtable_l2(rdomain);
-       if (af == AF_LINK) {
-               struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
-               if (sdl->sdl_index && (ifp = if_get(sdl->sdl_index)) != NULL)
-                       return (ifp->if_lladdr);
-       }
+       rdomain = rtable_l2(rtableid);
        TAILQ_FOREACH(ifp, &ifnet, if_list) {
                if (ifp->if_rdomain != rdomain)
                        continue;
                TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
                        char *cp, *cp2, *cp3;
 
-                       if (ifa->ifa_addr->sa_family != af ||
+                       if (ifa->ifa_addr->sa_family != sa->sa_family ||
                            ifa->ifa_netmask == 0)
                                next: continue;
                        cp = addr_data;
Index: sys/net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.160
diff -u -p -r1.160 route.c
--- sys/net/route.c     10 Apr 2014 13:55:55 -0000      1.160
+++ sys/net/route.c     10 Apr 2014 13:59:49 -0000
@@ -649,8 +649,17 @@ ifa_ifwithroute(int flags, struct sockad
                 */
                ifa = ifa_ifwithdstaddr(gateway, rtableid);
        }
-       if (ifa == NULL)
-               ifa = ifa_ifwithnet(gateway, rtableid);
+       if (ifa == NULL) {
+               if (gateway->sa_family == AF_LINK) {
+                       struct sockaddr_dl *sdl = (struct sockaddr_dl *)gateway;
+                       struct ifnet *ifp = if_get(sdl->sdl_index);
+
+                       if (ifp != NULL)
+                               ifa = ifp->if_lladdr;
+               } else {
+                       ifa = ifa_ifwithnet(gateway, rtableid);
+               }
+       }
        if (ifa == NULL) {
                struct rtentry  *rt = rtalloc1(gateway, 0, rtable_l2(rtableid));
                if (rt == NULL)

Reply via email to