Date: Tue, 20 Oct 2009 17:44:51 +0000 (UTC) From: Qing Li <qingli@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r198298 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/xen/xenpci netinet Message-ID: <200910201744.n9KHipOo073637@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: qingli Date: Tue Oct 20 17:44:50 2009 New Revision: 198298 URL: http://svn.freebsd.org/changeset/base/198298 Log: MFC r198111 This patch fixes the following issues in the ARP operation: 1. There is a regression issue in the ARP code. The incomplete ARP entry was timing out too quickly (1 second timeout), as such, a new entry is created each time arpresolve() is called. Therefore the maximum attempts made is always 1. Consequently the error code returned to the application is always 0. 2. Set the expiration of each incomplete entry to a 20-second lifetime. 3. Return "incomplete" entries to the application. 4. The return error code was incorrect. Reviewed by: kmacy Approved by: re Modified: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/netinet/if_ether.c stable/8/sys/netinet/in.c Modified: stable/8/sys/netinet/if_ether.c ============================================================================== --- stable/8/sys/netinet/if_ether.c Tue Oct 20 16:46:39 2009 (r198297) +++ stable/8/sys/netinet/if_ether.c Tue Oct 20 17:44:50 2009 (r198298) @@ -87,10 +87,13 @@ VNET_DEFINE(int, useloopback) = 1; /* us /* timer values */ static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20 * minutes */ +static VNET_DEFINE(int, arpt_down) = 20; /* keep incomplete entries for + * 20 seconds */ static VNET_DEFINE(int, arp_maxtries) = 5; static VNET_DEFINE(int, arp_proxyall); #define V_arpt_keep VNET(arpt_keep) +#define V_arpt_down VNET(arpt_down) #define V_arp_maxtries VNET(arp_maxtries) #define V_arp_proxyall VNET(arp_proxyall) @@ -299,7 +302,7 @@ retry: } if ((la->la_flags & LLE_VALID) && - ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) { + ((la->la_flags & LLE_STATIC) || la->la_expire > time_second)) { bcopy(&la->ll_addr, desten, ifp->if_addrlen); /* * If entry has an expiry time and it is approaching, @@ -307,7 +310,7 @@ retry: * arpt_down interval. */ if (!(la->la_flags & LLE_STATIC) && - time_uptime + la->la_preempt > la->la_expire) { + time_second + la->la_preempt > la->la_expire) { arprequest(ifp, NULL, &SIN(dst)->sin_addr, IF_LLADDR(ifp)); @@ -327,7 +330,7 @@ retry: goto done; } - renew = (la->la_asked == 0 || la->la_expire != time_uptime); + renew = (la->la_asked == 0 || la->la_expire != time_second); if ((renew || m != NULL) && (flags & LLE_EXCLUSIVE) == 0) { flags |= LLE_EXCLUSIVE; LLE_RUNLOCK(la); @@ -358,12 +361,12 @@ retry: error = EWOULDBLOCK; /* First request. */ else error = - (rt0->rt_flags & RTF_GATEWAY) ? EHOSTDOWN : EHOSTUNREACH; + (rt0->rt_flags & RTF_GATEWAY) ? EHOSTUNREACH : EHOSTDOWN; if (renew) { LLE_ADDREF(la); - la->la_expire = time_uptime; - callout_reset(&la->la_timer, hz, arptimer, la); + la->la_expire = time_second; + callout_reset(&la->la_timer, hz * V_arpt_down, arptimer, la); la->la_asked++; LLE_WUNLOCK(la); arprequest(ifp, NULL, &SIN(dst)->sin_addr, @@ -668,7 +671,7 @@ match: la->la_flags |= LLE_VALID; if (!(la->la_flags & LLE_STATIC)) { - la->la_expire = time_uptime + V_arpt_keep; + la->la_expire = time_second + V_arpt_keep; callout_reset(&la->la_timer, hz * V_arpt_keep, arptimer, la); } Modified: stable/8/sys/netinet/in.c ============================================================================== --- stable/8/sys/netinet/in.c Tue Oct 20 16:46:39 2009 (r198297) +++ stable/8/sys/netinet/in.c Tue Oct 20 17:44:50 2009 (r198298) @@ -1439,7 +1439,7 @@ in_lltable_dump(struct lltable *llt, str struct sockaddr_dl *sdl; /* skip deleted entries */ - if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID) + if ((lle->la_flags & LLE_DELETED) == LLE_DELETED) continue; /* Skip if jailed and not a valid IP of the prison. */ if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0) @@ -1471,10 +1471,15 @@ in_lltable_dump(struct lltable *llt, str sdl = &arpc.sdl; sdl->sdl_family = AF_LINK; sdl->sdl_len = sizeof(*sdl); - sdl->sdl_alen = ifp->if_addrlen; sdl->sdl_index = ifp->if_index; sdl->sdl_type = ifp->if_type; - bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen); + if ((lle->la_flags & LLE_VALID) == LLE_VALID) { + sdl->sdl_alen = ifp->if_addrlen; + bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen); + } else { + sdl->sdl_alen = 0; + bzero(LLADDR(sdl), ifp->if_addrlen); + } arpc.rtm.rtm_rmx.rmx_expire = lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910201744.n9KHipOo073637>