svn commit: r198111 - head/sys/netinet
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 */ #defineV_arpt_keep VNET(arpt_keep) +#defineV_arpt_down VNET(arpt_down) #defineV_arp_maxtries VNET(arp_maxtries) #defineV_arp_proxyall VNET(arp_proxyall) #defineV_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
Re: svn commit: r198111 - head/sys/netinet
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 qin...@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. */