summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2007-12-31 23:48:06 +0000
committerjulian <julian@FreeBSD.org>2007-12-31 23:48:06 +0000
commit3032c5c97143e8c0b92bae65601cbb7f7c746699 (patch)
treecafc9402b17d1ecb4bfcf6e0b22f4480ebac9217
parent9cea85864d49868ad2155b6f59d9ebd33a998a3f (diff)
downloadFreeBSD-src-3032c5c97143e8c0b92bae65601cbb7f7c746699.zip
FreeBSD-src-3032c5c97143e8c0b92bae65601cbb7f7c746699.tar.gz
Don't duplicate the whole of arpresolve to arpresolve 2 for the sake
of two compares against 0. The negative effect of cache flushing is probably more than the gain by not doing the two compares (the value is almost certainly in register or at worst, cache). Note that the uses of m_freem() are in error cases and m_freem() handles NULL anyhow. So fast-path really isn't changed much at all.
-rw-r--r--sys/dev/cxgb/cxgb_l2t.c16
-rw-r--r--sys/netinet/if_ether.c139
-rw-r--r--sys/netinet/if_ether.h2
3 files changed, 29 insertions, 128 deletions
diff --git a/sys/dev/cxgb/cxgb_l2t.c b/sys/dev/cxgb/cxgb_l2t.c
index f3e02f2..ad7ad1e 100644
--- a/sys/dev/cxgb/cxgb_l2t.c
+++ b/sys/dev/cxgb/cxgb_l2t.c
@@ -183,7 +183,8 @@ t3_l2t_send_slow(struct t3cdev *dev, struct mbuf *m, struct l2t_entry *e)
again:
switch (e->state) {
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
- arpresolve2(rt->rt_ifp, rt, (struct sockaddr *)&sin, e->dmac);
+ arpresolve(rt->rt_ifp, rt, NULL,
+ (struct sockaddr *)&sin, e->dmac);
mtx_lock(&e->lock);
if (e->state == L2T_STATE_STALE)
e->state = L2T_STATE_VALID;
@@ -208,8 +209,9 @@ again:
* A better way would be to use a work request to retry L2T
* entries when there's no memory.
*/
- printf("doing arpresolve2 on 0x%x \n", e->addr);
- if (arpresolve2(rt->rt_ifp, rt, (struct sockaddr *)&sin, e->dmac) == 0) {
+ printf("doing arpresolve on 0x%x \n", e->addr);
+ if (arpresolve(rt->rt_ifp, rt, NULL,
+ (struct sockaddr *)&sin, e->dmac) == 0) {
printf("mac=%x:%x:%x:%x:%x:%x\n",
e->dmac[0], e->dmac[1], e->dmac[2], e->dmac[3], e->dmac[4], e->dmac[5]);
@@ -223,7 +225,7 @@ again:
m_freem(m);
mtx_unlock(&e->lock);
} else
- printf("arpresolve2 returned non-zero\n");
+ printf("arpresolve returned non-zero\n");
}
return 0;
}
@@ -245,7 +247,8 @@ t3_l2t_send_event(struct t3cdev *dev, struct l2t_entry *e)
again:
switch (e->state) {
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
- arpresolve2(rt->rt_ifp, rt, (struct sockaddr *)&sin, e->dmac);
+ arpresolve(rt->rt_ifp, rt, NULL,
+ (struct sockaddr *)&sin, e->dmac);
mtx_lock(&e->lock);
if (e->state == L2T_STATE_STALE) {
e->state = L2T_STATE_VALID;
@@ -270,7 +273,8 @@ again:
* A better way would be to use a work request to retry L2T
* entries when there's no memory.
*/
- arpresolve2(rt->rt_ifp, rt, (struct sockaddr *)&sin, e->dmac);
+ arpresolve(rt->rt_ifp, rt, NULL,
+ (struct sockaddr *)&sin, e->dmac);
}
return;
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index f6c5c12..b1133c9 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -344,14 +344,15 @@ arprequest(struct ifnet *ifp, struct in_addr *sip, struct in_addr *tip,
* 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
+ * m is the mbuf. May be NULL if we don't have a packet.
+ * dst is the next hop,
* 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.
+ * Note that m_freem() handles NULL.
*/
int
arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
@@ -362,13 +363,18 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
struct sockaddr_dl *sdl;
int error;
- if (m->m_flags & M_BCAST) { /* broadcast */
- (void)memcpy(desten, ifp->if_broadcastaddr, ifp->if_addrlen);
- return (0);
- }
- if (m->m_flags & M_MCAST && ifp->if_type != IFT_ARCNET) {/* multicast */
- ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
- return (0);
+ if (m) {
+ if (m->m_flags & M_BCAST) {
+ /* broadcast */
+ (void)memcpy(desten,
+ ifp->if_broadcastaddr, ifp->if_addrlen);
+ return (0);
+ }
+ if (m->m_flags & M_MCAST && ifp->if_type != IFT_ARCNET) {
+ /* multicast */
+ ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
+ return (0);
+ }
}
if (rt0 != NULL) {
@@ -449,117 +455,10 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
* response yet. Replace the held mbuf with this
* latest one.
*/
- if (la->la_hold)
- m_freem(la->la_hold);
- la->la_hold = m;
- KASSERT(rt->rt_expire > 0, ("sending ARP request for static entry"));
-
- /*
- * Return EWOULDBLOCK if we have tried less than arp_maxtries. It
- * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH
- * if we have already sent arp_maxtries ARP requests. Retransmit the
- * ARP request, but not faster than one request per second.
- */
- if (la->la_asked < arp_maxtries)
- error = EWOULDBLOCK; /* First request. */
- else
- error = (rt == rt0) ? EHOSTDOWN : EHOSTUNREACH;
-
- if (la->la_asked == 0 || rt->rt_expire != time_uptime) {
- struct in_addr sin =
- SIN(rt->rt_ifa->ifa_addr)->sin_addr;
-
- rt->rt_expire = time_uptime;
- callout_reset(&la->la_timer, hz, arptimer, rt);
- la->la_asked++;
- RT_UNLOCK(rt);
-
- arprequest(ifp, &sin, &SIN(dst)->sin_addr,
- IF_LLADDR(ifp));
- } else
- RT_UNLOCK(rt);
-
- return (error);
-}
-
-
-int
-arpresolve2(struct ifnet *ifp, struct rtentry *rt0, struct sockaddr *dst,
- u_char *desten)
-{
- struct llinfo_arp *la = NULL;
- struct rtentry *rt = NULL;
- struct sockaddr_dl *sdl;
- int error;
-
- if (rt0 != NULL) {
- error = rt_check(&rt, &rt0, dst);
- if (error)
- return (error);
-
- la = (struct llinfo_arp *)rt->rt_llinfo;
- if (la == NULL)
- RT_UNLOCK(rt);
- }
- if (la == NULL) {
- /*
- * We enter this block in case if rt0 was NULL,
- * or if rt found by rt_check() didn't have llinfo.
- */
- rt = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0);
- if (rt == NULL) {
- log(LOG_DEBUG,
- "arpresolve: can't allocate route for %s\n",
- inet_ntoa(SIN(dst)->sin_addr));
- return (EINVAL); /* XXX */
- }
- la = (struct llinfo_arp *)rt->rt_llinfo;
- if (la == NULL) {
- RT_UNLOCK(rt);
- log(LOG_DEBUG,
- "arpresolve: can't allocate llinfo for %s\n",
- inet_ntoa(SIN(dst)->sin_addr));
- return (EINVAL); /* XXX */
- }
- }
- sdl = SDL(rt->rt_gateway);
- /*
- * Check the address family and length is valid, the address
- * is resolved; otherwise, try to resolve.
- */
- if ((rt->rt_expire == 0 || rt->rt_expire > time_uptime) &&
- sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
-
- bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
-
- /*
- * If entry has an expiry time and it is approaching,
- * send an ARP request.
- */
- if ((rt->rt_expire != 0) &&
- (time_uptime + la->la_preempt > rt->rt_expire)) {
- struct in_addr sin =
- SIN(rt->rt_ifa->ifa_addr)->sin_addr;
-
- la->la_preempt--;
- RT_UNLOCK(rt);
- arprequest(ifp, &sin, &SIN(dst)->sin_addr,
- IF_LLADDR(ifp));
- return (0);
- }
-
- RT_UNLOCK(rt);
- return (0);
- }
- /*
- * If ARP is disabled or static on this interface, stop.
- * XXX
- * Probably should not allocate empty llinfo struct if we are
- * not going to be sending out an arp request.
- */
- if (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) {
- RT_UNLOCK(rt);
- return (EINVAL);
+ if (m) {
+ if (la->la_hold)
+ m_freem(la->la_hold);
+ la->la_hold = m;
}
KASSERT(rt->rt_expire > 0, ("sending ARP request for static entry"));
diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h
index ae2b0d0..14df15f 100644
--- a/sys/netinet/if_ether.h
+++ b/sys/netinet/if_ether.h
@@ -111,8 +111,6 @@ extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
int arpresolve(struct ifnet *ifp, struct rtentry *rt,
struct mbuf *m, struct sockaddr *dst, u_char *desten);
-int arpresolve2(struct ifnet *ifp, struct rtentry *rt,
- struct sockaddr *dst, u_char *desten);
void arp_ifinit(struct ifnet *, struct ifaddr *);
void arp_ifinit2(struct ifnet *, struct ifaddr *, u_char *);
#endif
OpenPOWER on IntegriCloud