svn commit: r274916 - in projects/routing/sys: net netinet netinet6
Alexander V. Chernikov
melifaro at FreeBSD.org
Sun Nov 23 12:15:30 UTC 2014
Author: melifaro
Date: Sun Nov 23 12:15:28 2014
New Revision: 274916
URL: https://svnweb.freebsd.org/changeset/base/274916
Log:
* Add lltable llt_hash callback
* Move lltable items insertions/deletions to generic llt code.
Modified:
projects/routing/sys/net/if_llatbl.c
projects/routing/sys/net/if_llatbl.h
projects/routing/sys/netinet/in.c
projects/routing/sys/netinet6/in6.c
Modified: projects/routing/sys/net/if_llatbl.c
==============================================================================
--- projects/routing/sys/net/if_llatbl.c Sun Nov 23 12:05:49 2014 (r274915)
+++ projects/routing/sys/net/if_llatbl.c Sun Nov 23 12:15:28 2014 (r274916)
@@ -92,6 +92,42 @@ done:
return (error);
}
+
+void
+llentry_link(struct lltable *llt, struct llentry *lle)
+{
+ struct llentries *lleh;
+ uint32_t hashkey;
+
+ hashkey = llt->llt_hash(lle);
+ lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
+
+ lle->lle_tbl = llt;
+ lle->lle_head = lleh;
+ lle->la_flags |= LLE_LINKED;
+ LIST_INSERT_HEAD(lleh, lle, lle_next);
+}
+
+void
+llentry_unlink(struct llentry *lle)
+{
+
+ LIST_REMOVE(lle, lle_next);
+ lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
+ lle->lle_tbl = NULL;
+ lle->lle_head = NULL;
+}
+
+void
+llentries_unlink(struct llentries *head)
+{
+ struct llentry *lle, *next;
+
+ LIST_FOREACH_SAFE(lle, head, lle_chain, next) {
+ llentry_unlink(lle);
+ }
+}
+
/*
* Deletes an address from the address table.
* This function is called by the timer functions
Modified: projects/routing/sys/net/if_llatbl.h
==============================================================================
--- projects/routing/sys/net/if_llatbl.h Sun Nov 23 12:05:49 2014 (r274915)
+++ projects/routing/sys/net/if_llatbl.h Sun Nov 23 12:15:28 2014 (r274916)
@@ -80,6 +80,7 @@ struct llentry {
uint16_t ln_router;
time_t ln_ntick;
int lle_refcnt;
+ LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
struct rwlock lle_lock;
/* XXX af-private? */
@@ -94,8 +95,6 @@ struct llentry {
#define LLE_RLOCK(lle) rw_rlock(&(lle)->lle_lock)
#define LLE_WUNLOCK(lle) rw_wunlock(&(lle)->lle_lock)
#define LLE_RUNLOCK(lle) rw_runlock(&(lle)->lle_lock)
-#define LLE_DOWNGRADE(lle) rw_downgrade(&(lle)->lle_lock)
-#define LLE_TRY_UPGRADE(lle) rw_try_upgrade(&(lle)->lle_lock)
#define LLE_LOCK_INIT(lle) rw_init_flags(&(lle)->lle_lock, "lle", RW_DUPOK)
#define LLE_LOCK_DESTROY(lle) rw_destroy(&(lle)->lle_lock)
#define LLE_WLOCK_ASSERT(lle) rw_assert(&(lle)->lle_lock, RA_WLOCKED)
@@ -157,6 +156,7 @@ typedef int (llt_delete_t)(struct lltabl
typedef void (llt_prefix_free_t)(struct lltable *,
const struct sockaddr *prefix, const struct sockaddr *mask, u_int flags);
typedef int (llt_dump_t)(struct lltable *, struct sysctl_req *);
+typedef uint32_t (llt_hash_t)(const struct llentry *);
struct lltable {
SLIST_ENTRY(lltable) llt_link;
@@ -169,6 +169,7 @@ struct lltable {
llt_delete_t *llt_delete;
llt_prefix_free_t *llt_prefix_free;
llt_dump_t *llt_dump;
+ llt_hash_t *llt_hash;
};
MALLOC_DECLARE(M_LLTABLE);
@@ -204,6 +205,9 @@ void lltable_drain(int);
#endif
int lltable_sysctl_dumparp(int, struct sysctl_req *);
+void llentry_link(struct lltable *, struct llentry *);
+void llentry_unlink(struct llentry *);
+void llentries_unlink(struct llentries *);
size_t llentry_free(struct llentry *);
struct llentry *llentry_alloc(struct ifnet *, struct lltable *,
struct sockaddr_storage *);
Modified: projects/routing/sys/netinet/in.c
==============================================================================
--- projects/routing/sys/netinet/in.c Sun Nov 23 12:05:49 2014 (r274915)
+++ projects/routing/sys/netinet/in.c Sun Nov 23 12:15:28 2014 (r274916)
@@ -78,9 +78,6 @@ static int in_difaddr_ioctl(caddr_t, str
static void in_socktrim(struct sockaddr_in *);
static void in_purgemaddrs(struct ifnet *);
-static void in_lltable_link(struct lltable *llt, struct llentry *lle);
-static void in_lltable_unlink(struct llentry *lle);
-
static VNET_DEFINE(int, nosameprefix);
#define V_nosameprefix VNET(nosameprefix)
SYSCTL_INT(_net_inet_ip, OID_AUTO, no_same_prefix, CTLFLAG_VNET | CTLFLAG_RW,
@@ -1048,9 +1045,11 @@ in_lltable_prefix_free(struct lltable *l
const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix;
const struct sockaddr_in *msk = (const struct sockaddr_in *)mask;
struct llentry *lle, *next;
+ struct llentries dchain;
int i;
size_t pkts_dropped;
+ LIST_INIT(&dchain);
IF_AFDATA_WLOCK(llt->llt_ifp);
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
@@ -1066,11 +1065,16 @@ in_lltable_prefix_free(struct lltable *l
LLE_REMREF(lle);
lle->la_flags &= ~LLE_CALLOUTREF;
}
- pkts_dropped = llentry_free(lle);
- ARPSTAT_ADD(dropped, pkts_dropped);
+ LIST_INSERT_HEAD(&dchain, lle, lle_chain);
}
}
}
+ /* Unlink chain */
+ llentries_unlink(&dchain);
+ LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
+ pkts_dropped = llentry_free(lle);
+ ARPSTAT_ADD(dropped, pkts_dropped);
+ }
IF_AFDATA_WUNLOCK(llt->llt_ifp);
}
@@ -1116,6 +1120,20 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
return (0);
}
+static inline uint32_t
+in_lltable_hash_dst(const struct in_addr dst)
+{
+
+ return (dst.s_addr);
+}
+
+static uint32_t
+in_lltable_hash(const struct llentry *lle)
+{
+
+ return (in_lltable_hash_dst(lle->r_l3addr.addr4));
+}
+
static inline struct llentry *
in_lltable_find_dst(struct lltable *llt, struct in_addr dst)
{
@@ -1157,7 +1175,7 @@ in_lltable_delete(struct lltable *llt, u
LLE_WLOCK(lle);
lle->la_flags |= LLE_DELETED;
EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
- in_lltable_unlink(lle);
+ llentry_unlink(lle);
#ifdef DIAGNOSTIC
log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
#endif
@@ -1210,40 +1228,12 @@ in_lltable_create(struct lltable *llt, u
lle->la_flags |= (LLE_VALID | LLE_STATIC);
}
- in_lltable_link(llt, lle);
+ llentry_link(llt, lle);
LLE_WLOCK(lle);
return (lle);
}
-static void
-in_lltable_link(struct lltable *llt, struct llentry *lle)
-{
- struct in_addr dst;
- struct llentries *lleh;
- u_int hashkey;
-
- dst = lle->r_l3addr.addr4;
- hashkey = dst.s_addr;
- lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
-
- lle->lle_tbl = llt;
- lle->lle_head = lleh;
- lle->la_flags |= LLE_LINKED;
- LIST_INSERT_HEAD(lleh, lle, lle_next);
-
-}
-
-static void
-in_lltable_unlink(struct llentry *lle)
-{
-
- LIST_REMOVE(lle, lle_next);
- lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
- lle->lle_tbl = NULL;
- lle->lle_head = NULL;
-}
-
/*
* Return NULL if not found or marked for deletion.
* If found return lle read locked.
@@ -1363,6 +1353,7 @@ in_domifattach(struct ifnet *ifp)
llt->llt_create = in_lltable_create;
llt->llt_delete = in_lltable_delete;
llt->llt_dump = in_lltable_dump;
+ llt->llt_hash = in_lltable_hash;
}
ii->ii_llt = llt;
Modified: projects/routing/sys/netinet6/in6.c
==============================================================================
--- projects/routing/sys/netinet6/in6.c Sun Nov 23 12:05:49 2014 (r274915)
+++ projects/routing/sys/netinet6/in6.c Sun Nov 23 12:15:28 2014 (r274916)
@@ -149,9 +149,6 @@ static int in6_update_ifa_internal(struc
static int in6_broadcast_ifa(struct ifnet *, struct in6_aliasreq *,
struct in6_ifaddr *, int);
-static void in6_lltable_link(struct lltable *llt, struct llentry *lle);
-static void in6_lltable_unlink(struct llentry *lle);
-
#define ifa2ia6(ifa) ((struct in6_ifaddr *)(ifa))
#define ia62ifa(ia6) (&((ia6)->ia_ifa))
@@ -2094,6 +2091,7 @@ in6_lltable_prefix_free(struct lltable *
{
const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
+ struct llentries dchain;
struct llentry *lle, *next;
int i;
@@ -2101,6 +2099,7 @@ in6_lltable_prefix_free(struct lltable *
* (flags & LLE_STATIC) means deleting all entries
* including static ND6 entries.
*/
+ LIST_INIT(&dchain);
IF_AFDATA_WLOCK(llt->llt_ifp);
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
@@ -2114,10 +2113,13 @@ in6_lltable_prefix_free(struct lltable *
LLE_REMREF(lle);
lle->la_flags &= ~LLE_CALLOUTREF;
}
- llentry_free(lle);
+ LIST_INSERT_HEAD(&dchain, lle, lle_chain);
}
}
}
+ llentries_unlink(&dchain);
+ LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
+ llentry_free(lle);
IF_AFDATA_WUNLOCK(llt->llt_ifp);
}
@@ -2158,6 +2160,20 @@ in6_lltable_rtcheck(struct ifnet *ifp,
return 0;
}
+static inline uint32_t
+in6_lltable_hash_dst(const struct in6_addr *dst)
+{
+
+ return (dst->s6_addr32[3]);
+}
+
+static uint32_t
+in6_lltable_hash(const struct llentry *lle)
+{
+
+ return (in6_lltable_hash_dst(&lle->r_l3addr.addr6));
+}
+
static inline struct llentry *
in6_lltable_find_dst(struct lltable *llt, const struct in6_addr *dst)
{
@@ -2165,7 +2181,7 @@ in6_lltable_find_dst(struct lltable *llt
struct llentries *lleh;
u_int hashkey;
- hashkey = dst->s6_addr32[3];
+ hashkey = in6_lltable_hash_dst(dst);
lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
LIST_FOREACH(lle, lleh, lle_next) {
if (IN6_ARE_ADDR_EQUAL(&lle->r_l3addr.addr6, dst) != 0)
@@ -2194,7 +2210,7 @@ in6_lltable_delete(struct lltable *llt,
if (!(lle->la_flags & LLE_IFADDR) || (flags & LLE_IFADDR)) {
LLE_WLOCK(lle);
lle->la_flags |= LLE_DELETED;
- in6_lltable_unlink(lle);
+ llentry_unlink(lle);
#ifdef DIAGNOSTIC
log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
#endif
@@ -2246,41 +2262,12 @@ in6_lltable_create(struct lltable *llt,
lle->la_flags |= (LLE_VALID | LLE_STATIC);
}
- in6_lltable_link(llt, lle);
+ llentry_link(llt, lle);
LLE_WLOCK(lle);
return (lle);
}
-static void
-in6_lltable_link(struct lltable *llt, struct llentry *lle)
-{
- struct in6_addr dst;
- struct llentries *lleh;
- u_int hashkey;
-
- dst = lle->r_l3addr.addr6;;
- hashkey = dst.s6_addr32[3];
- lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
-
- lle->lle_tbl = llt;
- lle->lle_head = lleh;
- lle->la_flags |= LLE_LINKED;
- LIST_INSERT_HEAD(lleh, lle, lle_next);
-
-}
-
-static void
-in6_lltable_unlink(struct llentry *lle)
-{
-
- LIST_REMOVE(lle, lle_next);
- lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
- lle->lle_tbl = NULL;
- lle->lle_head = NULL;
-}
-
-
static struct llentry *
in6_lltable_lookup(struct lltable *llt, u_int flags,
const struct sockaddr *l3addr)
@@ -2421,6 +2408,7 @@ in6_domifattach(struct ifnet *ifp)
ext->lltable->llt_create = in6_lltable_create;
ext->lltable->llt_delete = in6_lltable_delete;
ext->lltable->llt_dump = in6_lltable_dump;
+ ext->lltable->llt_hash = in6_lltable_hash;
}
ext->mld_ifinfo = mld_domifattach(ifp);
More information about the svn-src-projects
mailing list