gif: use hashalloc(9)
Functional change is that on destruction INVARIANTS checks will run. Also the mask is no longer hardcoded, so makes it easier to make hash size a tunable. Reviewed by: ae Differential Revision: https://reviews.freebsd.org/D56176
This commit is contained in:
@@ -254,27 +254,6 @@ static moduledata_t gif_mod = {
|
||||
DECLARE_MODULE(if_gif, gif_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
|
||||
MODULE_VERSION(if_gif, 1);
|
||||
|
||||
struct gif_list *
|
||||
gif_hashinit(void)
|
||||
{
|
||||
struct gif_list *hash;
|
||||
int i;
|
||||
|
||||
hash = malloc(sizeof(struct gif_list) * GIF_HASH_SIZE,
|
||||
M_GIF, M_WAITOK);
|
||||
for (i = 0; i < GIF_HASH_SIZE; i++)
|
||||
CK_LIST_INIT(&hash[i]);
|
||||
|
||||
return (hash);
|
||||
}
|
||||
|
||||
void
|
||||
gif_hashdestroy(struct gif_list *hash)
|
||||
{
|
||||
|
||||
free(hash, M_GIF);
|
||||
}
|
||||
|
||||
#define MTAG_GIF 1080679712
|
||||
static int
|
||||
gif_transmit(struct ifnet *ifp, struct mbuf *m)
|
||||
|
||||
@@ -96,10 +96,6 @@ struct etherip_header {
|
||||
|
||||
#define GIF_WAIT() epoch_wait_preempt(net_epoch_preempt)
|
||||
|
||||
/* Prototypes */
|
||||
struct gif_list *gif_hashinit(void);
|
||||
void gif_hashdestroy(struct gif_list *);
|
||||
|
||||
void gif_input(struct mbuf *, struct ifnet *, int, uint8_t);
|
||||
int gif_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
|
||||
struct route *);
|
||||
|
||||
+21
-6
@@ -46,6 +46,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/hash.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
@@ -81,15 +82,17 @@ SYSCTL_INT(_net_inet_ip, IPCTL_GIF_TTL, gifttl, CTLFLAG_VNET | CTLFLAG_RW,
|
||||
*/
|
||||
VNET_DEFINE_STATIC(struct gif_list *, ipv4_hashtbl) = NULL;
|
||||
VNET_DEFINE_STATIC(struct gif_list *, ipv4_srchashtbl) = NULL;
|
||||
VNET_DEFINE_STATIC(u_int, ipv4_hashmask);
|
||||
VNET_DEFINE_STATIC(struct gif_list, ipv4_list) = CK_LIST_HEAD_INITIALIZER();
|
||||
#define V_ipv4_hashtbl VNET(ipv4_hashtbl)
|
||||
#define V_ipv4_srchashtbl VNET(ipv4_srchashtbl)
|
||||
#define V_ipv4_hashmask VNET(ipv4_hashmask)
|
||||
#define V_ipv4_list VNET(ipv4_list)
|
||||
|
||||
#define GIF_HASH(src, dst) (V_ipv4_hashtbl[\
|
||||
in_gif_hashval((src), (dst)) & (GIF_HASH_SIZE - 1)])
|
||||
in_gif_hashval((src), (dst)) & (V_ipv4_hashmask - 1)])
|
||||
#define GIF_SRCHASH(src) (V_ipv4_srchashtbl[\
|
||||
fnv_32_buf(&(src), sizeof(src), FNV1_32_INIT) & (GIF_HASH_SIZE - 1)])
|
||||
fnv_32_buf(&(src), sizeof(src), FNV1_32_INIT) & (V_ipv4_hashmask - 1)])
|
||||
#define GIF_HASH_SC(sc) GIF_HASH((sc)->gif_iphdr->ip_src.s_addr,\
|
||||
(sc)->gif_iphdr->ip_dst.s_addr)
|
||||
static uint32_t
|
||||
@@ -218,8 +221,15 @@ in_gif_ioctl(struct gif_softc *sc, u_long cmd, caddr_t data)
|
||||
break;
|
||||
}
|
||||
if (V_ipv4_hashtbl == NULL) {
|
||||
V_ipv4_hashtbl = gif_hashinit();
|
||||
V_ipv4_srchashtbl = gif_hashinit();
|
||||
struct hashalloc_args ha = {
|
||||
.size = GIF_HASH_SIZE,
|
||||
.mtype = M_GIF,
|
||||
.mflags = M_WAITOK,
|
||||
.head = HASH_HEAD_CK_LIST,
|
||||
};
|
||||
V_ipv4_hashtbl = hashalloc(&ha);
|
||||
V_ipv4_srchashtbl = hashalloc(&ha);
|
||||
V_ipv4_hashmask = ha.size - 1;
|
||||
}
|
||||
error = in_gif_checkdup(sc, src->sin_addr.s_addr,
|
||||
dst->sin_addr.s_addr);
|
||||
@@ -438,9 +448,14 @@ in_gif_uninit(void)
|
||||
ip_encap_unregister_srcaddr(ipv4_srcaddrtab);
|
||||
}
|
||||
if (V_ipv4_hashtbl != NULL) {
|
||||
gif_hashdestroy(V_ipv4_hashtbl);
|
||||
struct hashalloc_args ha = {
|
||||
.size = V_ipv4_hashmask + 1,
|
||||
.mtype = M_GIF,
|
||||
.head = HASH_HEAD_CK_LIST,
|
||||
};
|
||||
hashfree(V_ipv4_hashtbl, &ha);
|
||||
V_ipv4_hashtbl = NULL;
|
||||
GIF_WAIT();
|
||||
gif_hashdestroy(V_ipv4_srchashtbl);
|
||||
hashfree(V_ipv4_srchashtbl, &ha);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-6
@@ -47,6 +47,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/hash.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
@@ -86,15 +87,17 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim,
|
||||
*/
|
||||
VNET_DEFINE_STATIC(struct gif_list *, ipv6_hashtbl) = NULL;
|
||||
VNET_DEFINE_STATIC(struct gif_list *, ipv6_srchashtbl) = NULL;
|
||||
VNET_DEFINE_STATIC(u_int, ipv6_hashmask);
|
||||
VNET_DEFINE_STATIC(struct gif_list, ipv6_list) = CK_LIST_HEAD_INITIALIZER();
|
||||
#define V_ipv6_hashtbl VNET(ipv6_hashtbl)
|
||||
#define V_ipv6_srchashtbl VNET(ipv6_srchashtbl)
|
||||
#define V_ipv6_hashmask VNET(ipv6_hashmask)
|
||||
#define V_ipv6_list VNET(ipv6_list)
|
||||
|
||||
#define GIF_HASH(src, dst) (V_ipv6_hashtbl[\
|
||||
in6_gif_hashval((src), (dst)) & (GIF_HASH_SIZE - 1)])
|
||||
in6_gif_hashval((src), (dst)) & (V_ipv6_hashmask - 1)])
|
||||
#define GIF_SRCHASH(src) (V_ipv6_srchashtbl[\
|
||||
fnv_32_buf((src), sizeof(*src), FNV1_32_INIT) & (GIF_HASH_SIZE - 1)])
|
||||
fnv_32_buf((src), sizeof(*src), FNV1_32_INIT) & (V_ipv6_hashmask - 1)])
|
||||
#define GIF_HASH_SC(sc) GIF_HASH(&(sc)->gif_ip6hdr->ip6_src,\
|
||||
&(sc)->gif_ip6hdr->ip6_dst)
|
||||
static uint32_t
|
||||
@@ -237,8 +240,15 @@ in6_gif_ioctl(struct gif_softc *sc, u_long cmd, caddr_t data)
|
||||
break;
|
||||
|
||||
if (V_ipv6_hashtbl == NULL) {
|
||||
V_ipv6_hashtbl = gif_hashinit();
|
||||
V_ipv6_srchashtbl = gif_hashinit();
|
||||
struct hashalloc_args ha = {
|
||||
.size = GIF_HASH_SIZE,
|
||||
.mtype = M_GIF,
|
||||
.mflags = M_WAITOK,
|
||||
.head = HASH_HEAD_CK_LIST,
|
||||
};
|
||||
V_ipv6_hashtbl = hashalloc(&ha);
|
||||
V_ipv6_srchashtbl = hashalloc(&ha);
|
||||
V_ipv6_hashmask = ha.size - 1;
|
||||
}
|
||||
error = in6_gif_checkdup(sc, &src->sin6_addr,
|
||||
&dst->sin6_addr);
|
||||
@@ -469,9 +479,14 @@ in6_gif_uninit(void)
|
||||
ip6_encap_unregister_srcaddr(ipv6_srcaddrtab);
|
||||
}
|
||||
if (V_ipv6_hashtbl != NULL) {
|
||||
gif_hashdestroy(V_ipv6_hashtbl);
|
||||
struct hashalloc_args ha = {
|
||||
.size = V_ipv6_hashmask + 1,
|
||||
.mtype = M_GIF,
|
||||
.head = HASH_HEAD_CK_LIST,
|
||||
};
|
||||
hashfree(V_ipv6_hashtbl, &ha);
|
||||
V_ipv6_hashtbl = NULL;
|
||||
GIF_WAIT();
|
||||
gif_hashdestroy(V_ipv6_srchashtbl);
|
||||
hashfree(V_ipv6_srchashtbl, &ha);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user