Get SCTP working in combination with VIMAGE.

Contains code from bz.
Approved by: rrs (mentor)
MFC after: 1 month.
This commit is contained in:
Michael Tuexen 2009-09-19 14:02:16 +00:00
parent d2f7d5c975
commit 8518270e20
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=197326
8 changed files with 93 additions and 46 deletions

View File

@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filio.h>
#include <sys/jail.h>
#include <sys/mount.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
@ -2316,6 +2317,7 @@ sctp_peeloff(td, uap)
goto done;
td->td_retval[0] = fd;
CURVNET_SET(head->so_vnet);
so = sonewconn(head, SS_ISCONNECTED);
if (so == NULL)
goto noconnection;
@ -2355,6 +2357,7 @@ sctp_peeloff(td, uap)
/*
* Release explicitly held references before returning.
*/
CURVNET_RESTORE();
done:
if (nfp != NULL)
fdrop(nfp, td);
@ -2433,9 +2436,11 @@ sctp_generic_sendmsg (td, uap)
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
len = auio.uio_resid = uap->mlen;
CURVNET_SET(so->so_vnet);
error = sctp_lower_sosend(so, to, &auio,
(struct mbuf *)NULL, (struct mbuf *)NULL,
uap->flags, use_rcvinfo, u_sinfo, td);
CURVNET_RESTORE();
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@ -2543,9 +2548,11 @@ sctp_generic_sendmsg_iov(td, uap)
}
}
len = auio.uio_resid;
CURVNET_SET(so->so_vnet);
error = sctp_lower_sosend(so, to, &auio,
(struct mbuf *)NULL, (struct mbuf *)NULL,
uap->flags, use_rcvinfo, u_sinfo, td);
CURVNET_RESTORE();
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@ -2665,9 +2672,11 @@ sctp_generic_recvmsg(td, uap)
if (KTRPOINT(td, KTR_GENIO))
ktruio = cloneuio(&auio);
#endif /* KTRACE */
CURVNET_SET(so->so_vnet);
error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
fromsa, fromlen, &msg_flags,
(struct sctp_sndrcvinfo *)&sinfo, 1);
CURVNET_RESTORE();
if (error) {
if (auio.uio_resid != (int)len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))

View File

@ -150,39 +150,42 @@ struct protosw inetsw[] = {
},
#ifdef SCTP
{
.pr_type = SOCK_DGRAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_init = sctp_init,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
.pr_type = SOCK_DGRAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_init = sctp_init,
#ifdef VIMAGE
.pr_destroy = sctp_finish,
#endif
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
},
{
.pr_type = SOCK_SEQPACKET,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
.pr_type = SOCK_SEQPACKET,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
},
{
.pr_type = SOCK_STREAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
.pr_type = SOCK_STREAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
.pr_flags = PR_WANTRCVD,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
.pr_drain = sctp_drain,
.pr_usrreqs = &sctp_usrreqs
},
#endif /* SCTP */
{

View File

@ -89,6 +89,7 @@ sctp_wakeup_iterator(void)
static void
sctp_iterator_thread(void *v)
{
CURVNET_SET((struct vnet *)v);
SCTP_IPI_ITERATOR_WQ_LOCK();
SCTP_BASE_INFO(iterator_running) = 0;
while (1) {
@ -100,6 +101,7 @@ sctp_iterator_thread(void *v)
}
sctp_iterator_worker();
}
CURVNET_RESTORE();
}
void
@ -108,7 +110,7 @@ sctp_startup_iterator(void)
int ret;
ret = kproc_create(sctp_iterator_thread,
(void *)NULL,
(void *)curvnet,
&SCTP_BASE_INFO(thread_proc),
RFPROC,
SCTP_KTHREAD_PAGES,
@ -206,6 +208,9 @@ sctp_init_ifns_for_vrf(int vrfid)
struct sctp_ifa *sctp_ifa;
uint32_t ifa_flags;
#if 0
IFNET_RLOCK();
#endif
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
IF_ADDR_LOCK(ifn);
TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
@ -251,6 +256,9 @@ sctp_init_ifns_for_vrf(int vrfid)
}
IF_ADDR_UNLOCK(ifn);
}
#if 0
IFNET_RUNLOCK();
#endif
}
void
@ -336,6 +344,9 @@ void
struct ifnet *ifn;
struct ifaddr *ifa;
#if 0
IFNET_RLOCK();
#endif
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
if (!(*pred) (ifn)) {
continue;
@ -344,6 +355,9 @@ void
sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
}
}
#if 0
IFNET_RUNLOCK();
#endif
}
struct mbuf *

View File

@ -141,13 +141,14 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
* depending on whether VIMAGE is defined.
*/
/* then define the macro(s) that hook into the vimage macros */
#define MODULE_GLOBAL(__SYMBOL) V_ ## __SYMBOL
#define MODULE_GLOBAL(__SYMBOL) V_##__SYMBOL
#define V_system_base_info VNET_NAME(system_base_info)
#define V_system_base_info VNET(system_base_info)
#define SCTP_BASE_INFO(__m) V_system_base_info.sctppcbinfo.__m
#define SCTP_BASE_STATS V_system_base_info.sctpstat
#define SCTP_BASE_STATS_SYSCTL VNET_NAME(system_base_info.sctpstat)
#define SCTP_BASE_STAT(__m) V_system_base_info.sctpstat.__m
#define SCTP_BASE_SYSCTL(__m) V_system_base_info.sctpsysctl.__m
#define SCTP_BASE_SYSCTL(__m) VNET_NAME(system_base_info.sctpsysctl.__m)
#define SCTP_BASE_VAR(__m) V_system_base_info.__m
/*

View File

@ -6588,22 +6588,31 @@ sctp_drain()
* is LOW on MBUF's and needs help. This is where reneging will
* occur. We really hope this does NOT happen!
*/
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
SCTP_INP_INFO_RLOCK();
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
/* For each endpoint */
SCTP_INP_RLOCK(inp);
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
/* For each association */
SCTP_TCB_LOCK(stcb);
sctp_drain_mbufs(inp, stcb);
SCTP_TCB_UNLOCK(stcb);
VNET_ITERATOR_DECL(vnet_iter);
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
SCTP_INP_INFO_RLOCK();
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
/* For each endpoint */
SCTP_INP_RLOCK(inp);
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
/* For each association */
SCTP_TCB_LOCK(stcb);
sctp_drain_mbufs(inp, stcb);
SCTP_TCB_UNLOCK(stcb);
}
SCTP_INP_RUNLOCK(inp);
}
SCTP_INP_RUNLOCK(inp);
SCTP_INP_INFO_RUNLOCK();
CURVNET_RESTORE();
}
SCTP_INP_INFO_RUNLOCK();
VNET_LIST_RUNLOCK_NOSLEEP();
}
/*

View File

@ -51,6 +51,7 @@ struct sctp_timer {
void *ep;
void *tcb;
void *net;
void *vnet;
/* for sanity checking */
void *self;

View File

@ -930,7 +930,7 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, output_unlocked, CTLTYPE_INT | CTLFLAG_RW,
#endif
SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
&SCTP_BASE_STATS, sctpstat,
&SCTP_BASE_STATS_SYSCTL, sctpstat,
"SCTP statistics (struct sctp_stat)");
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,

View File

@ -1446,6 +1446,7 @@ sctp_timeout_handler(void *t)
inp = (struct sctp_inpcb *)tmr->ep;
stcb = (struct sctp_tcb *)tmr->tcb;
net = (struct sctp_nets *)tmr->net;
CURVNET_SET((struct vnet *)tmr->vnet);
did_output = 1;
#ifdef SCTP_AUDITING_ENABLED
@ -1459,6 +1460,7 @@ sctp_timeout_handler(void *t)
* SCTP_PRINTF("Stale SCTP timer fired (%p), ignoring...\n",
* tmr);
*/
CURVNET_RESTORE();
return;
}
tmr->stopped_from = 0xa001;
@ -1467,10 +1469,12 @@ sctp_timeout_handler(void *t)
* SCTP_PRINTF("SCTP timer fired with invalid type: 0x%x\n",
* tmr->type);
*/
CURVNET_RESTORE();
return;
}
tmr->stopped_from = 0xa002;
if ((tmr->type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) {
CURVNET_RESTORE();
return;
}
/* if this is an iterator timeout, get the struct and clear inp */
@ -1494,6 +1498,7 @@ sctp_timeout_handler(void *t)
(tmr->type != SCTP_TIMER_TYPE_ASOCKILL))
) {
SCTP_INP_DECR_REF(inp);
CURVNET_RESTORE();
return;
}
}
@ -1505,6 +1510,7 @@ sctp_timeout_handler(void *t)
if (inp) {
SCTP_INP_DECR_REF(inp);
}
CURVNET_RESTORE();
return;
}
}
@ -1517,6 +1523,7 @@ sctp_timeout_handler(void *t)
if (stcb) {
atomic_add_int(&stcb->asoc.refcnt, -1);
}
CURVNET_RESTORE();
return;
}
tmr->stopped_from = 0xa006;
@ -1531,6 +1538,7 @@ sctp_timeout_handler(void *t)
if (inp) {
SCTP_INP_DECR_REF(inp);
}
CURVNET_RESTORE();
return;
}
}
@ -1903,6 +1911,7 @@ sctp_timeout_handler(void *t)
out_no_decr:
SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type %d)\n",
type);
CURVNET_RESTORE();
}
void
@ -2263,6 +2272,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
tmr->tcb = (void *)stcb;
tmr->net = (void *)net;
tmr->self = (void *)tmr;
tmr->vnet = (void *)curvnet;
tmr->ticks = sctp_get_tick_count();
(void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
return;