svn commit: r198111 - head/sys/netinet
Qing Li
qingli at freebsd.org
Thu Oct 15 06:26:22 UTC 2009
Forgot to mention the return code was incorrect. The function was returning
EHOSTUNEACH when it should be returning EHOSTDOWN. This is also
fixed by this patch.
-- Qing
On Wed, Oct 14, 2009 at 11:12 PM, Qing Li <qingli at freebsd.org> wrote:
> Author: qingli
> Date: Thu Oct 15 06:12:04 2009
> New Revision: 198111
> URL: http://svn.freebsd.org/changeset/base/198111
>
> Log:
> 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.
>
> Reviewed by: kmacy
> MFC after: 3 days
>
> Modified:
> head/sys/netinet/if_ether.c
> head/sys/netinet/in.c
>
> Modified: head/sys/netinet/if_ether.c
> ==============================================================================
> --- head/sys/netinet/if_ether.c Thu Oct 15 06:02:37 2009 (r198110)
> +++ head/sys/netinet/if_ether.c Thu Oct 15 06:12:04 2009 (r198111)
> @@ -88,11 +88,14 @@ 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);
> static VNET_DEFINE(struct arpstat, arpstat); /* ARP statistics, see if_arp.h */
>
> #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)
> #define V_arpstat VNET(arpstat)
> @@ -309,7 +312,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,
> @@ -317,7 +320,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));
>
> @@ -337,7 +340,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);
> @@ -370,12 +373,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,
> @@ -687,7 +690,7 @@ match:
> EVENTHANDLER_INVOKE(arp_update_event, la);
>
> 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: head/sys/netinet/in.c
> ==============================================================================
> --- head/sys/netinet/in.c Thu Oct 15 06:02:37 2009 (r198110)
> +++ head/sys/netinet/in.c Thu Oct 15 06:12:04 2009 (r198111)
> @@ -1440,7 +1440,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)
> @@ -1472,10 +1472,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;
>
More information about the svn-src-all
mailing list