diff options
author | kmacy <kmacy@FreeBSD.org> | 2012-01-26 20:02:40 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2012-01-26 20:02:40 +0000 |
commit | 8466f3ca886feafe17fd7d572669c98e463ce34d (patch) | |
tree | 98d66f731634129c7a5a13a96369ba4514ffbac8 /sys/net | |
parent | 891dd313e70093cc92443c7fb6b047395b1310db (diff) | |
download | FreeBSD-src-8466f3ca886feafe17fd7d572669c98e463ce34d.zip FreeBSD-src-8466f3ca886feafe17fd7d572669c98e463ce34d.tar.gz |
A flowtable entry can continue referencing an llentry indefinitely if the entry is repeatedly
referenced within its timeout window. This change clears the LLE_VALID flag when an llentry
is removed from an interface's hash table and adds an extra check to the flowtable code
for the LLE_VALID flag in llentry to avoid retaining and using a stale reference.
Reviewed by: qingli@
MFC after: 2 weeks
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/flowtable.c | 4 | ||||
-rw-r--r-- | sys/net/if_llatbl.c | 1 |
2 files changed, 4 insertions, 1 deletions
diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index 7814e3a..fac0f59 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -1186,12 +1186,14 @@ keycheck: rt = __DEVOLATILE(struct rtentry *, fle->f_rt); lle = __DEVOLATILE(struct llentry *, fle->f_lle); if ((rt != NULL) + && lle != NULL && fle->f_fhash == hash && flowtable_key_equal(fle, key) && (proto == fle->f_proto) && (fibnum == fle->f_fibnum) && (rt->rt_flags & RTF_UP) - && (rt->rt_ifp != NULL)) { + && (rt->rt_ifp != NULL) + && (lle->la_flags & LLE_VALID)) { fs->ft_hits++; fle->f_uptime = time_uptime; fle->f_flags |= flags; diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index 559a174..8092f0f 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -122,6 +122,7 @@ llentry_free(struct llentry *lle) ("%s: la_numheld %d > 0, pkts_droped %zd", __func__, lle->la_numheld, pkts_dropped)); + lle->la_flags &= ~LLE_VALID; LLE_FREE_LOCKED(lle); return (pkts_dropped); |