- fix initial pcb vrf setting when the initial vrf is not the

default_vrf_id
- Missing lock/unlock of inp added as well in the v6 side.
- IFN hash table moves to sctppcbinfo since indexes are
  unique across systems (including different VRFs) this makes it easier
  to do ifn lookups.
This commit is contained in:
Randall Stewart 2007-06-02 11:05:08 +00:00
parent e20b748d5f
commit f4c93d2405
7 changed files with 36 additions and 40 deletions

View File

@ -489,7 +489,6 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
* Now lets see if we can deliver the next one on
* the stream
*/
uint16_t nxt_todel;
struct sctp_stream_in *strm;
strm = &asoc->strmin[stream_no];

View File

@ -164,10 +164,9 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
#define SCTP_SIZE_OF_VRF_HASH 3
#define SCTP_IFNAMSIZ IFNAMSIZ
#define SCTP_DEFAULT_VRFID 0
#define SCTP_DEFAULT_TABLEID 0
#define SCTP_VRF_ADDR_HASH_SIZE 16
#define SCTP_VRF_IFN_HASH_SIZE 3
#define SCTP_VRF_DEFAULT_TABLEID(vrf_id) 0
#define SCTP_INIT_VRF_TABLEID(vrf)
#define SCTP_IFN_IS_IFT_LOOP(ifn) ((ifn)->ifn_type == IFT_LOOP)

View File

@ -2370,7 +2370,7 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index);
sctp_ifn = sctp_find_ifn(ifn, ifn_index);
/*
* first question, is the ifn we will emit on in our list, if so, we
* want such an address. Note that we first looked for a preferred
@ -2478,7 +2478,7 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index);
sctp_ifn = sctp_find_ifn(ifn, ifn_index);
/*
* first question, is the ifn we will emit on in our list? If so,
@ -2705,7 +2705,7 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
emit_ifn = looked_at = sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index);
emit_ifn = looked_at = sctp_ifn = sctp_find_ifn(ifn, ifn_index);
if (sctp_ifn == NULL) {
/* ?? We don't have this guy ?? */
goto bound_all_plan_b;
@ -10572,7 +10572,7 @@ sctp_lower_sosend(struct socket *so,
struct thread *p
)
{
unsigned int sndlen, max_len;
unsigned int sndlen = 0, max_len;
int error, len;
struct mbuf *top = NULL;
@ -11747,6 +11747,7 @@ sctp_lower_sosend(struct socket *so,
out:
out_unlocked:
if (create_lock_applied) {
SCTP_ASOC_CREATE_UNLOCK(inp);
create_lock_applied = 0;

View File

@ -155,6 +155,8 @@ sctp_allocate_vrf(int vrf_id)
vrf->vrf_id = vrf_id;
LIST_INIT(&vrf->ifnlist);
vrf->total_ifa_count = 0;
/* now also setup table ids */
SCTP_INIT_VRF_TABLEID(vrf);
/* Init the HASH of addresses */
vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_ADDR_HASH_SIZE,
&vrf->vrf_addr_hashmark);
@ -166,17 +168,6 @@ sctp_allocate_vrf(int vrf_id)
SCTP_FREE(vrf, SCTP_M_VRF);
return (NULL);
}
vrf->vrf_ifn_hash = SCTP_HASH_INIT(SCTP_VRF_IFN_HASH_SIZE,
&vrf->vrf_ifn_hashmark);
if (vrf->vrf_ifn_hash == NULL) {
/* No memory */
#ifdef INVARIANTS
panic("No memory for VRF:%d", vrf_id);
#endif
SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
SCTP_FREE(vrf, SCTP_M_VRF);
return (NULL);
}
/* Add it to the hash table */
bucket = &sctppcbinfo.sctp_vrfhash[(vrf_id & sctppcbinfo.hashvrfmark)];
LIST_INSERT_HEAD(bucket, vrf, next_vrf);
@ -186,7 +177,7 @@ sctp_allocate_vrf(int vrf_id)
struct sctp_ifn *
sctp_find_ifn(struct sctp_vrf *vrf, void *ifn, uint32_t ifn_index)
sctp_find_ifn(void *ifn, uint32_t ifn_index)
{
struct sctp_ifn *sctp_ifnp;
struct sctp_ifnlist *hash_ifn_head;
@ -195,7 +186,7 @@ sctp_find_ifn(struct sctp_vrf *vrf, void *ifn, uint32_t ifn_index)
* We assume the lock is held for the addresses if thats wrong
* problems could occur :-)
*/
hash_ifn_head = &vrf->vrf_ifn_hash[(ifn_index & vrf->vrf_ifn_hashmark)];
hash_ifn_head = &sctppcbinfo.vrf_ifn_hash[(ifn_index & sctppcbinfo.vrf_ifn_hashmark)];
LIST_FOREACH(sctp_ifnp, hash_ifn_head, next_bucket) {
if (sctp_ifnp->ifn_index == ifn_index) {
return (sctp_ifnp);
@ -239,15 +230,11 @@ sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
}
void
sctp_update_ifn_mtu(uint32_t vrf_id, uint32_t ifn_index, uint32_t mtu)
sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu)
{
struct sctp_ifn *sctp_ifnp;
struct sctp_vrf *vrf;
vrf = sctp_find_vrf(vrf_id);
if (vrf == NULL)
return;
sctp_ifnp = sctp_find_ifn(vrf, (void *)NULL, ifn_index);
sctp_ifnp = sctp_find_ifn((void *)NULL, ifn_index);
if (sctp_ifnp != NULL) {
sctp_ifnp->ifn_mtu = mtu;
}
@ -272,7 +259,7 @@ sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
{
struct sctp_ifn *found;
found = sctp_find_ifn(sctp_ifnp->vrf, sctp_ifnp->ifn_p, sctp_ifnp->ifn_index);
found = sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index);
if (found == NULL) {
/* Not in the list.. sorry */
return;
@ -314,7 +301,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
return (NULL);
}
}
sctp_ifnp = sctp_find_ifn(vrf, ifn, ifn_index);
sctp_ifnp = sctp_find_ifn(ifn, ifn_index);
if (sctp_ifnp == NULL) {
/*
* build one and add it, can't hold lock until after malloc
@ -340,7 +327,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
} else {
memcpy(sctp_ifnp->ifn_name, "unknown", min(7, SCTP_IFNAMSIZ));
}
hash_ifn_head = &vrf->vrf_ifn_hash[(ifn_index & vrf->vrf_ifn_hashmark)];
hash_ifn_head = &sctppcbinfo.vrf_ifn_hash[(ifn_index & sctppcbinfo.vrf_ifn_hashmark)];
LIST_INIT(&sctp_ifnp->ifalist);
SCTP_IPI_ADDR_LOCK();
LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket);
@ -1741,7 +1728,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
* port with all addresses bound.
*/
int
sctp_inpcb_alloc(struct socket *so)
sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
{
/*
* we get called when a new endpoint starts up. We need to allocate
@ -1828,7 +1815,7 @@ sctp_inpcb_alloc(struct socket *so)
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
return (ENOBUFS);
}
inp->def_vrf_id = SCTP_DEFAULT_VRFID;
inp->def_vrf_id = vrf_id;
SCTP_INP_INFO_WLOCK();
SCTP_INP_LOCK_INIT(inp);
@ -4588,6 +4575,9 @@ sctp_pcb_init()
sctppcbinfo.sctp_vrfhash = SCTP_HASH_INIT(SCTP_SIZE_OF_VRF_HASH,
&sctppcbinfo.hashvrfmark);
sctppcbinfo.vrf_ifn_hash = SCTP_HASH_INIT(SCTP_VRF_IFN_HASH_SIZE,
&sctppcbinfo.vrf_ifn_hashmark);
/* init the zones */
/*
* FIX ME: Should check for NULL returns, but if it does fail we are

View File

@ -59,12 +59,12 @@ TAILQ_HEAD(sctp_streamhead, sctp_stream_queue_pending);
struct sctp_vrf {
LIST_ENTRY(sctp_vrf) next_vrf;
struct sctp_ifalist *vrf_addr_hash;
struct sctp_ifnlist *vrf_ifn_hash;
struct sctp_ifnlist ifnlist;
uint32_t vrf_id;
uint32_t tbl_id_v4; /* default v4 table id */
uint32_t tbl_id_v6; /* default v6 table id */
uint32_t total_ifa_count;
u_long vrf_addr_hashmark;
u_long vrf_ifn_hashmark;
};
struct sctp_ifn {
@ -166,6 +166,9 @@ struct sctp_epinfo {
struct sctp_vrflist *sctp_vrfhash;
u_long hashvrfmark;
struct sctp_ifnlist *vrf_ifn_hash;
u_long vrf_ifn_hashmark;
struct sctppcbhead listhead;
struct sctpladdr addr_wq;
@ -416,7 +419,7 @@ int SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b);
void sctp_fill_pcbinfo(struct sctp_pcbinfo *);
struct sctp_ifn *
sctp_find_ifn(struct sctp_vrf *vrf, void *ifn, uint32_t ifn_index);
sctp_find_ifn(void *ifn, uint32_t ifn_index);
struct sctp_vrf *sctp_allocate_vrf(int vrfid);
@ -426,9 +429,10 @@ struct sctp_ifa *
sctp_add_addr_to_vrf(uint32_t vrfid,
void *ifn, uint32_t ifn_index, uint32_t ifn_type,
const char *if_name,
void *ifa, struct sockaddr *addr, uint32_t ifa_flags, int dynamic_add);
void *ifa, struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add);
void sctp_update_ifn_mtu(uint32_t vrf_id, uint32_t ifn_index, uint32_t mtu);
void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu);
void sctp_free_ifn(struct sctp_ifn *sctp_ifnp);
void sctp_free_ifa(struct sctp_ifa *sctp_ifap);
@ -479,7 +483,7 @@ struct sctp_tcb *
sctp_findassociation_ep_asconf(struct mbuf *, int, int,
struct sctphdr *, struct sctp_inpcb **, struct sctp_nets **);
int sctp_inpcb_alloc(struct socket *);
int sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id);
int sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id);

View File

@ -383,7 +383,6 @@ sctp_getcred(SYSCTL_HANDLER_ARGS)
int error;
uint32_t vrf_id;
/* FIX, for non-bsd is this right? */
vrf_id = SCTP_DEFAULT_VRFID;
@ -487,6 +486,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
struct sctp_inpcb *inp;
struct inpcb *ip_inp;
int error;
uint32_t vrf_id = SCTP_DEFAULT_VRFID;
#ifdef IPSEC
uint32_t flags;
@ -500,7 +500,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
if (error) {
return error;
}
error = sctp_inpcb_alloc(so);
error = sctp_inpcb_alloc(so, vrf_id);
if (error) {
return error;
}

View File

@ -543,6 +543,7 @@ sctp6_attach(struct socket *so, int proto, struct thread *p)
struct in6pcb *inp6;
int error;
struct sctp_inpcb *inp;
uint32_t vrf_id = SCTP_DEFAULT_VRFID;
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp != NULL)
@ -553,10 +554,11 @@ sctp6_attach(struct socket *so, int proto, struct thread *p)
if (error)
return error;
}
error = sctp_inpcb_alloc(so);
error = sctp_inpcb_alloc(so, vrf_id);
if (error)
return error;
inp = (struct sctp_inpcb *)so->so_pcb;
SCTP_INP_WLOCK(inp);
inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_V6; /* I'm v6! */
inp6 = (struct in6pcb *)inp;
@ -575,6 +577,7 @@ sctp6_attach(struct socket *so, int proto, struct thread *p)
* Hmm what about the IPSEC stuff that is missing here but in
* sctp_attach()?
*/
SCTP_INP_WUNLOCK(inp);
return 0;
}