diff options
author | wollman <wollman@FreeBSD.org> | 1997-06-18 01:24:28 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1997-06-18 01:24:28 +0000 |
commit | 58389eea9e84d5e0c70c01855b3fcaae96853393 (patch) | |
tree | 5763ebb0646b34795852d632f7a2471b8a17e885 /sys/netinet | |
parent | e5ccd3d79ccb6d06ad75151df380d357f911bfcb (diff) | |
download | FreeBSD-src-58389eea9e84d5e0c70c01855b3fcaae96853393.zip FreeBSD-src-58389eea9e84d5e0c70c01855b3fcaae96853393.tar.gz |
Add for public examination the beginnings of the per-host cache support
which will for the basis of RTF_PRCLONING's more efficient, better-
designed replacement.
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in_hostcache.c | 158 | ||||
-rw-r--r-- | sys/netinet/in_hostcache.h | 83 |
2 files changed, 241 insertions, 0 deletions
diff --git a/sys/netinet/in_hostcache.c b/sys/netinet/in_hostcache.c new file mode 100644 index 0000000..8b46959 --- /dev/null +++ b/sys/netinet/in_hostcache.c @@ -0,0 +1,158 @@ +/* + * Copyright 1997 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/socket.h> +#include <sys/socketvar.h> + +#include <net/hostcache.h> +#include <net/if.h> +#include <net/if_var.h> +#include <net/route.h> + +#include <netinet/in.h> +#include <netinet/in_hostcache.h> +#include <netinet/tcp.h> +#include <netinet/tcp_timer.h> +#include <netinet/tcp_var.h> + +/* + * Manage the IP per-host cache (really a thin veneer over the generic + * per-host cache code). + */ + +/* Look up an entry -- can be called from interrupt context. */ +struct in_hcentry * +inhc_lookup(struct sockaddr_in *sin) +{ + struct hcentry *hc; + + hc = hc_get((struct sockaddr *)sin); + return ((struct in_hcentry *)hc); +} + +/* Look up and possibly create an entry -- must be called from user mode. */ +struct in_hcentry * +inhc_alloc(struct sockaddr_in *sin) +{ + struct in_hcentry *inhc; + struct rtentry *rt; + int error; + /* xxx mutual exclusion for smp */ + + inhc = inhc_lookup(sin); + if (inhc != 0) + return inhc; + + rt = rtalloc1(inhc->inhc_hc.hc_host, 1, 0); + if (rt == 0) + return 0; + + MALLOC(inhc, struct in_hcentry *, sizeof *inhc, M_HOSTCACHE, M_WAITOK); + bzero(inhc, sizeof *inhc); + inhc->inhc_hc.hc_host = dup_sockaddr((struct sockaddr *)sin, 1); + if (in_broadcast(sin->sin_addr, rt->rt_ifp)) + inhc->inhc_flags |= INHC_BROADCAST; + else if (((struct sockaddr_in *)rt->rt_ifa->ifa_addr)->sin_addr.s_addr + == sin->sin_addr.s_addr) + inhc->inhc_flags |= INHC_LOCAL; + else if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) + inhc->inhc_flags |= INHC_MULTICAST; + inhc->inhc_pmtu = rt->rt_rmx.rmx_mtu; + inhc->inhc_recvpipe = rt->rt_rmx.rmx_recvpipe; + inhc->inhc_sendpipe = rt->rt_rmx.rmx_sendpipe; + inhc->inhc_ssthresh = rt->rt_rmx.rmx_ssthresh; + if (rt->rt_rmx.rmx_locks & RTV_RTT) + inhc->inhc_rttmin = rt->rt_rmx.rmx_rtt + / (RTM_RTTUNIT / TCP_RTT_SCALE); + inhc->inhc_hc.hc_rt = rt; + error = hc_insert(&inhc->inhc_hc); + if (error != 0) { + RTFREE(rt); + FREE(inhc, M_HOSTCACHE); + return 0; + } + /* + * We don't return the structure directly because hc_get() needs + * to be allowed to do its own processing. + */ + return (inhc_lookup(sin)); +} + +/* + * This is Van Jacobson's hash function for IPv4 addresses. + * It is designed to work with a power-of-two-sized hash table. + */ +static u_long +inhc_hash(struct sockaddr *sa, u_long nbuckets) +{ + u_long ip; + + ip = ((struct sockaddr_in *)sa)->sin_addr.s_addr; + return ((ip ^ (ip >> 23) ^ (ip >> 17)) & ~(nbuckets - 1)); +} + +/* + * We don't need to do any special work... if there are no references, + * as the caller has already ensured, then it's OK to kill. + */ +static int +inhc_delete(struct hcentry *hc) +{ + return 0; +} + +/* + * Return the next increment for the number of buckets in the hash table. + * Zero means ``do not bump''. + */ +static u_long +inhc_bump(u_long oldsize) +{ + if (oldsize < 512) + return (oldsize << 1); + return 0; +} + +static struct hccallback inhc_cb = { + inhc_hash, inhc_delete, inhc_bump +}; + +int +inhc_init(void) +{ + int error; + + return (hc_init(AF_INET, &inhc_cb, 128, 0)); +} + diff --git a/sys/netinet/in_hostcache.h b/sys/netinet/in_hostcache.h new file mode 100644 index 0000000..81ae4bd --- /dev/null +++ b/sys/netinet/in_hostcache.h @@ -0,0 +1,83 @@ +/* + * Copyright 1997 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _NETINET_IN_HOSTCACHE_H +#define _NETINET_IN_HOSTCACHE_H 1 + +/* + * This file defines the particular structures contained in the host cache + * for the use of IP. + */ + +/* + * An IP host cache entry. Note that we include the srtt/var here, + * with the expectation that it might be used to keep a persistent, + * cross-connection view of this statistic. + */ +struct in_hcentry { + struct hcentry inhc_hc; + u_long inhc_pmtu; + u_long inhc_recvpipe; + u_long inhc_sendpipe; + u_long inhc_pksent; + u_long inhc_flags; + u_long inhc_ssthresh; + int inhc_srtt; /* VJ RTT estimator */ + int inhc_srttvar; /* VJ */ + u_int inhc_rttmin; /* VJ */ + int inhc_rxt; /* TCP retransmit timeout */ + u_long inhc_cc; /* deliberate type pun with tcp_cc */ + u_long inhc_ccsent; /* as above */ + u_short inhc_mssopt; +}; + +#define inhc_addr(inhc) ((struct sockaddr_in *)(inhc)->inhc_hc.hc_host) + +/* Flags for inhc_flags... */ +#define INHC_LOCAL 0x0001 /* this address is local */ +#define INHC_BROADCAST 0x0002 /* this address is broadcast */ +#define INHC_MULTICAST 0x0004 /* this address is multicast */ +#define INHC_REDUCEDMTU 0x0008 /* we reduced the mtu via PMTU discovery */ + +#ifdef KERNEL +/* + * inhc_alloc can block while adding a new entry to the cache; + * inhc_lookup will does not add new entries and so can be called + * in non-process context. + */ +struct in_hcentry *inhc_alloc(struct sockaddr_in *sin); +int inhc_init(void); +struct in_hcentry *inhc_lookup(struct sockaddr_in *sin); +#define inhc_ref(inhc) (hc_ref(&(inhc)->inhc_hc)) +#define inhc_rele(inhc) (hc_rele(&(inhc)->inhc_hc)) +#endif /* KERNEL */ + +#endif /* _NETINET_IN_HOSTCACHE_H */ |