summaryrefslogtreecommitdiffstats
path: root/sys/netinet/if_ether.c
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2004-04-25 09:24:52 +0000
committerluigi <luigi@FreeBSD.org>2004-04-25 09:24:52 +0000
commit59063f7a089ed07823309dc56641c8a847f21c23 (patch)
treeb64da6798f0d544a1f0a0369b5c8f192b6c31e34 /sys/netinet/if_ether.c
parent6430766c7e3512aa8239ab4ffe30ab8faa9dfe7d (diff)
downloadFreeBSD-src-59063f7a089ed07823309dc56641c8a847f21c23.zip
FreeBSD-src-59063f7a089ed07823309dc56641c8a847f21c23.tar.gz
This commit does two things:
1. rt_check() cleanup: rt_check() is only necessary for some address families to gain access to the corresponding arp entry, so call it only in/near the *resolve() routines where it is actually used -- at the moment this is arpresolve(), nd6_storelladdr() (the call is embedded here), and atmresolve() (the call is just before atmresolve to reduce the number of changes). This change will make it a lot easier to decouple the arp table from the routing table. There is an extra call to rt_check() in if_iso88025subr.c to determine the routing info length. I have left it alone for the time being. The interface of arpresolve() and nd6_storelladdr() now changes slightly: + the 'rtentry' parameter (really a hint from the upper level layer) is now passed unchanged from *_output(), so it becomes the route to the final destination and not to the gateway. + the routines will return 0 if resolution is possible, non-zero otherwise. + arpresolve() returns EWOULDBLOCK in case the mbuf is being held waiting for an arp reply -- in this case the error code is masked in the caller so the upper layer protocol will not see a failure. 2. arpcom untangling Where possible, use 'struct ifnet' instead of 'struct arpcom' variables, and use the IFP2AC macro to access arpcom fields. This mostly affects the netatalk code. === Detailed changes: === net/if_arcsubr.c rt_check() cleanup, remove a useless variable net/if_atmsubr.c rt_check() cleanup net/if_ethersubr.c rt_check() cleanup, arpcom untangling net/if_fddisubr.c rt_check() cleanup, arpcom untangling net/if_iso88025subr.c rt_check() cleanup netatalk/aarp.c arpcom untangling, remove a block of duplicated code netatalk/at_extern.h arpcom untangling netinet/if_ether.c rt_check() cleanup (change arpresolve) netinet6/nd6.c rt_check() cleanup (change nd6_storelladdr)
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r--sys/netinet/if_ether.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 4c91522..1bdc1fb 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -341,21 +341,42 @@ arprequest(ifp, sip, tip, enaddr)
* that desten has been filled in and the packet should be sent
* normally; a 0 return indicates that the packet has been
* taken over here, either now or for later transmission.
+ *
+ * NEW COMMENT
+ * Resolve an IP address into an ethernet address.
+ * On input:
+ * ifp is the interface we use
+ * dst is the next hop,
+ * rt0 is the route to the final destination (possibly useless)
+ * m is the mbuf
+ * desten is where we want the address.
+ *
+ * On success, desten is filled in and the function returns 0;
+ * If the packet must be held pending resolution, we return EWOULDBLOCK
+ * On other errors, we return the corresponding error code.
*/
int
-arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
+arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
struct sockaddr *dst, u_char *desten)
{
struct llinfo_arp *la = 0;
struct sockaddr_dl *sdl;
+ int error;
+ struct rtentry *rt;
+
+ error = rt_check(&rt, &rt0, dst);
+ if (error) {
+ m_freem(m);
+ return error;
+ }
if (m->m_flags & M_BCAST) { /* broadcast */
(void)memcpy(desten, ifp->if_broadcastaddr, ifp->if_addrlen);
- return (1);
+ return (0);
}
if (m->m_flags & M_MCAST && ifp->if_type != IFT_ARCNET) {/* multicast */
ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
- return(1);
+ return (0);
}
if (rt)
la = (struct llinfo_arp *)rt->rt_llinfo;
@@ -369,7 +390,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
inet_ntoa(SIN(dst)->sin_addr), la ? "la" : "",
rt ? "rt" : "");
m_freem(m);
- return (0);
+ return (EINVAL); /* XXX */
}
sdl = SDL(rt->rt_gateway);
/*
@@ -393,7 +414,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
}
bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
- return 1;
+ return (0);
}
/*
* If ARP is disabled or static on this interface, stop.
@@ -403,7 +424,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
*/
if (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) {
m_freem(m);
- return (0);
+ return (EINVAL);
}
/*
* There is an arptab entry, but no ethernet address
@@ -433,7 +454,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
}
RT_UNLOCK(rt);
}
- return (0);
+ return (EWOULDBLOCK);
}
/*
OpenPOWER on IntegriCloud