From owner-svn-src-projects@FreeBSD.ORG Sun Nov 23 12:15:30 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 28BE72E0; Sun, 23 Nov 2014 12:15:30 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 09BA3DC7; Sun, 23 Nov 2014 12:15:30 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sANCFTjU031419; Sun, 23 Nov 2014 12:15:29 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sANCFTsB031413; Sun, 23 Nov 2014 12:15:29 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201411231215.sANCFTsB031413@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sun, 23 Nov 2014 12:15:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r274916 - in projects/routing/sys: net netinet netinet6 X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 Nov 2014 12:15:30 -0000 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);