diff options
-rw-r--r-- | sys/dev/cxgb/cxgb_l2t.c | 16 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 139 | ||||
-rw-r--r-- | sys/netinet/if_ether.h | 2 |
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 |