Get SCTP working in combination with VIMAGE.
Contains code from bz. Approved by: rrs (mentor) MFC after: 1 month.
This commit is contained in:
parent
d2f7d5c975
commit
8518270e20
@ -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 @@ noconnection:
|
||||
/*
|
||||
* 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))
|
||||
|
@ -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 */
|
||||
{
|
||||
|
@ -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 *
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -51,6 +51,7 @@ struct sctp_timer {
|
||||
void *ep;
|
||||
void *tcb;
|
||||
void *net;
|
||||
void *vnet;
|
||||
|
||||
/* for sanity checking */
|
||||
void *self;
|
||||
|
@ -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,
|
||||
|
@ -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 @@ out_decr:
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user