Module Name:    src
Committed By:   knakahara
Date:           Thu Apr 13 00:12:10 UTC 2017

Modified Files:
        src/sys/net: if_l2tp.c

Log Message:
l2tp(4) support when hashinit() cannot allocate requried hash size.

pointed out by s-yamaguchi@IIJ


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/net/if_l2tp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if_l2tp.c
diff -u src/sys/net/if_l2tp.c:1.8 src/sys/net/if_l2tp.c:1.9
--- src/sys/net/if_l2tp.c:1.8	Tue Apr  4 23:49:17 2017
+++ src/sys/net/if_l2tp.c	Thu Apr 13 00:12:10 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_l2tp.c,v 1.8 2017/04/04 23:49:17 knakahara Exp $	*/
+/*	$NetBSD: if_l2tp.c,v 1.9 2017/04/13 00:12:10 knakahara Exp $	*/
 
 /*
  * Copyright (c) 2017 Internet Initiative Japan Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.8 2017/04/04 23:49:17 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.9 2017/04/13 00:12:10 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -110,6 +110,7 @@ static struct {
 static struct {
 	kmutex_t lock;
 	struct pslist_head *lists;
+	u_long mask;
 } l2tp_hash __cacheline_aligned = {
 	.lists = NULL,
 };
@@ -140,7 +141,7 @@ static int	l2tp_set_tunnel(struct ifnet 
 		    struct sockaddr *);
 static void	l2tp_delete_tunnel(struct ifnet *);
 
-static int	id_hash_func(uint32_t);
+static int	id_hash_func(uint32_t, u_long);
 
 static void	l2tp_variant_update(struct l2tp_softc *, struct l2tp_variant *);
 static int	l2tp_set_session(struct l2tp_softc *, uint32_t, uint32_t);
@@ -1002,24 +1003,22 @@ l2tp_delete_tunnel(struct ifnet *ifp)
 }
 
 static int
-id_hash_func(uint32_t id)
+id_hash_func(uint32_t id, u_long mask)
 {
 	uint32_t hash;
 
 	hash = (id >> 16) ^ id;
 	hash = (hash >> 4) ^ hash;
 
-	return hash & (L2TP_ID_HASH_SIZE - 1);
+	return hash & mask;
 }
 
 static void
 l2tp_hash_init(void)
 {
-	u_long mask;
 
 	l2tp_hash.lists = hashinit(L2TP_ID_HASH_SIZE, HASH_PSLIST, true,
-	    &mask);
-	KASSERT(mask == (L2TP_ID_HASH_SIZE - 1));
+	    &l2tp_hash.mask);
 }
 
 static int
@@ -1029,19 +1028,19 @@ l2tp_hash_fini(void)
 
 	mutex_enter(&l2tp_hash.lock);
 
-	for (i = 0; i < L2TP_ID_HASH_SIZE; i++) {
+	for (i = 0; i < l2tp_hash.mask + 1; i++) {
 		if (PSLIST_WRITER_FIRST(&l2tp_hash.lists[i], struct l2tp_softc,
 			l2tp_hash) != NULL) {
 			mutex_exit(&l2tp_hash.lock);
 			return EBUSY;
 		}
 	}
-	for (i = 0; i < L2TP_ID_HASH_SIZE; i++)
+	for (i = 0; i < l2tp_hash.mask + 1; i++)
 		PSLIST_DESTROY(&l2tp_hash.lists[i]);
 
 	mutex_exit(&l2tp_hash.lock);
 
-	hashdone(l2tp_hash.lists, HASH_PSLIST, L2TP_ID_HASH_SIZE - 1);
+	hashdone(l2tp_hash.lists, HASH_PSLIST, l2tp_hash.mask);
 
 	return 0;
 }
@@ -1075,7 +1074,7 @@ l2tp_set_session(struct l2tp_softc *sc, 
 	l2tp_variant_update(sc, nvar);
 	mutex_exit(&sc->l2tp_lock);
 
-	idx = id_hash_func(nvar->lv_my_sess_id);
+	idx = id_hash_func(nvar->lv_my_sess_id, l2tp_hash.mask);
 	if ((ifp->if_flags & IFF_DEBUG) != 0)
 		log(LOG_DEBUG, "%s: add hash entry: sess_id=%" PRIu32 ", idx=%" PRIu32 "\n",
 		    sc->l2tp_ec.ec_if.if_xname, nvar->lv_my_sess_id, idx);
@@ -1124,7 +1123,7 @@ l2tp_lookup_session_ref(uint32_t id, str
 	int s;
 	struct l2tp_softc *sc;
 
-	idx = id_hash_func(id);
+	idx = id_hash_func(id, l2tp_hash.mask);
 
 	s = pserialize_read_enter();
 	PSLIST_READER_FOREACH(sc, &l2tp_hash.lists[idx], struct l2tp_softc,

Reply via email to