diff options
-rw-r--r-- | sys/netinet/sctp_constants.h | 34 | ||||
-rw-r--r-- | sys/netinet/sctp_indata.c | 4 | ||||
-rw-r--r-- | sys/netinet/sctp_input.c | 110 | ||||
-rw-r--r-- | sys/netinet/sctp_input.h | 4 | ||||
-rw-r--r-- | sys/netinet/sctp_os_bsd.h | 20 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 39 | ||||
-rw-r--r-- | sys/netinet/sctp_output.h | 10 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.c | 42 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.h | 7 | ||||
-rw-r--r-- | sys/netinet/sctp_structs.h | 1 | ||||
-rw-r--r-- | sys/netinet/sctp_timer.c | 5 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 28 | ||||
-rw-r--r-- | sys/netinet/sctputil.h | 4 | ||||
-rw-r--r-- | sys/netinet6/sctp6_usrreq.c | 14 |
14 files changed, 164 insertions, 158 deletions
diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index 5d923fe..cdba2f1 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_COUNT_LIMIT 40 #define SCTP_ZERO_COPY_TICK_DELAY (((100 * hz) + 999) / 1000) +#define SCTP_ZERO_COPY_SENDQ_TICK_DELAY (((100 * hz) + 999) / 1000) /* Number of ticks to delay before running * iterator on an address change. @@ -545,8 +546,9 @@ __FBSDID("$FreeBSD$"); #define SCTP_TIMER_TYPE_ASOCKILL 18 #define SCTP_TIMER_TYPE_ADDR_WQ 19 #define SCTP_TIMER_TYPE_ZERO_COPY 20 +#define SCTP_TIMER_TYPE_ZCOPY_SENDQ 21 /* add new timers here - and increment LAST */ -#define SCTP_TIMER_TYPE_LAST 21 +#define SCTP_TIMER_TYPE_LAST 22 #define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \ ((t) < SCTP_TIMER_TYPE_LAST)) @@ -685,37 +687,37 @@ __FBSDID("$FreeBSD$"); /* SCTP DEBUG Switch parameters */ #define SCTP_DEBUG_TIMER1 0x00000001 -#define SCTP_DEBUG_TIMER2 0x00000002 -#define SCTP_DEBUG_TIMER3 0x00000004 +#define SCTP_DEBUG_TIMER2 0x00000002 /* unused */ +#define SCTP_DEBUG_TIMER3 0x00000004 /* unused */ #define SCTP_DEBUG_TIMER4 0x00000008 #define SCTP_DEBUG_OUTPUT1 0x00000010 #define SCTP_DEBUG_OUTPUT2 0x00000020 #define SCTP_DEBUG_OUTPUT3 0x00000040 #define SCTP_DEBUG_OUTPUT4 0x00000080 #define SCTP_DEBUG_UTIL1 0x00000100 -#define SCTP_DEBUG_UTIL2 0x00000200 +#define SCTP_DEBUG_UTIL2 0x00000200 /* unused */ #define SCTP_DEBUG_AUTH1 0x00000400 -#define SCTP_DEBUG_AUTH2 0x00000800 +#define SCTP_DEBUG_AUTH2 0x00000800 /* unused */ #define SCTP_DEBUG_INPUT1 0x00001000 #define SCTP_DEBUG_INPUT2 0x00002000 #define SCTP_DEBUG_INPUT3 0x00004000 -#define SCTP_DEBUG_INPUT4 0x00008000 +#define SCTP_DEBUG_INPUT4 0x00008000 /* unused */ #define SCTP_DEBUG_ASCONF1 0x00010000 #define SCTP_DEBUG_ASCONF2 0x00020000 -#define SCTP_DEBUG_OUTPUT5 0x00040000 -#define SCTP_DEBUG_XXX 0x00080000 +#define SCTP_DEBUG_OUTPUT5 0x00040000 /* unused */ +#define SCTP_DEBUG_XXX 0x00080000 /* unused */ #define SCTP_DEBUG_PCB1 0x00100000 -#define SCTP_DEBUG_PCB2 0x00200000 +#define SCTP_DEBUG_PCB2 0x00200000 /* unused */ #define SCTP_DEBUG_PCB3 0x00400000 -#define SCTP_DEBUG_PCB4 0x00800000 +#define SCTP_DEBUG_PCB4 0x00800000 /* unused */ #define SCTP_DEBUG_INDATA1 0x01000000 -#define SCTP_DEBUG_INDATA2 0x02000000 -#define SCTP_DEBUG_INDATA3 0x04000000 -#define SCTP_DEBUG_INDATA4 0x08000000 -#define SCTP_DEBUG_USRREQ1 0x10000000 -#define SCTP_DEBUG_USRREQ2 0x20000000 +#define SCTP_DEBUG_INDATA2 0x02000000 /* unused */ +#define SCTP_DEBUG_INDATA3 0x04000000 /* unused */ +#define SCTP_DEBUG_INDATA4 0x08000000 /* unused */ +#define SCTP_DEBUG_USRREQ1 0x10000000 /* unused */ +#define SCTP_DEBUG_USRREQ2 0x20000000 /* unused */ #define SCTP_DEBUG_PEEL1 0x40000000 -#define SCTP_DEBUG_XXXXX 0x80000000 +#define SCTP_DEBUG_XXXXX 0x80000000 /* unused */ #define SCTP_DEBUG_ALL 0x7ff3ffff #define SCTP_DEBUG_NOISY 0x00040000 diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index a55720d..665e14b 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -2597,7 +2597,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, } stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19; sctp_abort_association(inp, stcb, m, iphlen, sh, - op_err, 0, 0); + op_err, 0); return (2); } #ifdef SCTP_AUDITING_ENABLED @@ -2660,7 +2660,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, struct mbuf *op_err; op_err = sctp_generate_invmanparam(SCTP_CAUSE_PROTOCOL_VIOLATION); - sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, 0, 0); + sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, 0); return (2); } break; diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 249b9f2..85cfeed 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -78,8 +78,7 @@ sctp_stop_all_cookie_timers(struct sctp_tcb *stcb) static void sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, struct sctp_init_chunk *cp, struct sctp_inpcb *inp, struct sctp_tcb *stcb, - struct sctp_nets *net, int *abort_no_unlock, uint32_t vrf_id, - uint32_t table_id) + struct sctp_nets *net, int *abort_no_unlock, uint32_t vrf_id) { struct sctp_init *init; struct mbuf *op_err; @@ -99,7 +98,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, * match/restart case? */ sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, - vrf_id, table_id); + vrf_id); if (stcb) *abort_no_unlock = 1; return; @@ -108,7 +107,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, /* Invalid length */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, - vrf_id, table_id); + vrf_id); if (stcb) *abort_no_unlock = 1; return; @@ -118,7 +117,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, /* protocol error... send abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, - vrf_id, table_id); + vrf_id); if (stcb) *abort_no_unlock = 1; return; @@ -127,14 +126,14 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, /* invalid parameter... send abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, - vrf_id, table_id); + vrf_id); return; } if (init->num_inbound_streams == 0) { /* protocol error... send abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, - vrf_id, table_id); + vrf_id); if (stcb) *abort_no_unlock = 1; return; @@ -143,7 +142,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, /* protocol error... send abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, - vrf_id, table_id); + vrf_id); if (stcb) *abort_no_unlock = 1; return; @@ -152,16 +151,14 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, if (sctp_validate_init_auth_params(m, offset + sizeof(*cp), init_limit)) { /* auth parameter(s) error... send abort */ - sctp_abort_association(inp, stcb, m, iphlen, sh, NULL, vrf_id, - table_id); + sctp_abort_association(inp, stcb, m, iphlen, sh, NULL, vrf_id); if (stcb) *abort_no_unlock = 1; return; } /* send an INIT-ACK w/cookie */ SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n"); - sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp, vrf_id, - table_id); + sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp, vrf_id); } /* @@ -306,8 +303,7 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb, static int sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb, - struct sctp_nets *net, int *abort_no_unlock, uint32_t vrf_id, - uint32_t table_id) + struct sctp_nets *net, int *abort_no_unlock, uint32_t vrf_id) { struct sctp_association *asoc; struct mbuf *op_err; @@ -343,7 +339,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, "Load addresses from INIT causes an abort %d\n", retval); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, - NULL, 0, 0); + NULL, 0); *abort_no_unlock = 1; return (-1); } @@ -400,7 +396,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, mp->resv = 0; } sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, - sh, op_err, 0, 0); + sh, op_err, 0); *abort_no_unlock = 1; } return (retval); @@ -859,8 +855,7 @@ sctp_handle_error(struct sctp_chunkhdr *ch, static int sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb, - struct sctp_nets *net, int *abort_no_unlock, uint32_t vrf_id, - uint32_t table_id) + struct sctp_nets *net, int *abort_no_unlock, uint32_t vrf_id) { struct sctp_init_ack *init_ack; int *state; @@ -878,7 +873,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, /* Invalid length */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, - op_err, 0, 0); + op_err, 0); *abort_no_unlock = 1; return (-1); } @@ -888,7 +883,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, /* protocol error... send an abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, - op_err, 0, 0); + op_err, 0); *abort_no_unlock = 1; return (-1); } @@ -896,7 +891,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, /* protocol error... send an abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, - op_err, 0, 0); + op_err, 0); *abort_no_unlock = 1; return (-1); } @@ -904,7 +899,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, /* protocol error... send an abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, - op_err, 0, 0); + op_err, 0); *abort_no_unlock = 1; return (-1); } @@ -912,7 +907,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, /* protocol error... send an abort */ op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, - op_err, 0, 0); + op_err, 0); *abort_no_unlock = 1; return (-1); } @@ -936,8 +931,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, stcb, 0, (void *)stcb->asoc.primary_destination); } if (sctp_process_init_ack(m, iphlen, offset, sh, cp, stcb, - net, abort_no_unlock, vrf_id, - table_id) < 0) { + net, abort_no_unlock, vrf_id) < 0) { /* error in parsing parameters */ return (-1); } @@ -996,7 +990,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, struct sockaddr *init_src, int *notification, sctp_assoc_t * sac_assoc_id, - uint32_t vrf_id, uint32_t table_id) + uint32_t vrf_id) { struct sctp_association *asoc; struct sctp_init_chunk *init_cp, init_buf; @@ -1038,7 +1032,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN); ph->param_length = htons(sizeof(struct sctp_paramhdr)); sctp_send_operr_to(m, iphlen, op_err, cookie->peers_vtag, - vrf_id, table_id); + vrf_id); if (how_indx < sizeof(asoc->cookie_how)) asoc->cookie_how[how_indx] = 2; return (NULL); @@ -1473,7 +1467,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, struct sctp_inpcb *inp, struct sctp_nets **netp, struct sockaddr *init_src, int *notification, int auth_skipped, uint32_t auth_offset, uint32_t auth_len, - uint32_t vrf_id, uint32_t table_id) + uint32_t vrf_id) { struct sctp_tcb *stcb; struct sctp_init_chunk *init_cp, init_buf; @@ -1550,7 +1544,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen, - sh, op_err, vrf_id, table_id); + sh, op_err, vrf_id); return (NULL); } /* get the correct sctp_nets */ @@ -1558,8 +1552,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, *netp = sctp_findnet(stcb, init_src); asoc = &stcb->asoc; - /* save the table id (vrf_id is done in aloc_assoc) */ - asoc->table_id = table_id; /* get scope variables out of cookie */ asoc->ipv4_local_scope = cookie->ipv4_scope; asoc->site_scope = cookie->site_scope; @@ -1578,7 +1570,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, atomic_add_int(&stcb->asoc.refcnt, 1); op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen, - sh, op_err, vrf_id, table_id); + sh, op_err, vrf_id); atomic_add_int(&stcb->asoc.refcnt, -1); return (NULL); } @@ -1743,7 +1735,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, struct sctp_cookie_echo_chunk *cp, struct sctp_inpcb **inp_p, struct sctp_tcb **stcb, struct sctp_nets **netp, int auth_skipped, uint32_t auth_offset, uint32_t auth_len, - struct sctp_tcb **locked_tcb, uint32_t vrf_id, uint32_t table_id) + struct sctp_tcb **locked_tcb, uint32_t vrf_id) { struct sctp_state_cookie *cookie; struct sockaddr_in6 sin6; @@ -1950,7 +1942,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, tim = now.tv_usec - cookie->time_entered.tv_usec; scm->time_usec = htonl(tim); sctp_send_operr_to(m, iphlen, op_err, cookie->peers_vtag, - vrf_id, table_id); + vrf_id); return (NULL); } /* @@ -2030,13 +2022,13 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, /* this is the "normal" case... get a new TCB */ *stcb = sctp_process_cookie_new(m, iphlen, offset, sh, cookie, cookie_len, *inp_p, netp, to, ¬ification, - auth_skipped, auth_offset, auth_len, vrf_id, table_id); + auth_skipped, auth_offset, auth_len, vrf_id); } else { /* this is abnormal... cookie-echo on existing TCB */ had_a_existing_tcb = 1; *stcb = sctp_process_cookie_existing(m, iphlen, offset, sh, - cookie, cookie_len, *inp_p, *stcb, *netp, to, ¬ification, - &sac_restart_id, vrf_id, table_id); + cookie, cookie_len, *inp_p, *stcb, *netp, to, + ¬ification, &sac_restart_id, vrf_id); } if (*stcb == NULL) { @@ -2111,8 +2103,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n"); op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); sctp_abort_association(*inp_p, NULL, m, iphlen, - sh, op_err, vrf_id, - table_id); + sh, op_err, vrf_id); sctp_free_assoc(*inp_p, *stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_20); return (NULL); } @@ -3452,7 +3443,7 @@ __attribute__((noinline)) sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length, struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets **netp, int *fwd_tsn_seen, - uint32_t vrf_id, uint32_t table_id) + uint32_t vrf_id) { struct sctp_association *asoc; uint32_t vtag_in; @@ -3583,7 +3574,7 @@ __attribute__((noinline)) if (stcb == NULL) { /* no association, so it's out of the blue... */ sctp_handle_ootb(m, iphlen, *offset, sh, inp, NULL, - vrf_id, table_id); + vrf_id); *offset = length; if (locked_tcb) { SCTP_TCB_UNLOCK(locked_tcb); @@ -3620,7 +3611,7 @@ __attribute__((noinline)) SCTP_TCB_UNLOCK(locked_tcb); } sctp_handle_ootb(m, iphlen, *offset, sh, inp, - NULL, vrf_id, table_id); + NULL, vrf_id); return (NULL); } } else { @@ -3812,7 +3803,7 @@ process_control_chunks: if (netp) { sctp_handle_init(m, iphlen, *offset, sh, (struct sctp_init_chunk *)ch, inp, - stcb, *netp, &abort_no_unlock, vrf_id, table_id); + stcb, *netp, &abort_no_unlock, vrf_id); } if (abort_no_unlock) return (NULL); @@ -3851,7 +3842,7 @@ process_control_chunks: } if ((netp) && (*netp)) { ret = sctp_handle_init_ack(m, iphlen, *offset, sh, - (struct sctp_init_ack_chunk *)ch, stcb, *netp, &abort_no_unlock, vrf_id, table_id); + (struct sctp_init_ack_chunk *)ch, stcb, *netp, &abort_no_unlock, vrf_id); } else { ret = -1; } @@ -4028,8 +4019,7 @@ process_control_chunks: goto process_cookie_anyway; } sctp_abort_association(inp, stcb, m, iphlen, - sh, NULL, vrf_id, - table_id); + sh, NULL, vrf_id); *offset = length; return (NULL); } else if (inp->sctp_socket->so_qlimit) { @@ -4055,7 +4045,7 @@ process_control_chunks: htons(sizeof(struct sctp_paramhdr)); } sctp_abort_association(inp, stcb, m, - iphlen, sh, oper, vrf_id, table_id); + iphlen, sh, oper, vrf_id); } *offset = length; return (NULL); @@ -4085,8 +4075,7 @@ process_control_chunks: auth_offset, auth_len, &locked_tcb, - vrf_id, - table_id); + vrf_id); } else { ret_buf = NULL; } @@ -4483,7 +4472,7 @@ void sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length, struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, - uint8_t ecn_bits, uint32_t vrf_id, uint32_t table_id) + uint8_t ecn_bits, uint32_t vrf_id) { /* * Control chunk processing @@ -4512,7 +4501,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, /* process the control portion of the SCTP packet */ /* sa_ignore NO_NULL_CHK */ stcb = sctp_process_control(m, iphlen, &offset, length, sh, ch, - inp, stcb, &net, &fwd_tsn_seen, vrf_id, table_id); + inp, stcb, &net, &fwd_tsn_seen, vrf_id); if (stcb) { /* * This covers us if the cookie-echo was there and @@ -4542,7 +4531,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, if (stcb == NULL) { /* out of the blue DATA chunk */ sctp_handle_ootb(m, iphlen, offset, sh, inp, NULL, - vrf_id, table_id); + vrf_id); return; } if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) { @@ -4603,7 +4592,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, * We consider OOTB any data sent during asoc setup. */ sctp_handle_ootb(m, iphlen, offset, sh, inp, NULL, - vrf_id, table_id); + vrf_id); SCTP_TCB_UNLOCK(stcb); return; break; @@ -4705,7 +4694,7 @@ sctp_input(i_pak, off) #endif struct mbuf *m; int iphlen; - uint32_t vrf_id = 0, table_id = 0; + uint32_t vrf_id = 0; uint8_t ecn_bits; struct ip *ip; struct sctphdr *sh; @@ -4723,10 +4712,6 @@ sctp_input(i_pak, off) SCTP_RELEASE_PKT(i_pak); return; } - if (SCTP_GET_PKT_TABLEID(i_pak, table_id)) { - SCTP_RELEASE_PKT(i_pak); - return; - } mlen = SCTP_HEADER_LEN(i_pak); iphlen = off; m = SCTP_HEADER_TO_CHAIN(i_pak); @@ -4865,16 +4850,14 @@ sctp_skip_csum_4: sh->v_tag = init_chk->init.initiate_tag; } if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { - sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id, - table_id); + sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id); goto bad; } if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { goto bad; } if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) - sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, - table_id); + sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id); goto bad; } else if (stcb == NULL) { refcount_up = 1; @@ -4902,8 +4885,7 @@ sctp_skip_csum_4: /* sa_ignore NO_NULL_CHK */ sctp_common_input_processing(&m, iphlen, offset, length, sh, ch, - inp, stcb, net, ecn_bits, vrf_id, - table_id); + inp, stcb, net, ecn_bits, vrf_id); /* inp's ref-count reduced && stcb unlocked */ if (m) { sctp_m_freem(m); diff --git a/sys/netinet/sctp_input.h b/sys/netinet/sctp_input.h index 582dcce..3de05fe 100644 --- a/sys/netinet/sctp_input.h +++ b/sys/netinet/sctp_input.h @@ -40,8 +40,7 @@ __FBSDID("$FreeBSD$"); void sctp_common_input_processing(struct mbuf **, int, int, int, struct sctphdr *, struct sctp_chunkhdr *, struct sctp_inpcb *, - struct sctp_tcb *, struct sctp_nets *, uint8_t, uint32_t, uint32_t); - + struct sctp_tcb *, struct sctp_nets *, uint8_t, uint32_t); struct sctp_stream_reset_out_request * sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, @@ -51,6 +50,5 @@ void sctp_reset_in_stream(struct sctp_tcb *stcb, int number_entries, uint16_t * list); - #endif #endif diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index c2a1115..163b3b6 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -272,7 +272,7 @@ typedef struct callout sctp_os_timer_t; /*************************/ /* MTU */ /*************************/ -#define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index) ((struct ifnet *)ifn)->if_mtu +#define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, af) ((struct ifnet *)ifn)->if_mtu #define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, rt) ((rt != NULL) ? rt->rt_rmx.rmx_mtu : 0) #define SCTP_GATHER_MTU_FROM_INTFC(sctp_ifn) ((sctp_ifn->ifn_p != NULL) ? ((struct ifnet *)(sctp_ifn->ifn_p))->if_mtu : 0) #define SCTP_SET_MTU_OF_ROUTE(sa, rt, mtu) do { \ @@ -281,8 +281,8 @@ typedef struct callout sctp_os_timer_t; } while(0) /* (de-)register interface event notifications */ -#define SCTP_REGISTER_INTERFACE(ifhandle, ifname) -#define SCTP_DEREGISTER_INTERFACE(ifhandle, ifname) +#define SCTP_REGISTER_INTERFACE(ifhandle, af) +#define SCTP_DEREGISTER_INTERFACE(ifhandle, af) /*************************/ /* These are for logging */ @@ -314,12 +314,6 @@ SCTP_GET_PKT_VRFID(void *m, uint32_t vrf_id) vrf_id = SCTP_DEFAULT_VRFID; return (0); } -static inline int -SCTP_GET_PKT_TABLEID(void *m, uint32_t table_id) -{ - table_id = SCTP_DEFAULT_TABLEID; - return (0); -} /* Attach the chain of data into the sendable packet. */ #define SCTP_ATTACH_CHAIN(pak, m, packet_length) do { \ @@ -371,15 +365,17 @@ SCTP_GET_PKT_TABLEID(void *m, uint32_t table_id) typedef struct route sctp_route_t; typedef struct rtentry sctp_rtentry_t; -#define SCTP_RTALLOC(ro, vrf_id, table_id) rtalloc_ign((struct route *)ro, 0UL) +#define SCTP_RTALLOC(ro, vrf_id) rtalloc_ign((struct route *)ro, 0UL) /* Future zero copy wakeup/send function */ #define SCTP_ZERO_COPY_EVENT(inp, so) +/* This is re-pulse ourselves for sendbuf */ +#define SCTP_ZERO_COPY_SENDQ_EVENT(inp, so) /* * IP output routines */ -#define SCTP_IP_OUTPUT(result, o_pak, ro, stcb, vrf_id, table_id) \ +#define SCTP_IP_OUTPUT(result, o_pak, ro, stcb, vrf_id) \ { \ int o_flgs = 0; \ if (stcb && stcb->sctp_ep && stcb->sctp_ep->sctp_socket) { \ @@ -390,7 +386,7 @@ typedef struct rtentry sctp_rtentry_t; result = ip_output(o_pak, NULL, ro, o_flgs, 0, NULL); \ } -#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id, table_id) \ +#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) \ { \ if (stcb && stcb->sctp_ep) \ result = ip6_output(o_pak, \ diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index f35ea8c..022ffbe 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -2949,17 +2949,10 @@ sctp_source_address_selection(struct sctp_inpcb *inp, * we must use rotation amongst the bound addresses.. */ if (ro->ro_rt == NULL) { - uint32_t table_id = 0; - /* * Need a route to cache. */ - if (stcb) { - table_id = stcb->asoc.table_id; - } else { - table_id = SCTP_VRF_DEFAULT_TABLEID(vrf_id); - } - SCTP_RTALLOC(ro, vrf_id, table_id); + SCTP_RTALLOC(ro, vrf_id); } if (ro->ro_rt == NULL) { return (NULL); @@ -3469,7 +3462,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, SCTP_ATTACH_CHAIN(o_pak, m, packet_length); /* send it out. table id is taken from stcb */ - SCTP_IP_OUTPUT(ret, o_pak, ro, stcb, vrf_id, 0); + SCTP_IP_OUTPUT(ret, o_pak, ro, stcb, vrf_id); SCTP_STAT_INCR(sctps_sendpackets); SCTP_STAT_INCR_COUNTER64(sctps_outpackets); @@ -3686,7 +3679,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, /* send it out. table id is taken from stcb */ SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, &ifp, - stcb, vrf_id, 0); + stcb, vrf_id); if (net) { /* for link local this must be done */ @@ -4483,7 +4476,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc, void sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct mbuf *init_pkt, int iphlen, int offset, struct sctphdr *sh, - struct sctp_init_chunk *init_chk, uint32_t vrf_id, uint32_t table_id) + struct sctp_init_chunk *init_chk, uint32_t vrf_id) { struct sctp_association *asoc; struct mbuf *m, *m_at, *m_tmp, *m_cookie, *op_err, *mp_last; @@ -4521,8 +4514,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, * though we even set the T bit and copy in the 0 tag.. this * looks no different than if no listener was present. */ - sctp_send_abort(init_pkt, iphlen, sh, 0, NULL, vrf_id, - table_id); + sctp_send_abort(init_pkt, iphlen, sh, 0, NULL, vrf_id); return; } abort_flag = 0; @@ -4531,8 +4523,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, &abort_flag, (struct sctp_chunkhdr *)init_chk); if (abort_flag) { sctp_send_abort(init_pkt, iphlen, sh, - init_chk->init.initiate_tag, op_err, vrf_id, - table_id); + init_chk->init.initiate_tag, op_err, vrf_id); return; } m = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); @@ -9252,7 +9243,7 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb, void sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh, - uint32_t vrf_id, uint32_t table_id) + uint32_t vrf_id) { /* formulate and SEND a SHUTDOWN-COMPLETE */ struct mbuf *o_pak; @@ -9355,7 +9346,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh, SCTP_ATTACH_CHAIN(o_pak, mout, mlen); /* out it goes */ - SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id, table_id); + SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id); /* Free the route if we got one back */ if (ro.ro_rt) @@ -9372,7 +9363,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh, sctp_packet_log(mout, mlen); #endif SCTP_ATTACH_CHAIN(o_pak, mout, mlen); - SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id, table_id); + SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id); /* Free the route if we got one back */ if (ro.ro_rt) @@ -10091,7 +10082,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, void sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag, - struct mbuf *err_cause, uint32_t vrf_id, uint32_t table_id) + struct mbuf *err_cause, uint32_t vrf_id) { /*- * Formulate the abort message, and send it back down. @@ -10224,7 +10215,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag, sctp_packet_log(mout, len); #endif SCTP_ATTACH_CHAIN(o_pak, mout, len); - SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id, table_id); + SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id); /* Free the route if we got one back */ if (ro.ro_rt) @@ -10244,7 +10235,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag, sctp_packet_log(mout, len); #endif SCTP_ATTACH_CHAIN(o_pak, mout, len); - SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id, table_id); + SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id); /* Free the route if we got one back */ if (ro.ro_rt) @@ -10256,7 +10247,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag, void sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag, - uint32_t vrf_id, uint32_t table_id) + uint32_t vrf_id) { struct mbuf *o_pak; struct sctphdr *ihdr; @@ -10349,7 +10340,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag, #endif SCTP_ATTACH_CHAIN(o_pak, mout, len); - SCTP_IP_OUTPUT(retcode, o_pak, &ro, stcb, vrf_id, table_id); + SCTP_IP_OUTPUT(retcode, o_pak, &ro, stcb, vrf_id); SCTP_STAT_INCR(sctps_sendpackets); SCTP_STAT_INCR_COUNTER64(sctps_outpackets); @@ -10396,7 +10387,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag, sctp_packet_log(mout, len); #endif SCTP_ATTACH_CHAIN(o_pak, mout, len); - SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id, table_id); + SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id); SCTP_STAT_INCR(sctps_sendpackets); SCTP_STAT_INCR_COUNTER64(sctps_outpackets); diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index 4ff2842..5240eef 100644 --- a/sys/netinet/sctp_output.h +++ b/sys/netinet/sctp_output.h @@ -76,7 +76,7 @@ void sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *); void sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *, int, int, struct sctphdr *, struct sctp_init_chunk *, - uint32_t, uint32_t); + uint32_t); struct mbuf * sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *, @@ -102,7 +102,7 @@ void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *); void sctp_send_shutdown_complete2(struct mbuf *, int, struct sctphdr *, - uint32_t, uint32_t); + uint32_t); void sctp_send_asconf(struct sctp_tcb *, struct sctp_nets *); @@ -179,11 +179,9 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, void sctp_send_abort(struct mbuf *, int, struct sctphdr *, uint32_t, - struct mbuf *, uint32_t, uint32_t); + struct mbuf *, uint32_t); -void -sctp_send_operr_to(struct mbuf *, int, struct mbuf *, uint32_t, uint32_t, - uint32_t); +void sctp_send_operr_to(struct mbuf *, int, struct mbuf *, uint32_t, uint32_t); int sctp_sosend(struct socket *so, diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 76f59c4..3b1e3b7 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -281,6 +281,8 @@ sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock) SCTP_IPI_ADDR_LOCK(); LIST_REMOVE(sctp_ifnp, next_bucket); LIST_REMOVE(sctp_ifnp, next_ifn); + SCTP_DEREGISTER_INTERFACE(sctp_ifnp->ifn_index, + sctp_ifnp->registered_af); if (hold_addr_lock == 0) SCTP_IPI_ADDR_UNLOCK(); /* Take away the reference, and possibly free it */ @@ -300,6 +302,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, struct sctp_ifalist *hash_addr_head; struct sctp_ifnlist *hash_ifn_head; uint32_t hash_of_addr; + int new_ifn_af = 0; /* How granular do we need the locks to be here? */ SCTP_IPI_ADDR_LOCK(); @@ -331,7 +334,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, sctp_ifnp->ifa_count = 0; sctp_ifnp->refcount = 1; sctp_ifnp->vrf = vrf; - sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index); + sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, addr->sa_family); if (if_name != NULL) { memcpy(sctp_ifnp->ifn_name, if_name, SCTP_IFNAMSIZ); } else { @@ -343,6 +346,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket); LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn); atomic_add_int(&sctppcbinfo.ipi_count_ifns, 1); + new_ifn_af = 1; } sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1); if (sctp_ifap) { @@ -403,6 +407,9 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { sctp_ifap->src_is_priv = 1; } + sctp_ifnp->num_v4++; + if (new_ifn_af) + new_ifn_af = AF_INET; } else if (sctp_ifap->address.sa.sa_family == AF_INET6) { /* ok to use deprecated addresses? */ struct sockaddr_in6 *sin6; @@ -415,6 +422,11 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { sctp_ifap->src_is_priv = 1; } + sctp_ifnp->num_v6++; + if (new_ifn_af) + new_ifn_af = AF_INET6; + } else { + new_ifn_af = 0; } hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa); @@ -430,6 +442,10 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, sctp_ifnp->ifa_count++; vrf->total_ifa_count++; atomic_add_int(&sctppcbinfo.ipi_count_ifas, 1); + if (new_ifn_af) { + SCTP_REGISTER_INTERFACE(ifn_index, new_ifn_af); + sctp_ifnp->registered_af = new_ifn_af; + } SCTP_IPI_ADDR_UNLOCK(); if (dynamic_add) { /* @@ -496,8 +512,28 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr, LIST_REMOVE(sctp_ifap, next_ifa); if (sctp_ifap->ifn_p) { sctp_ifap->ifn_p->ifa_count--; + if (sctp_ifap->address.sa.sa_family == AF_INET6) + sctp_ifap->ifn_p->num_v6--; + else if (sctp_ifap->address.sa.sa_family == AF_INET) + sctp_ifap->ifn_p->num_v4--; if (SCTP_LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) { sctp_delete_ifn(sctp_ifap->ifn_p, 1); + } else { + if ((sctp_ifap->ifn_p->num_v6 == 0) && + (sctp_ifap->ifn_p->registered_af == AF_INET6)) { + SCTP_DEREGISTER_INTERFACE(ifn_index, + AF_INET6); + SCTP_REGISTER_INTERFACE(ifn_index, + AF_INET); + sctp_ifap->ifn_p->registered_af = AF_INET; + } else if ((sctp_ifap->ifn_p->num_v4 == 0) && + (sctp_ifap->ifn_p->registered_af == AF_INET)) { + SCTP_DEREGISTER_INTERFACE(ifn_index, + AF_INET); + SCTP_REGISTER_INTERFACE(ifn_index, + AF_INET6); + sctp_ifap->ifn_p->registered_af = AF_INET6; + } } sctp_free_ifn(sctp_ifap->ifn_p); sctp_ifap->ifn_p = NULL; @@ -1793,7 +1829,6 @@ sctp_inpcb_alloc(struct socket *so) return (ENOBUFS); } inp->def_vrf_id = SCTP_DEFAULT_VRFID; - inp->def_table_id = SCTP_DEFAULT_TABLEID; SCTP_INP_INFO_WLOCK(); SCTP_INP_LOCK_INIT(inp); @@ -3068,8 +3103,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, (void)sa6_embedscope(sin6, ip6_use_defzone); sin6->sin6_scope_id = 0; } - SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id, - stcb->asoc.table_id); + SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id); if (newaddr->sa_family == AF_INET6) { struct sockaddr_in6 *sin6; diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h index 7f336e7..af69bbe 100644 --- a/sys/netinet/sctp_pcb.h +++ b/sys/netinet/sctp_pcb.h @@ -79,6 +79,9 @@ struct sctp_ifn { uint32_t refcount; /* number of reference held should be >= * ifa_count */ uint32_t ifa_count; /* IFA's we hold (in our list - ifalist) */ + uint32_t num_v6; /* number of v6 addresses */ + uint32_t num_v4; /* number of v4 addresses */ + uint32_t registered_af; /* registered address family for i/f events */ char ifn_name[SCTP_IFNAMSIZ]; }; @@ -109,7 +112,6 @@ struct sctp_ifa { uint8_t src_is_priv; uint8_t src_is_glob; uint8_t resv; - }; struct sctp_laddr { @@ -281,6 +283,8 @@ struct sctp_pcb { /* Zero copy full buffer timer */ struct sctp_timer zero_copy_timer; + /* Zero copy app to transport (sendq) read repulse timer */ + struct sctp_timer zero_copy_sendq_timer; int def_cookie_life; /* defaults to 0 */ int auto_close_time; @@ -364,7 +368,6 @@ struct sctp_inpcb { struct mtx inp_rdata_mtx; int32_t refcount; uint32_t def_vrf_id; - uint32_t def_table_id; uint32_t total_sends; uint32_t total_recvs; uint32_t last_abort_code; diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index e50ccc5..acfd6f9 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -598,7 +598,6 @@ struct sctp_association { struct sctp_readhead pending_reply_queue; uint32_t vrf_id; - uint32_t table_id; uint32_t cookie_preserve_req; /* ASCONF next seq I am sending out, inits at init-tsn */ diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 8d67179..39f46d06 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -291,7 +291,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb, */ continue; } - if (val > mnet->ssthresh) { + if (val < mnet->ssthresh) { hthresh = mnet; val = mnet->ssthresh; } else if (val == mnet->ssthresh) { @@ -644,6 +644,9 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq; } } + /* + * CMT: Do not allow FRs on retransmitted TSNs. + */ if (sctp_cmt_on_off == 1) { chk->no_fr_allowed = 1; } diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 8b4943a..ab4e8aa 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -955,8 +955,6 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, asoc->my_vtag_nonce = sctp_select_a_tag(m); asoc->peer_vtag_nonce = sctp_select_a_tag(m); asoc->vrf_id = vrf_id; - /* Save the table id as well from the inp */ - asoc->table_id = m->def_table_id; if (sctp_is_feature_on(m, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) asoc->hb_is_disabled = 1; @@ -1466,6 +1464,11 @@ sctp_timeout_handler(void *t) SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); } break; + case SCTP_TIMER_TYPE_ZCOPY_SENDQ: + if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { + SCTP_ZERO_COPY_SENDQ_EVENT(inp, inp->sctp_socket); + } + break; case SCTP_TIMER_TYPE_ADDR_WQ: sctp_handle_addr_wq(); break; @@ -1788,6 +1791,10 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, tmr = &inp->sctp_ep.zero_copy_timer; to_ticks = SCTP_ZERO_COPY_TICK_DELAY; break; + case SCTP_TIMER_TYPE_ZCOPY_SENDQ: + tmr = &inp->sctp_ep.zero_copy_sendq_timer; + to_ticks = SCTP_ZERO_COPY_SENDQ_TICK_DELAY; + break; case SCTP_TIMER_TYPE_ADDR_WQ: /* Only 1 tick away :-) */ tmr = &sctppcbinfo.addr_wq_timer; @@ -2137,7 +2144,9 @@ sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, case SCTP_TIMER_TYPE_ZERO_COPY: tmr = &inp->sctp_ep.zero_copy_timer; break; - + case SCTP_TIMER_TYPE_ZCOPY_SENDQ: + tmr = &inp->sctp_ep.zero_copy_sendq_timer; + break; case SCTP_TIMER_TYPE_ADDR_WQ: tmr = &sctppcbinfo.addr_wq_timer; break; @@ -3559,7 +3568,7 @@ sctp_abort_notification(struct sctp_tcb *stcb, int error) void sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err, - uint32_t vrf_id, uint32_t table_id) + uint32_t vrf_id) { uint32_t vtag; @@ -3570,9 +3579,8 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_abort_notification(stcb, 0); /* get the assoc vrf id and table id */ vrf_id = stcb->asoc.vrf_id; - table_id = stcb->asoc.table_id; } - sctp_send_abort(m, iphlen, sh, vtag, op_err, vrf_id, table_id); + sctp_send_abort(m, iphlen, sh, vtag, op_err, vrf_id); if (stcb != NULL) { /* Ok, now lets free it */ sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_4); @@ -3684,8 +3692,7 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, - struct sctp_inpcb *inp, struct mbuf *op_err, uint32_t vrf_id, - uint32_t table_id) + struct sctp_inpcb *inp, struct mbuf *op_err, uint32_t vrf_id) { struct sctp_chunkhdr *ch, chunk_buf; unsigned int chk_length; @@ -3720,8 +3727,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, */ return; case SCTP_SHUTDOWN_ACK: - sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id, - table_id); + sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id); return; default: break; @@ -3730,7 +3736,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch), (uint8_t *) & chunk_buf); } - sctp_send_abort(m, iphlen, sh, 0, op_err, vrf_id, table_id); + sctp_send_abort(m, iphlen, sh, 0, op_err, vrf_id); } /* diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index e3f85de..c0beff8 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -207,7 +207,7 @@ void sctp_abort_notification(struct sctp_tcb *, int); /* We abort responding to an IP packet for some reason */ void sctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *, - struct mbuf *, int, struct sctphdr *, struct mbuf *, uint32_t, uint32_t); + struct mbuf *, int, struct sctphdr *, struct mbuf *, uint32_t); /* We choose to abort via user input */ @@ -217,7 +217,7 @@ sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *, int, void sctp_handle_ootb(struct mbuf *, int, int, struct sctphdr *, - struct sctp_inpcb *, struct mbuf *, uint32_t, uint32_t); + struct sctp_inpcb *, struct mbuf *, uint32_t); int sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index 427b69b..cf8df3a 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -71,7 +71,7 @@ sctp6_input(i_pak, offp, proto) struct sctp_nets *net; int refcount_up = 0; uint32_t check, calc_check; - uint32_t vrf_id = 0, table_id = 0; + uint32_t vrf_id = 0; struct inpcb *in6p_ip; struct sctp_chunkhdr *ch; int length, mlen, offset, iphlen; @@ -85,10 +85,6 @@ sctp6_input(i_pak, offp, proto) SCTP_RELEASE_PKT(*i_pak); return (-1); } - if (SCTP_GET_PKT_TABLEID(*i_pak, table_id)) { - SCTP_RELEASE_PKT(*i_pak); - return (-1); - } m = SCTP_HEADER_TO_CHAIN(*i_pak); pkt_len = SCTP_HEADER_LEN((*i_pak)); @@ -189,16 +185,14 @@ sctp_skip_csum: sh->v_tag = 0; } if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { - sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id, - table_id); + sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id); goto bad; } if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { goto bad; } if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) - sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, - table_id); + sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id); goto bad; } else if (stcb == NULL) { refcount_up = 1; @@ -226,7 +220,7 @@ sctp_skip_csum: /* sa_ignore NO_NULL_CHK */ sctp_common_input_processing(&m, iphlen, offset, length, sh, ch, - in6p, stcb, net, ecn_bits, vrf_id, table_id); + in6p, stcb, net, ecn_bits, vrf_id); /* inp's ref-count reduced && stcb unlocked */ /* XXX this stuff below gets moved to appropriate parts later... */ if (m) |