Epochify SCTP.
This commit is contained in:
parent
9a4a1be02c
commit
868b51f234
@ -412,7 +412,6 @@ typedef struct rtentry sctp_rtentry_t;
|
||||
*/
|
||||
#define SCTP_IP_OUTPUT(result, o_pak, ro, stcb, vrf_id) \
|
||||
{ \
|
||||
struct epoch_tracker et; \
|
||||
int o_flgs = IP_RAWOUTPUT; \
|
||||
struct sctp_tcb *local_stcb = stcb; \
|
||||
if (local_stcb && \
|
||||
@ -420,24 +419,19 @@ typedef struct rtentry sctp_rtentry_t;
|
||||
local_stcb->sctp_ep->sctp_socket) \
|
||||
o_flgs |= local_stcb->sctp_ep->sctp_socket->so_options & SO_DONTROUTE; \
|
||||
m_clrprotoflags(o_pak); \
|
||||
NET_EPOCH_ENTER(et); \
|
||||
result = ip_output(o_pak, NULL, ro, o_flgs, 0, NULL); \
|
||||
NET_EPOCH_EXIT(et); \
|
||||
}
|
||||
|
||||
#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) \
|
||||
{ \
|
||||
struct epoch_tracker et; \
|
||||
struct sctp_tcb *local_stcb = stcb; \
|
||||
m_clrprotoflags(o_pak); \
|
||||
NET_EPOCH_ENTER(et); \
|
||||
if (local_stcb && local_stcb->sctp_ep) \
|
||||
result = ip6_output(o_pak, \
|
||||
((struct inpcb *)(local_stcb->sctp_ep))->in6p_outputopts, \
|
||||
(ro), 0, 0, ifp, NULL); \
|
||||
else \
|
||||
result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \
|
||||
NET_EPOCH_EXIT(et); \
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
|
@ -12561,6 +12561,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
struct thread *p
|
||||
)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
ssize_t sndlen = 0, max_len, local_add_more;
|
||||
int error, len;
|
||||
struct mbuf *top = NULL;
|
||||
@ -13062,7 +13063,9 @@ sctp_lower_sosend(struct socket *so,
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
free_cnt_applied = 0;
|
||||
/* release this lock, otherwise we hang on ourselves */
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, mm, SCTP_SO_LOCKED);
|
||||
NET_EPOCH_EXIT(et);
|
||||
/* now relock the stcb so everything is sane */
|
||||
hold_tcblock = 0;
|
||||
stcb = NULL;
|
||||
@ -13366,7 +13369,9 @@ skip_preblock:
|
||||
/* a collision took us forward? */
|
||||
queue_only = 0;
|
||||
} else {
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
|
||||
NET_EPOCH_EXIT(et);
|
||||
SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
|
||||
queue_only = 1;
|
||||
}
|
||||
@ -13424,6 +13429,7 @@ skip_preblock:
|
||||
* the input via the net is happening
|
||||
* and I don't need to start output :-D
|
||||
*/
|
||||
NET_EPOCH_ENTER(et);
|
||||
if (hold_tcblock == 0) {
|
||||
if (SCTP_TCB_TRYLOCK(stcb)) {
|
||||
hold_tcblock = 1;
|
||||
@ -13436,6 +13442,7 @@ skip_preblock:
|
||||
stcb,
|
||||
SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
}
|
||||
if (hold_tcblock == 1) {
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
@ -13609,8 +13616,10 @@ dataless_eof:
|
||||
"%s:%d at %s", __FILE__, __LINE__, __func__);
|
||||
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
|
||||
msg);
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb,
|
||||
op_err, SCTP_SO_LOCKED);
|
||||
NET_EPOCH_EXIT(et);
|
||||
/*
|
||||
* now relock the stcb so everything
|
||||
* is sane
|
||||
@ -13684,6 +13693,7 @@ skip_out_eof:
|
||||
stcb->asoc.total_flight,
|
||||
stcb->asoc.chunks_on_out_queue, stcb->asoc.total_flight_count);
|
||||
}
|
||||
NET_EPOCH_ENTER(et);
|
||||
if ((queue_only == 0) && (nagle_applies == 0) && (stcb->asoc.peers_rwnd && un_sent)) {
|
||||
/* we can attempt to send too. */
|
||||
if (hold_tcblock == 0) {
|
||||
@ -13719,6 +13729,7 @@ skip_out_eof:
|
||||
(void)sctp_med_chunk_output(inp, stcb, &stcb->asoc, &num_out,
|
||||
&reason, 1, 1, &now, &now_filled, frag_point, SCTP_SO_LOCKED);
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
SCTPDBG(SCTP_DEBUG_OUTPUT1, "USR Send complete qo:%d prw:%d unsent:%d tf:%d cooq:%d toqs:%d err:%d\n",
|
||||
queue_only, stcb->asoc.peers_rwnd, un_sent,
|
||||
stcb->asoc.total_flight, stcb->asoc.chunks_on_out_queue,
|
||||
|
@ -429,6 +429,7 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW,
|
||||
static void
|
||||
sctp_abort(struct socket *so)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
struct sctp_inpcb *inp;
|
||||
uint32_t flags;
|
||||
|
||||
@ -437,6 +438,7 @@ sctp_abort(struct socket *so)
|
||||
return;
|
||||
}
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_must_try_again:
|
||||
flags = inp->sctp_flags;
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
@ -466,6 +468,7 @@ sctp_must_try_again:
|
||||
goto sctp_must_try_again;
|
||||
}
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -526,6 +529,7 @@ sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
void
|
||||
sctp_close(struct socket *so)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
struct sctp_inpcb *inp;
|
||||
uint32_t flags;
|
||||
|
||||
@ -536,6 +540,7 @@ sctp_close(struct socket *so)
|
||||
/*
|
||||
* Inform all the lower layer assoc that we are done.
|
||||
*/
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_must_try_again:
|
||||
flags = inp->sctp_flags;
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
@ -578,6 +583,7 @@ sctp_must_try_again:
|
||||
goto sctp_must_try_again;
|
||||
}
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -660,9 +666,12 @@ connected_type:
|
||||
* definitions) but this is not advisable. This code is used
|
||||
* by FreeBSD when sending a file with sendfile() though.
|
||||
*/
|
||||
struct epoch_tracker et;
|
||||
int ret;
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
|
||||
NET_EPOCH_EXIT(et);
|
||||
inp->pkt = NULL;
|
||||
inp->control = NULL;
|
||||
return (ret);
|
||||
@ -689,6 +698,7 @@ sctp_disconnect(struct socket *so)
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
return (0);
|
||||
} else {
|
||||
struct epoch_tracker et;
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_tcb *stcb;
|
||||
|
||||
@ -706,6 +716,7 @@ sctp_disconnect(struct socket *so)
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
return (0);
|
||||
}
|
||||
NET_EPOCH_ENTER(et);
|
||||
if (((so->so_options & SO_LINGER) &&
|
||||
(so->so_linger == 0)) ||
|
||||
(so->so_rcv.sb_cc > 0)) {
|
||||
@ -725,6 +736,7 @@ sctp_disconnect(struct socket *so)
|
||||
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
|
||||
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
|
||||
/* No unlock tcb assoc is gone */
|
||||
NET_EPOCH_EXIT(et);
|
||||
return (0);
|
||||
}
|
||||
if (TAILQ_EMPTY(&asoc->send_queue) &&
|
||||
@ -799,12 +811,14 @@ sctp_disconnect(struct socket *so)
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
|
||||
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
|
||||
NET_EPOCH_EXIT(et);
|
||||
return (0);
|
||||
} else {
|
||||
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
|
||||
}
|
||||
}
|
||||
soisdisconnecting(so);
|
||||
NET_EPOCH_EXIT(et);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
return (0);
|
||||
@ -896,6 +910,7 @@ sctp_shutdown(struct socket *so)
|
||||
* SHUT_WR or SHUT_RDWR. This means we put the shutdown flag
|
||||
* against it.
|
||||
*/
|
||||
struct epoch_tracker et;
|
||||
struct sctp_tcb *stcb;
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_nets *netp;
|
||||
@ -935,6 +950,7 @@ sctp_shutdown(struct socket *so)
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
return (0);
|
||||
}
|
||||
NET_EPOCH_ENTER(et);
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
@ -974,6 +990,7 @@ sctp_shutdown(struct socket *so)
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb,
|
||||
op_err, SCTP_SO_LOCKED);
|
||||
NET_EPOCH_EXIT(et);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -985,6 +1002,7 @@ sctp_shutdown(struct socket *so)
|
||||
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
NET_EPOCH_EXIT(et);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -6906,11 +6924,12 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
int
|
||||
sctp_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
{
|
||||
void *optval = NULL;
|
||||
size_t optsize = 0;
|
||||
void *p;
|
||||
int error = 0;
|
||||
struct epoch_tracker et;
|
||||
struct sctp_inpcb *inp;
|
||||
void *optval = NULL;
|
||||
void *p;
|
||||
size_t optsize = 0;
|
||||
int error = 0;
|
||||
|
||||
if ((sopt->sopt_level == SOL_SOCKET) &&
|
||||
(sopt->sopt_name == SO_SETFIB)) {
|
||||
@ -6957,7 +6976,9 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
}
|
||||
p = (void *)sopt->sopt_td;
|
||||
if (sopt->sopt_dir == SOPT_SET) {
|
||||
NET_EPOCH_ENTER(et);
|
||||
error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p);
|
||||
NET_EPOCH_EXIT(et);
|
||||
} else if (sopt->sopt_dir == SOPT_GET) {
|
||||
error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p);
|
||||
} else {
|
||||
@ -6978,6 +6999,7 @@ out:
|
||||
static int
|
||||
sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
int error = 0;
|
||||
int create_lock_on = 0;
|
||||
uint32_t vrf_id;
|
||||
@ -7037,7 +7059,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
SCTP_INP_INCR_REF(inp);
|
||||
SCTP_ASOC_CREATE_LOCK(inp);
|
||||
create_lock_on = 1;
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
|
||||
@ -7122,10 +7144,10 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
out_now:
|
||||
NET_EPOCH_EXIT(et);
|
||||
if (create_lock_on) {
|
||||
SCTP_ASOC_CREATE_UNLOCK(inp);
|
||||
}
|
||||
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -1371,11 +1371,13 @@ sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
|
||||
static void
|
||||
sctp_iterator_work(struct sctp_iterator *it)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
struct sctp_inpcb *tinp;
|
||||
int iteration_count = 0;
|
||||
int inp_skip = 0;
|
||||
int first_in = 1;
|
||||
struct sctp_inpcb *tinp;
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
SCTP_ITERATOR_LOCK();
|
||||
sctp_it_ctl.cur_it = it;
|
||||
@ -1393,6 +1395,7 @@ done_with_iterator:
|
||||
(*it->function_atend) (it->pointer, it->val);
|
||||
}
|
||||
SCTP_FREE(it, SCTP_M_ITER);
|
||||
NET_EPOCH_EXIT(et);
|
||||
return;
|
||||
}
|
||||
select_a_new_ep:
|
||||
@ -1601,6 +1604,7 @@ sctp_handle_addr_wq(void)
|
||||
void
|
||||
sctp_timeout_handler(void *t)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_tcb *stcb;
|
||||
struct sctp_nets *net;
|
||||
@ -1716,6 +1720,7 @@ sctp_timeout_handler(void *t)
|
||||
/* record in stopped what t-o occurred */
|
||||
tmr->stopped_from = type;
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
/* mark as being serviced now */
|
||||
if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
|
||||
/*
|
||||
@ -1910,7 +1915,6 @@ sctp_timeout_handler(void *t)
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
/* no need to unlock on tcb its gone */
|
||||
goto out_decr;
|
||||
|
||||
case SCTP_TIMER_TYPE_STRRESET:
|
||||
if ((stcb == NULL) || (inp == NULL)) {
|
||||
break;
|
||||
@ -1943,7 +1947,6 @@ sctp_timeout_handler(void *t)
|
||||
sctp_delete_prim_timer(inp, stcb, net);
|
||||
SCTP_STAT_INCR(sctps_timodelprim);
|
||||
break;
|
||||
|
||||
case SCTP_TIMER_TYPE_AUTOCLOSE:
|
||||
if ((stcb == NULL) || (inp == NULL)) {
|
||||
break;
|
||||
@ -2034,6 +2037,7 @@ out_decr:
|
||||
out_no_decr:
|
||||
SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type = %d)\n", type);
|
||||
CURVNET_RESTORE();
|
||||
NET_EPOCH_EXIT(et);
|
||||
}
|
||||
|
||||
void
|
||||
@ -5184,6 +5188,7 @@ sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t *freed_so_far, int hold_rlock,
|
||||
uint32_t rwnd_req)
|
||||
{
|
||||
/* User pulled some data, do we need a rwnd update? */
|
||||
struct epoch_tracker et;
|
||||
int r_unlocked = 0;
|
||||
uint32_t dif, rwnd;
|
||||
struct socket *so = NULL;
|
||||
@ -5239,11 +5244,13 @@ sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t *freed_so_far, int hold_rlock,
|
||||
goto out;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_wu_sacks_sent);
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_send_sack(stcb, SCTP_SO_LOCKED);
|
||||
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb,
|
||||
SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
|
||||
/* make sure no timer is running */
|
||||
NET_EPOCH_EXIT(et);
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
|
||||
SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
|
@ -111,7 +111,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
|
||||
}
|
||||
}
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
sh = (struct sctphdr *)(mtod(m, caddr_t) + iphlen);
|
||||
sh = (struct sctphdr *)(mtod(m, caddr_t)+iphlen);
|
||||
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
|
||||
offset -= sizeof(struct sctp_chunkhdr);
|
||||
memset(&src, 0, sizeof(struct sockaddr_in6));
|
||||
@ -481,6 +481,7 @@ SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW,
|
||||
static void
|
||||
sctp6_abort(struct socket *so)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
struct sctp_inpcb *inp;
|
||||
uint32_t flags;
|
||||
|
||||
@ -489,6 +490,7 @@ sctp6_abort(struct socket *so)
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
|
||||
return;
|
||||
}
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_must_try_again:
|
||||
flags = inp->sctp_flags;
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
@ -517,6 +519,7 @@ sctp_must_try_again:
|
||||
goto sctp_must_try_again;
|
||||
}
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -776,9 +779,12 @@ connected_type:
|
||||
* optionaly switch back to this code (by changing back the
|
||||
* defininitions but this is not advisable.
|
||||
*/
|
||||
struct epoch_tracker et;
|
||||
int ret;
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
|
||||
NET_EPOCH_EXIT(et);
|
||||
inp->pkt = NULL;
|
||||
inp->control = NULL;
|
||||
return (ret);
|
||||
@ -790,6 +796,7 @@ connected_type:
|
||||
static int
|
||||
sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
uint32_t vrf_id;
|
||||
int error = 0;
|
||||
struct sctp_inpcb *inp;
|
||||
@ -924,8 +931,10 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
}
|
||||
SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
|
||||
(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
NET_EPOCH_EXIT(et);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user