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)