diff options
author | rrs <rrs@FreeBSD.org> | 2007-03-19 11:11:16 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-03-19 11:11:16 +0000 |
commit | 56faff0a7452b39fd328d13e20d96518124918ad (patch) | |
tree | a8df83dcc65a165ded6c77be172e14119f46ab38 /sys/netinet/sctp_pcb.c | |
parent | d9b60cf6fa9667eb83a9934de16d3be1db0033a4 (diff) | |
download | FreeBSD-src-56faff0a7452b39fd328d13e20d96518124918ad.zip FreeBSD-src-56faff0a7452b39fd328d13e20d96518124918ad.tar.gz |
Adds a hash table to speed local address lookup
on a per VRF basis (BSD has only one VRF currently).
Hash table is sized to 16 but may need to be adjusted
for machines with large numbers of addresses.
Reviewed by: gnn
Diffstat (limited to 'sys/netinet/sctp_pcb.c')
-rw-r--r-- | sys/netinet/sctp_pcb.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 820bd98..26e0d59 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -155,6 +155,16 @@ sctp_allocate_vrf(int vrfid) vrf->vrf_id = vrfid; LIST_INIT(&vrf->ifnlist); vrf->total_ifa_count = 0; + /* Init the HASH of addresses */ + vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_HASH_SIZE, + &vrf->vrf_hashmark); + if (vrf->vrf_addr_hash == NULL) { + /* No memory */ +#ifdef INVARIANTS + panic("No memory for VRF:%d", vrfid); +#endif + return (NULL); + } /* Add it to the hash table */ bucket = &sctppcbinfo.sctp_vrfhash[(vrfid & sctppcbinfo.hashvrfmark)]; LIST_INSERT_HEAD(bucket, vrf, next_vrf); @@ -217,6 +227,8 @@ sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index, struct sctp_vrf *vrf; struct sctp_ifn *sctp_ifnp = NULL; struct sctp_ifa *sctp_ifap = NULL; + struct sctp_ifalist *hash_head; + uint32_t hash_of_addr; /* How granular do we need the locks to be here? */ SCTP_IPI_ADDR_LOCK(); @@ -325,11 +337,15 @@ sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index, sctp_ifap->src_is_priv = 1; } } + hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa); + if ((sctp_ifap->src_is_priv == 0) && (sctp_ifap->src_is_loop == 0)) { sctp_ifap->src_is_glob = 1; } SCTP_IPI_ADDR_LOCK(); + hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_hashmark)]; + LIST_INSERT_HEAD(hash_head, sctp_ifap, next_bucket); sctp_ifap->refcount = 1; LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); sctp_ifnp->ifa_count++; @@ -365,6 +381,7 @@ sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr, sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; sctp_ifnp->ifa_count--; vrf->total_ifa_count--; + LIST_REMOVE(sctp_ifap, next_bucket); LIST_REMOVE(sctp_ifap, next_ifa); atomic_add_int(&sctp_ifnp->refcount, -1); } else { |