Module Name:    src
Committed By:   knakahara
Date:           Mon Jul  4 04:26:00 UTC 2016

Modified Files:
        src/sys/netinet: ip_encap.c

Log Message:
restore ifdef USE_RADIX (revert ip_encap.c:r1.44)

To help future ip_encap optimaization works.


To generate a diff of this commit:
cvs rdiff -u -r1.54 -r1.55 src/sys/netinet/ip_encap.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/netinet/ip_encap.c
diff -u src/sys/netinet/ip_encap.c:1.54 src/sys/netinet/ip_encap.c:1.55
--- src/sys/netinet/ip_encap.c:1.54	Mon Jul  4 04:17:25 2016
+++ src/sys/netinet/ip_encap.c	Mon Jul  4 04:26:00 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_encap.c,v 1.54 2016/07/04 04:17:25 knakahara Exp $	*/
+/*	$NetBSD: ip_encap.c,v 1.55 2016/07/04 04:26:00 knakahara Exp $	*/
 /*	$KAME: ip_encap.c,v 1.73 2001/10/02 08:30:58 itojun Exp $	*/
 
 /*
@@ -58,16 +58,17 @@
 /* XXX is M_NETADDR correct? */
 
 /*
- * The code will use radix table for tunnel lookup, for
+ * With USE_RADIX the code will use radix table for tunnel lookup, for
  * tunnels registered with encap_attach() with a addr/mask pair.
  * Faster on machines with thousands of tunnel registerations (= interfaces).
  *
  * The code assumes that radix table code can handle non-continuous netmask,
  * as it will pass radix table memory region with (src + dst) sockaddr pair.
  */
+#define USE_RADIX
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.54 2016/07/04 04:17:25 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.55 2016/07/04 04:26:00 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mrouting.h"
@@ -118,13 +119,20 @@ static struct encaptab *encap6_lookup(st
 static int encap_add(struct encaptab *);
 static int encap_remove(struct encaptab *);
 static int encap_afcheck(int, const struct sockaddr *, const struct sockaddr *);
+#ifdef USE_RADIX
 static struct radix_node_head *encap_rnh(int);
 static int mask_matchlen(const struct sockaddr *);
+#else
+static int mask_match(const struct encaptab *, const struct sockaddr *,
+		const struct sockaddr *);
+#endif
 static void encap_fillarg(struct mbuf *, const struct encaptab *);
 
 LIST_HEAD(, encaptab) encaptab = LIST_HEAD_INITIALIZER(&encaptab);
 
+#ifdef USE_RADIX
 struct radix_node_head *encap_head[2];	/* 0 for AF_INET, 1 for AF_INET6 */
+#endif
 
 static ONCE_DECL(encap_init_control);
 
@@ -151,6 +159,7 @@ encap_init(void)
 	LIST_INIT(&encaptab);
 #endif
 
+#ifdef USE_RADIX
 	/*
 	 * initialize radix lookup table when the radix subsystem is inited.
 	 */
@@ -160,6 +169,7 @@ encap_init(void)
 	rn_delayedinit((void *)&encap_head[1],
 	    sizeof(struct sockaddr_pack) << 3);
 #endif
+#endif
 }
 
 #ifdef INET
@@ -170,8 +180,10 @@ encap4_lookup(struct mbuf *m, int off, i
 	struct ip_pack4 pack;
 	struct encaptab *ep, *match;
 	int prio, matchprio;
+#ifdef USE_RADIX
 	struct radix_node_head *rnh = encap_rnh(AF_INET);
 	struct radix_node *rn;
+#endif
 
 	KASSERT(m->m_len >= sizeof(*ip));
 	KASSERT(rw_read_held(&encap_whole_lock));
@@ -193,12 +205,14 @@ encap4_lookup(struct mbuf *m, int off, i
 	match = NULL;
 	matchprio = 0;
 
+#ifdef USE_RADIX
 	rn = rnh->rnh_matchaddr((void *)&pack, rnh);
 	if (rn && (rn->rn_flags & RNF_ROOT) == 0) {
 		match = (struct encaptab *)rn;
 		matchprio = mask_matchlen(match->srcmask) +
 		    mask_matchlen(match->dstmask);
 	}
+#endif
 
 	LIST_FOREACH(ep, &encaptab, chain) {
 		if (ep->af != AF_INET)
@@ -207,8 +221,14 @@ encap4_lookup(struct mbuf *m, int off, i
 			continue;
 		if (ep->func)
 			prio = (*ep->func)(m, off, proto, ep->arg);
-		else
+		else {
+#ifdef USE_RADIX
 			continue;
+#else
+			prio = mask_match(ep, (struct sockaddr *)&pack.mine,
+			    (struct sockaddr *)&pack.yours);
+#endif
+		}
 
 		/*
 		 * We prioritize the matches by using bit length of the
@@ -286,8 +306,10 @@ encap6_lookup(struct mbuf *m, int off, i
 	struct ip_pack6 pack;
 	int prio, matchprio;
 	struct encaptab *ep, *match;
+#ifdef USE_RADIX
 	struct radix_node_head *rnh = encap_rnh(AF_INET6);
 	struct radix_node *rn;
+#endif
 
 	KASSERT(m->m_len >= sizeof(*ip6));
 	KASSERT(rw_read_held(&encap_whole_lock));
@@ -309,12 +331,14 @@ encap6_lookup(struct mbuf *m, int off, i
 	match = NULL;
 	matchprio = 0;
 
+#ifdef USE_RADIX
 	rn = rnh->rnh_matchaddr((void *)&pack, rnh);
 	if (rn && (rn->rn_flags & RNF_ROOT) == 0) {
 		match = (struct encaptab *)rn;
 		matchprio = mask_matchlen(match->srcmask) +
 		    mask_matchlen(match->dstmask);
 	}
+#endif
 
 	LIST_FOREACH(ep, &encaptab, chain) {
 		if (ep->af != AF_INET6)
@@ -323,8 +347,14 @@ encap6_lookup(struct mbuf *m, int off, i
 			continue;
 		if (ep->func)
 			prio = (*ep->func)(m, off, proto, ep->arg);
-		else
+		else {
+#ifdef USE_RADIX
 			continue;
+#else
+			prio = mask_match(ep, (struct sockaddr *)&pack.mine,
+			    (struct sockaddr *)&pack.yours);
+#endif
+		}
 
 		/* see encap4_lookup() for issues here */
 		if (prio <= 0)
@@ -375,12 +405,15 @@ encap6_input(struct mbuf **mp, int *offp
 static int
 encap_add(struct encaptab *ep)
 {
+#ifdef USE_RADIX
 	struct radix_node_head *rnh = encap_rnh(ep->af);
+#endif
 	int error = 0;
 
 	KASSERT(rw_write_held(&encap_whole_lock));
 
 	LIST_INSERT_HEAD(&encaptab, ep, chain);
+#ifdef USE_RADIX
 	if (!ep->func && rnh) {
 		if (!rnh->rnh_addaddr((void *)ep->addrpack,
 		    (void *)ep->maskpack, rnh, ep->nodes)) {
@@ -388,11 +421,14 @@ encap_add(struct encaptab *ep)
 			goto fail;
 		}
 	}
+#endif
 	return error;
 
+#ifdef USE_RADIX
  fail:
 	LIST_REMOVE(ep, chain);
 	return error;
+#endif
 }
 
 /*
@@ -402,17 +438,21 @@ encap_add(struct encaptab *ep)
 static int
 encap_remove(struct encaptab *ep)
 {
+#ifdef USE_RADIX
 	struct radix_node_head *rnh = encap_rnh(ep->af);
+#endif
 	int error = 0;
 
 	KASSERT(rw_write_held(&encap_whole_lock));
 
 	LIST_REMOVE(ep, chain);
+#ifdef USE_RADIX
 	if (!ep->func && rnh) {
 		if (!rnh->rnh_deladdr((void *)ep->addrpack,
 		    (void *)ep->maskpack, rnh))
 			error = ESRCH;
 	}
+#endif
 	return error;
 }
 
@@ -764,6 +804,7 @@ encap_detach(const struct encaptab *cook
 	return ENOENT;
 }
 
+#ifdef USE_RADIX
 static struct radix_node_head *
 encap_rnh(int af)
 {
@@ -797,6 +838,63 @@ mask_matchlen(const struct sockaddr *sa)
 	}
 	return l;
 }
+#endif
+
+#ifndef USE_RADIX
+static int
+mask_match(const struct encaptab *ep,
+	   const struct sockaddr *sp,
+	   const struct sockaddr *dp)
+{
+	struct sockaddr_storage s;
+	struct sockaddr_storage d;
+	int i;
+	const u_int8_t *p, *q;
+	u_int8_t *r;
+	int matchlen;
+
+	KASSERTMSG(ep->func == NULL, "wrong encaptab passed to mask_match");
+
+	if (sp->sa_len > sizeof(s) || dp->sa_len > sizeof(d))
+		return 0;
+	if (sp->sa_family != ep->af || dp->sa_family != ep->af)
+		return 0;
+	if (sp->sa_len != ep->src->sa_len || dp->sa_len != ep->dst->sa_len)
+		return 0;
+
+	matchlen = 0;
+
+	p = (const u_int8_t *)sp;
+	q = (const u_int8_t *)ep->srcmask;
+	r = (u_int8_t *)&s;
+	for (i = 0 ; i < sp->sa_len; i++) {
+		r[i] = p[i] & q[i];
+		/* XXX estimate */
+		matchlen += (q[i] ? 8 : 0);
+	}
+
+	p = (const u_int8_t *)dp;
+	q = (const u_int8_t *)ep->dstmask;
+	r = (u_int8_t *)&d;
+	for (i = 0 ; i < dp->sa_len; i++) {
+		r[i] = p[i] & q[i];
+		/* XXX rough estimate */
+		matchlen += (q[i] ? 8 : 0);
+	}
+
+	/* need to overwrite len/family portion as we don't compare them */
+	s.ss_len = sp->sa_len;
+	s.ss_family = sp->sa_family;
+	d.ss_len = dp->sa_len;
+	d.ss_family = dp->sa_family;
+
+	if (memcmp(&s, ep->src, ep->src->sa_len) == 0 &&
+	    memcmp(&d, ep->dst, ep->dst->sa_len) == 0) {
+		return matchlen;
+	} else
+		return 0;
+}
+#endif
 
 static void
 encap_fillarg(struct mbuf *m, const struct encaptab *ep)

Reply via email to