- fixed several places where we did not release INP locks.
- fixed a refcount bug in the new ifa structures. - use vrf's from default stcb or inp whenever possible. - Address limits raised to account for a full IP fragmented packet (1000 addresses). - flight size correcting updated to include one message only and to handle case where the peer does not cumack the next segment aka lists 1/1 in sack blocks.. - Various bad init/init-ack handling could cause a panic since we tried to unlock the destroyed mutex. Fixes so we properly exit when we need to destroy an assoc. (Found by Cisco DevTest team :D) - name rename in src-addr-selection from pass to sifa. - route structure typedef'd to allow different platforms and updated into sctp_os_bsd file. - Max retransmissions a chunk can be made added. Reviewed by: gnn
This commit is contained in:
parent
c277843c22
commit
ad3d567017
@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/sctp_header.h>
|
||||
#include <netinet/sctputil.h>
|
||||
#include <netinet/sctp_output.h>
|
||||
#include <netinet/sctp_bsd_addr.h>
|
||||
#include <netinet/sctp_asconf.h>
|
||||
|
||||
/*
|
||||
@ -1054,6 +1053,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa, uint16_t type
|
||||
/* take the entry off the appropriate list */
|
||||
sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
|
||||
/* free the entry */
|
||||
sctp_free_ifa(aa->ifa);
|
||||
SCTP_FREE(aa);
|
||||
return (-1);
|
||||
}
|
||||
@ -1074,6 +1074,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa, uint16_t type
|
||||
/* top level elements are "networked" during send */
|
||||
aa->ap.aph.ph.param_type = type;
|
||||
aa->ifa = ifa;
|
||||
atomic_add_int(&ifa->refcount, 1);
|
||||
/* correlation_id filled in during send routine later... */
|
||||
if (ifa->address.sa.sa_family == AF_INET6) {
|
||||
/* IPv6 address */
|
||||
@ -1150,6 +1151,7 @@ static uint32_t
|
||||
sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
uint16_t type)
|
||||
{
|
||||
struct sctp_ifa *ifa;
|
||||
struct sctp_asconf_addr *aa, *aa_next;
|
||||
uint32_t vrf_id;
|
||||
|
||||
@ -1178,6 +1180,7 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
/* delete the existing entry in the queue */
|
||||
TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
|
||||
/* free the entry */
|
||||
sctp_free_ifa(aa->ifa);
|
||||
SCTP_FREE(aa);
|
||||
return (-1);
|
||||
} else if (type == SCTP_DEL_IP_ADDRESS &&
|
||||
@ -1189,11 +1192,22 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
/* take the entry off the appropriate list */
|
||||
sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
|
||||
/* free the entry */
|
||||
sctp_free_ifa(aa->ifa);
|
||||
SCTP_FREE(aa);
|
||||
return (-1);
|
||||
}
|
||||
} /* for each aa */
|
||||
if (stcb) {
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
} else {
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
}
|
||||
|
||||
ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
|
||||
if (ifa == NULL) {
|
||||
/* Invalid address */
|
||||
return (-1);
|
||||
}
|
||||
/* adding new request to the queue */
|
||||
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
|
||||
if (aa == NULL) {
|
||||
@ -1207,9 +1221,9 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
}
|
||||
/* fill in asconf address parameter fields */
|
||||
/* top level elements are "networked" during send */
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
aa->ap.aph.ph.param_type = type;
|
||||
aa->ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
|
||||
aa->ifa = ifa;
|
||||
atomic_add_int(&ifa->refcount, 1);
|
||||
/* correlation_id filled in during send routine later... */
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
/* IPv6 address */
|
||||
@ -1372,6 +1386,7 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
|
||||
|
||||
/* remove the param and free it */
|
||||
TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
|
||||
sctp_free_ifa(aparam->ifa);
|
||||
SCTP_FREE(aparam);
|
||||
}
|
||||
|
||||
@ -2413,7 +2428,12 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
}
|
||||
|
||||
/* see if this address really (still) exists */
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
if (stcb) {
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
} else {
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
}
|
||||
|
||||
sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
|
||||
if (sctp_ifa == NULL) {
|
||||
/* address doesn't exist anymore */
|
||||
@ -2626,7 +2646,11 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
uint32_t vrf_id;
|
||||
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
if (stcb) {
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
} else {
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
}
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
return;
|
||||
|
@ -33,8 +33,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#ifndef __sctp_bsd_addr_h__
|
||||
#define __sctp_bsd_addr_h__
|
||||
|
||||
#include <netinet/sctp_header.h>
|
||||
#include <netinet/sctp_pcb.h>
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
@ -45,11 +44,9 @@ void sctp_startup_iterator(void);
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa);
|
||||
void sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa);
|
||||
|
||||
|
||||
extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
|
||||
void sctp_addr_change(struct ifaddr *ifa, int cmd);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -40,26 +40,22 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_DEFAULT_SACK_FREQ 2
|
||||
|
||||
/* Address limit - This variable is calculated
|
||||
* based on an 1500 byte mtu. We take out 100 bytes
|
||||
* based on an 65535 byte max ip packet. We take out 100 bytes
|
||||
* for the cookie, 40 bytes for a v6 header and 32
|
||||
* bytes for the init structure. A second init structure
|
||||
* for the init-ack and then finally a third one for the
|
||||
* imbedded init. This yeilds 100+40+(3 * 32) = 236 bytes.
|
||||
* This leaves 1264 bytes for addresses. Now whatever we
|
||||
* send in the INIT() we need to allow to get back in the
|
||||
* This leaves 65299 bytes for addresses. We throw out the 299 bytes.
|
||||
* Now whatever we send in the INIT() we need to allow to get back in the
|
||||
* INIT-ACK plus all the values from INIT and INIT-ACK
|
||||
* listed in the cookie. Plus we need some overhead for
|
||||
* maybe copied parameters in the COOKIE. If we
|
||||
* allow 20 addresses, and each side has 20 V6 addresses
|
||||
* that will be 400 bytes. In the INIT-ACK we will
|
||||
* see the INIT-ACK 400 + 800 in the cookie. This leaves
|
||||
* 64 bytes slack for misc things in the cookie. Otherwise
|
||||
* we need to allow IP fragmentation.. which I believe
|
||||
* the INIT-ACK and COOKIE do, I don't think we do that
|
||||
* to the INIT though. So the max you could make this
|
||||
* value is 60 addresses.
|
||||
* allow 1080 addresses, and each side has 1080 V6 addresses
|
||||
* that will be 21600 bytes. In the INIT-ACK we will
|
||||
* see the INIT-ACK 21600 + 43200 in the cookie. This leaves
|
||||
* about 500 bytes slack for misc things in the cookie.
|
||||
*/
|
||||
#define SCTP_ADDRESS_LIMIT 20
|
||||
#define SCTP_ADDRESS_LIMIT 1080
|
||||
|
||||
/* Number of addresses where we just skip the counting */
|
||||
#define SCTP_COUNT_LIMIT 40
|
||||
|
@ -4071,6 +4071,63 @@ sctp_cwnd_update(struct sctp_tcb *stcb,
|
||||
}
|
||||
}
|
||||
|
||||
static int sctp_anal_print = 0;
|
||||
|
||||
static void
|
||||
sctp_print_fs_audit(struct sctp_association *asoc)
|
||||
{
|
||||
int cnt, i;
|
||||
struct sctp_tmit_chunk *chk;
|
||||
int inflight = 0, resend = 0, inbetween = 0, acked = 0, above = 0;
|
||||
|
||||
printf("sdqc:%d stqc:%d retran:%d reasm:%d cnt:%d tot_flight:%d tfc:%d\n",
|
||||
(int)asoc->send_queue_cnt,
|
||||
(int)asoc->sent_queue_cnt,
|
||||
(int)asoc->sent_queue_retran_cnt,
|
||||
(int)asoc->size_on_reasm_queue,
|
||||
(int)asoc->cnt_on_reasm_queue,
|
||||
(int)asoc->total_flight,
|
||||
(int)asoc->total_flight_count);
|
||||
printf("my_rwnd:%d peers_rwnd:%d asoc calc cumack:%x\n",
|
||||
(int)asoc->my_rwnd, (int)asoc->peers_rwnd, asoc->last_acked_seq);
|
||||
for (i = 0; i < asoc->streamoutcnt; i++) {
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
|
||||
cnt = 0;
|
||||
TAILQ_FOREACH(sp, &asoc->strmout[i].outqueue, next)
|
||||
cnt++;
|
||||
if (cnt) {
|
||||
printf("Stream %d has %d msgs yet to be sent in strm queue\n", i, cnt);
|
||||
}
|
||||
}
|
||||
cnt = 0;
|
||||
TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
|
||||
cnt++;
|
||||
}
|
||||
printf("The control_send_queue has %d pending\n", cnt);
|
||||
cnt = 0;
|
||||
TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
|
||||
cnt++;
|
||||
}
|
||||
printf("The send_queue (waiting to get in flight) has %d chunks pending\n", cnt);
|
||||
TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
|
||||
if (chk->sent < SCTP_DATAGRAM_RESEND) {
|
||||
inflight++;
|
||||
} else if (chk->sent == SCTP_DATAGRAM_RESEND) {
|
||||
resend++;
|
||||
} else if (chk->sent < SCTP_DATAGRAM_ACKED) {
|
||||
inbetween++;
|
||||
} else if (chk->sent > SCTP_DATAGRAM_ACKED) {
|
||||
above++;
|
||||
} else {
|
||||
acked++;
|
||||
printf("chk->sent:%x chk->tsn:%x\n",
|
||||
chk->sent, chk->rec.data.TSN_seq);
|
||||
}
|
||||
}
|
||||
printf("The sent_queue stats inflight:%d resend:%d acked:%d above:%d inbetween:%d\n",
|
||||
inflight, resend, acked, above, inbetween);
|
||||
}
|
||||
|
||||
void
|
||||
sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
@ -4081,7 +4138,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
struct sctp_tmit_chunk *tp1, *tp2;
|
||||
uint32_t old_rwnd;
|
||||
int win_probe_recovery = 0;
|
||||
int j;
|
||||
int j, done_once;;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
asoc = &stcb->asoc;
|
||||
@ -4351,6 +4408,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
win_probe_recovery = 1;
|
||||
}
|
||||
/* Now assure a timer where data is queued at */
|
||||
done_once = 0;
|
||||
again:
|
||||
j = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
@ -4402,12 +4460,15 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((j == 0) && (!TAILQ_EMPTY(&asoc->sent_queue)) && (asoc->sent_queue_retran_cnt == 0)) {
|
||||
if ((j == 0) &&
|
||||
(!TAILQ_EMPTY(&asoc->sent_queue)) &&
|
||||
(asoc->sent_queue_retran_cnt == 0) &&
|
||||
(done_once == 0)) {
|
||||
/* huh, this should not happen */
|
||||
#ifdef INVARIANTS
|
||||
panic("Flight size incorrect? fixing??");
|
||||
#else
|
||||
printf("Flight size incorrect? fixing\n");
|
||||
if (sctp_anal_print == 0) {
|
||||
printf("Flight size-express incorrect? cumack:%x\n", cumack);
|
||||
sctp_print_fs_audit(asoc);
|
||||
}
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
net->flight_size = 0;
|
||||
}
|
||||
@ -4423,7 +4484,12 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
asoc->sent_queue_retran_cnt++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (sctp_anal_print == 0) {
|
||||
printf("After audit, totalflight:%d, retran_cnt:%d\n",
|
||||
asoc->total_flight, asoc->sent_queue_retran_cnt);
|
||||
sctp_anal_print = 1;
|
||||
}
|
||||
done_once = 1;
|
||||
goto again;
|
||||
}
|
||||
/**********************************/
|
||||
@ -4527,6 +4593,7 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
|
||||
struct sctp_tmit_chunk *tp1, *tp2;
|
||||
uint32_t cum_ack, last_tsn, biggest_tsn_acked, biggest_tsn_newly_acked,
|
||||
this_sack_lowest_newack;
|
||||
uint32_t sav_cum_ack;
|
||||
uint16_t num_seg, num_dup;
|
||||
uint16_t wake_him = 0;
|
||||
unsigned int sack_length;
|
||||
@ -4538,6 +4605,7 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
|
||||
int win_probe_recovery = 0;
|
||||
struct sctp_nets *net = NULL;
|
||||
int nonce_sum_flag, ecn_seg_sums = 0;
|
||||
int done_once;
|
||||
uint8_t reneged_all = 0;
|
||||
uint8_t cmt_dac_flag;
|
||||
|
||||
@ -4668,6 +4736,8 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
|
||||
/* acking something behind */
|
||||
return;
|
||||
}
|
||||
sav_cum_ack = asoc->last_acked_seq;
|
||||
|
||||
/* update the Rwnd of the peer */
|
||||
if (TAILQ_EMPTY(&asoc->sent_queue) &&
|
||||
TAILQ_EMPTY(&asoc->send_queue) &&
|
||||
@ -5391,6 +5461,7 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
|
||||
* Now we must setup so we have a timer up for anyone with
|
||||
* outstanding data.
|
||||
*/
|
||||
done_once = 0;
|
||||
again:
|
||||
j = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
@ -5423,12 +5494,16 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
|
||||
stcb->sctp_ep, stcb, net);
|
||||
}
|
||||
}
|
||||
if ((j == 0) && (!TAILQ_EMPTY(&asoc->sent_queue)) && (asoc->sent_queue_retran_cnt == 0)) {
|
||||
if ((j == 0) &&
|
||||
(!TAILQ_EMPTY(&asoc->sent_queue)) &&
|
||||
(asoc->sent_queue_retran_cnt == 0) &&
|
||||
(done_once == 0)) {
|
||||
/* huh, this should not happen */
|
||||
#ifdef INVARIANTS
|
||||
panic("Flight size incorrect? fixing??");
|
||||
#else
|
||||
printf("Flight size incorrect? fixing??\n");
|
||||
if (sctp_anal_print == 0) {
|
||||
printf("Flight size incorrect sack-cumack:%x prev_last_ack:%x? fixing??",
|
||||
cum_ack, sav_cum_ack);
|
||||
sctp_print_fs_audit(asoc);
|
||||
}
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
net->flight_size = 0;
|
||||
}
|
||||
@ -5444,7 +5519,12 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
|
||||
asoc->sent_queue_retran_cnt++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (sctp_anal_print == 0) {
|
||||
printf("After audit, totalflight:%d retran count:%d\n",
|
||||
asoc->total_flight, asoc->sent_queue_retran_cnt);
|
||||
sctp_anal_print = 1;
|
||||
}
|
||||
done_once = 1;
|
||||
goto again;
|
||||
}
|
||||
#ifdef SCTP_SACK_RWND_LOGGING
|
||||
|
@ -78,7 +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)
|
||||
struct sctp_nets *net, int *abort_no_unlock)
|
||||
{
|
||||
struct sctp_init *init;
|
||||
struct mbuf *op_err;
|
||||
@ -103,12 +103,16 @@ 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);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
}
|
||||
if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
|
||||
/* Invalid length */
|
||||
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
|
||||
sctp_abort_association(inp, stcb, m, iphlen, sh, op_err);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
}
|
||||
/* validate parameters */
|
||||
@ -116,6 +120,8 @@ 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);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
}
|
||||
if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
|
||||
@ -128,12 +134,16 @@ 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);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
}
|
||||
if (init->num_outbound_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);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
}
|
||||
init_limit = offset + ntohs(cp->ch.chunk_length);
|
||||
@ -141,6 +151,8 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
init_limit)) {
|
||||
/* auth parameter(s) error... send abort */
|
||||
sctp_abort_association(inp, stcb, m, iphlen, sh, NULL);
|
||||
if (stcb)
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
}
|
||||
/* send an INIT-ACK w/cookie */
|
||||
@ -301,7 +313,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)
|
||||
struct sctp_nets *net, int *abort_no_unlock)
|
||||
{
|
||||
struct sctp_association *asoc;
|
||||
struct mbuf *op_err;
|
||||
@ -330,6 +342,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
|
||||
* same param back
|
||||
*/
|
||||
sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
|
||||
*abort_no_unlock = 1;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -352,6 +365,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
|
||||
#endif
|
||||
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
|
||||
NULL);
|
||||
*abort_no_unlock = 1;
|
||||
return (-1);
|
||||
}
|
||||
stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs,
|
||||
@ -410,6 +424,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
|
||||
}
|
||||
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
|
||||
sh, op_err);
|
||||
*abort_no_unlock = 1;
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
@ -910,7 +925,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)
|
||||
struct sctp_nets *net, int *abort_no_unlock)
|
||||
{
|
||||
struct sctp_init_ack *init_ack;
|
||||
int *state;
|
||||
@ -934,6 +949,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
|
||||
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
|
||||
op_err);
|
||||
*abort_no_unlock = 1;
|
||||
return (-1);
|
||||
}
|
||||
init_ack = &cp->init;
|
||||
@ -943,6 +959,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
|
||||
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
|
||||
op_err);
|
||||
*abort_no_unlock = 1;
|
||||
return (-1);
|
||||
}
|
||||
if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
|
||||
@ -950,6 +967,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
|
||||
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
|
||||
op_err);
|
||||
*abort_no_unlock = 1;
|
||||
return (-1);
|
||||
}
|
||||
if (init_ack->num_inbound_streams == 0) {
|
||||
@ -957,6 +975,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
|
||||
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
|
||||
op_err);
|
||||
*abort_no_unlock = 1;
|
||||
return (-1);
|
||||
}
|
||||
if (init_ack->num_outbound_streams == 0) {
|
||||
@ -964,6 +983,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
|
||||
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
|
||||
op_err);
|
||||
*abort_no_unlock = 1;
|
||||
return (-1);
|
||||
}
|
||||
/* process according to association state... */
|
||||
@ -985,8 +1005,8 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
|
||||
stcb, 0, (void *)stcb->asoc.primary_destination);
|
||||
}
|
||||
if (sctp_process_init_ack(m, iphlen, offset, sh, cp, stcb, net
|
||||
) < 0) {
|
||||
if (sctp_process_init_ack(m, iphlen, offset, sh, cp, stcb, net,
|
||||
abort_no_unlock) < 0) {
|
||||
/* error in parsing parameters */
|
||||
return (-1);
|
||||
}
|
||||
@ -1536,7 +1556,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sctp_association *asoc;
|
||||
uint32_t vrf;
|
||||
uint32_t vrf_id;
|
||||
int chk_length;
|
||||
int init_offset, initack_offset, initack_limit;
|
||||
int retval;
|
||||
@ -1544,7 +1564,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
uint32_t old_tag;
|
||||
uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
|
||||
|
||||
vrf = SCTP_DEFAULT_VRFID;
|
||||
vrf_id = inp->def_vrf_id;
|
||||
|
||||
/*
|
||||
* find and validate the INIT chunk in the cookie (peer's info) the
|
||||
@ -1607,7 +1627,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
* and popluate
|
||||
*/
|
||||
stcb = sctp_aloc_assoc(inp, init_src, 0, &error,
|
||||
ntohl(initack_cp->init.initiate_tag), vrf);
|
||||
ntohl(initack_cp->init.initiate_tag), vrf_id);
|
||||
if (stcb == NULL) {
|
||||
struct mbuf *op_err;
|
||||
|
||||
@ -3527,6 +3547,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
int num_chunks = 0; /* number of control chunks processed */
|
||||
int chk_length;
|
||||
int ret;
|
||||
int abort_no_unlock = 0;
|
||||
|
||||
/*
|
||||
* How big should this be, and should it be alloc'd? Lets try the
|
||||
@ -3829,7 +3850,10 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
return (NULL);
|
||||
}
|
||||
sctp_handle_init(m, iphlen, *offset, sh,
|
||||
(struct sctp_init_chunk *)ch, inp, stcb, *netp);
|
||||
(struct sctp_init_chunk *)ch, inp, stcb, *netp, &abort_no_unlock);
|
||||
if (abort_no_unlock)
|
||||
return (NULL);
|
||||
|
||||
*offset = length;
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
@ -3864,11 +3888,14 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
return (NULL);
|
||||
}
|
||||
ret = sctp_handle_init_ack(m, iphlen, *offset, sh,
|
||||
(struct sctp_init_ack_chunk *)ch, stcb, *netp);
|
||||
(struct sctp_init_ack_chunk *)ch, stcb, *netp, &abort_no_unlock);
|
||||
/*
|
||||
* Special case, I must call the output routine to
|
||||
* get the cookie echoed
|
||||
*/
|
||||
if (abort_no_unlock)
|
||||
return (NULL);
|
||||
|
||||
if ((stcb) && ret == 0)
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC);
|
||||
*offset = length;
|
||||
@ -4683,6 +4710,7 @@ sctp_input(i_pak, off)
|
||||
#endif
|
||||
struct mbuf *m;
|
||||
int iphlen;
|
||||
uint32_t vrf_id;
|
||||
uint8_t ecn_bits;
|
||||
struct ip *ip;
|
||||
struct sctphdr *sh;
|
||||
@ -4695,7 +4723,8 @@ sctp_input(i_pak, off)
|
||||
int refcount_up = 0;
|
||||
int length, mlen, offset;
|
||||
|
||||
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
mlen = SCTP_HEADER_LEN(i_pak);
|
||||
iphlen = off;
|
||||
m = SCTP_HEADER_TO_CHAIN(i_pak);
|
||||
net = NULL;
|
||||
@ -4767,7 +4796,7 @@ sctp_input(i_pak, off)
|
||||
|
||||
stcb = sctp_findassociation_addr(m, iphlen,
|
||||
offset - sizeof(*ch),
|
||||
sh, ch, &inp, &net);
|
||||
sh, ch, &inp, &net, vrf_id);
|
||||
if ((inp) && (stcb)) {
|
||||
sctp_send_packet_dropped(stcb, net, m, iphlen, 1);
|
||||
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR);
|
||||
@ -4779,11 +4808,8 @@ sctp_input(i_pak, off)
|
||||
goto bad;
|
||||
}
|
||||
sh->checksum = calc_check;
|
||||
} else {
|
||||
sctp_skip_csum_4:
|
||||
mlen = SCTP_HEADER_LEN(m);
|
||||
}
|
||||
|
||||
sctp_skip_csum_4:
|
||||
/* destination port of 0 is illegal, based on RFC2960. */
|
||||
if (sh->dest_port == 0) {
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
@ -4799,7 +4825,7 @@ sctp_input(i_pak, off)
|
||||
* IP/SCTP/first chunk header...
|
||||
*/
|
||||
stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch),
|
||||
sh, ch, &inp, &net);
|
||||
sh, ch, &inp, &net, vrf_id);
|
||||
/* inp's ref-count increased && stcb locked */
|
||||
if (inp == NULL) {
|
||||
struct sctp_init_chunk *init_chk, chunk_buf;
|
||||
|
@ -93,10 +93,8 @@ __FBSDID("$FreeBSD$");
|
||||
#endif /* INET6 */
|
||||
|
||||
|
||||
|
||||
#include <netinet/ip_options.h>
|
||||
|
||||
|
||||
#ifndef in6pcb
|
||||
#define in6pcb inpcb
|
||||
#endif
|
||||
@ -269,6 +267,12 @@ typedef struct callout sctp_os_timer_t;
|
||||
#define SCTP_SB_LIMIT_RCV(so) so->so_rcv.sb_hiwat
|
||||
#define SCTP_SB_LIMIT_SND(so) so->so_snd.sb_hiwat
|
||||
|
||||
/*
|
||||
* routes, output, etc.
|
||||
*/
|
||||
typedef struct route sctp_route_t;
|
||||
|
||||
|
||||
/*
|
||||
* SCTP AUTH
|
||||
*/
|
||||
|
@ -1991,7 +1991,7 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_scoping *scope,
|
||||
int cnt, limit_out = 0, total_count;
|
||||
uint32_t vrf_id;
|
||||
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
vrf_id = inp->def_vrf_id;
|
||||
SCTP_IPI_ADDR_LOCK();
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
@ -2403,7 +2403,7 @@ sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
|
||||
|
||||
static struct sctp_ifa *
|
||||
sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
|
||||
struct route *ro,
|
||||
sctp_route_t * ro,
|
||||
uint32_t vrf_id,
|
||||
int non_asoc_addr_ok,
|
||||
uint8_t dest_is_priv,
|
||||
@ -2414,7 +2414,7 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
|
||||
void *ifn;
|
||||
int resettotop = 0;
|
||||
struct sctp_ifn *sctp_ifn;
|
||||
struct sctp_ifa *sctp_ifa, *pass;
|
||||
struct sctp_ifa *sctp_ifa, *sifa;
|
||||
struct sctp_vrf *vrf;
|
||||
uint32_t ifn_index;
|
||||
|
||||
@ -2435,12 +2435,12 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
|
||||
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
|
||||
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
|
||||
continue;
|
||||
pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if (sctp_is_addr_in_ep(inp, pass)) {
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
if (sctp_is_addr_in_ep(inp, sifa)) {
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2461,11 +2461,11 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
|
||||
/* address has been removed */
|
||||
continue;
|
||||
}
|
||||
pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
if (resettotop == 0) {
|
||||
inp->next_addr_touse = NULL;
|
||||
@ -2484,11 +2484,11 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
|
||||
/* address has been removed */
|
||||
continue;
|
||||
}
|
||||
pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
if (resettotop == 0) {
|
||||
inp->next_addr_touse = NULL;
|
||||
@ -2507,7 +2507,7 @@ static struct sctp_ifa *
|
||||
sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
|
||||
struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net,
|
||||
struct route *ro,
|
||||
sctp_route_t * ro,
|
||||
uint32_t vrf_id,
|
||||
uint8_t dest_is_priv,
|
||||
uint8_t dest_is_loop,
|
||||
@ -2517,7 +2517,7 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
|
||||
struct sctp_laddr *laddr, *starting_point;
|
||||
void *ifn;
|
||||
struct sctp_ifn *sctp_ifn;
|
||||
struct sctp_ifa *sctp_ifa, *pass;
|
||||
struct sctp_ifa *sctp_ifa, *sifa;
|
||||
uint8_t start_at_beginning = 0;
|
||||
struct sctp_vrf *vrf;
|
||||
uint32_t ifn_index;
|
||||
@ -2540,21 +2540,21 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
|
||||
* acceptable.
|
||||
*/
|
||||
if (sctp_ifn) {
|
||||
/* first try for an prefered address on the ep */
|
||||
/* first try for a prefered address on the ep */
|
||||
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
|
||||
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
|
||||
continue;
|
||||
if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
|
||||
pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if ((non_asoc_addr_ok == 0) &&
|
||||
(sctp_is_addr_restricted(stcb, pass))) {
|
||||
(sctp_is_addr_restricted(stcb, sifa))) {
|
||||
/* on the no-no list */
|
||||
continue;
|
||||
}
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
}
|
||||
/* next try for an acceptable address on the ep */
|
||||
@ -2562,16 +2562,16 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
|
||||
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
|
||||
continue;
|
||||
if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
|
||||
pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if ((non_asoc_addr_ok == 0) &&
|
||||
(sctp_is_addr_restricted(stcb, pass))) {
|
||||
(sctp_is_addr_restricted(stcb, sifa))) {
|
||||
/* on the no-no list */
|
||||
continue;
|
||||
}
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2593,17 +2593,17 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
|
||||
/* address has been removed */
|
||||
continue;
|
||||
}
|
||||
pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if ((non_asoc_addr_ok == 0) &&
|
||||
(sctp_is_addr_restricted(stcb, pass))) {
|
||||
(sctp_is_addr_restricted(stcb, sifa))) {
|
||||
/* on the no-no list */
|
||||
continue;
|
||||
}
|
||||
stcb->asoc.last_used_address = laddr;
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
|
||||
}
|
||||
if (start_at_beginning == 0) {
|
||||
@ -2625,17 +2625,17 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
|
||||
/* address has been removed */
|
||||
continue;
|
||||
}
|
||||
pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if ((non_asoc_addr_ok == 0) &&
|
||||
(sctp_is_addr_restricted(stcb, pass))) {
|
||||
(sctp_is_addr_restricted(stcb, sifa))) {
|
||||
/* on the no-no list */
|
||||
continue;
|
||||
}
|
||||
stcb->asoc.last_used_address = laddr;
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
if (start_at_beginning == 0) {
|
||||
stcb->asoc.last_used_address = NULL;
|
||||
@ -2653,17 +2653,17 @@ sctp_select_nth_prefered_addr_from_ifn_boundall(struct sctp_ifn *ifn,
|
||||
int addr_wanted,
|
||||
sa_family_t fam)
|
||||
{
|
||||
struct sctp_ifa *ifa, *pass;
|
||||
struct sctp_ifa *ifa, *sifa;
|
||||
int num_eligible_addr = 0;
|
||||
|
||||
LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
|
||||
if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
|
||||
continue;
|
||||
pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if (stcb) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) {
|
||||
/*
|
||||
* It is restricted for some reason..
|
||||
* probably not yet added.
|
||||
@ -2672,7 +2672,7 @@ sctp_select_nth_prefered_addr_from_ifn_boundall(struct sctp_ifn *ifn,
|
||||
}
|
||||
}
|
||||
if (num_eligible_addr >= addr_wanted) {
|
||||
return (pass);
|
||||
return (sifa);
|
||||
}
|
||||
num_eligible_addr++;
|
||||
}
|
||||
@ -2688,19 +2688,19 @@ sctp_count_num_prefered_boundall(struct sctp_ifn *ifn,
|
||||
uint8_t dest_is_priv,
|
||||
sa_family_t fam)
|
||||
{
|
||||
struct sctp_ifa *ifa, *pass;
|
||||
struct sctp_ifa *ifa, *sifa;
|
||||
int num_eligible_addr = 0;
|
||||
|
||||
LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
|
||||
if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) {
|
||||
continue;
|
||||
}
|
||||
pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL) {
|
||||
sifa = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (stcb) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) {
|
||||
/*
|
||||
* It is restricted for some reason..
|
||||
* probably not yet added.
|
||||
@ -2717,7 +2717,7 @@ static struct sctp_ifa *
|
||||
sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net,
|
||||
struct route *ro,
|
||||
sctp_route_t * ro,
|
||||
uint32_t vrf_id,
|
||||
uint8_t dest_is_priv,
|
||||
uint8_t dest_is_loop,
|
||||
@ -2727,7 +2727,7 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
int cur_addr_num = 0, num_prefered = 0;
|
||||
void *ifn;
|
||||
struct sctp_ifn *sctp_ifn, *looked_at = NULL, *emit_ifn;
|
||||
struct sctp_ifa *sctp_ifa, *pass;
|
||||
struct sctp_ifa *sctp_ifa, *sifa;
|
||||
uint32_t ifn_index;
|
||||
struct sctp_vrf *vrf;
|
||||
|
||||
@ -2854,9 +2854,9 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
if (cur_addr_num >= num_prefered) {
|
||||
cur_addr_num = 0;
|
||||
}
|
||||
pass = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
|
||||
sifa = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
|
||||
dest_is_priv, cur_addr_num, fam);
|
||||
if (pass == NULL)
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if (net) {
|
||||
net->indx_of_eligible_next_to_use = cur_addr_num + 1;
|
||||
@ -2864,14 +2864,14 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
|
||||
printf("we selected %d\n", cur_addr_num);
|
||||
printf("Source:");
|
||||
sctp_print_address(&pass->address.sa);
|
||||
sctp_print_address(&sifa->address.sa);
|
||||
printf("Dest:");
|
||||
sctp_print_address(&net->ro._l_addr.sa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
|
||||
}
|
||||
|
||||
@ -2888,11 +2888,11 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) {
|
||||
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
|
||||
continue;
|
||||
pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if (stcb) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) {
|
||||
/*
|
||||
* It is restricted for some reason..
|
||||
* probably not yet added.
|
||||
@ -2900,8 +2900,8 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2927,11 +2927,11 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
|
||||
if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
|
||||
continue;
|
||||
pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (pass == NULL)
|
||||
sifa = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
|
||||
if (sifa == NULL)
|
||||
continue;
|
||||
if (stcb) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
|
||||
if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) {
|
||||
/*
|
||||
* It is restricted for some
|
||||
* reason.. probably not yet added.
|
||||
@ -2939,8 +2939,8 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
atomic_add_int(&pass->refcount, 1);
|
||||
return (pass);
|
||||
atomic_add_int(&sifa->refcount, 1);
|
||||
return (sifa);
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -2957,7 +2957,7 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
struct sctp_ifa *
|
||||
sctp_source_address_selection(struct sctp_inpcb *inp,
|
||||
struct sctp_tcb *stcb,
|
||||
struct route *ro,
|
||||
sctp_route_t * ro,
|
||||
struct sctp_nets *net,
|
||||
int non_asoc_addr_ok, uint32_t vrf_id)
|
||||
{
|
||||
@ -3398,7 +3398,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
int ret;
|
||||
unsigned int have_mtu;
|
||||
uint32_t vrf_id;
|
||||
struct route *ro;
|
||||
sctp_route_t *ro;
|
||||
|
||||
|
||||
if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) {
|
||||
@ -3406,7 +3406,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
return (EFAULT);
|
||||
}
|
||||
if (stcb == NULL) {
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
vrf_id = inp->def_vrf_id;
|
||||
} else {
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
}
|
||||
@ -3436,7 +3436,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
|
||||
if (to->sa_family == AF_INET) {
|
||||
struct ip *ip = NULL;
|
||||
struct route iproute;
|
||||
sctp_route_t iproute;
|
||||
uint8_t tos_value;
|
||||
|
||||
o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip));
|
||||
@ -3491,7 +3491,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
memset(&iproute, 0, sizeof(iproute));
|
||||
memcpy(&ro->ro_dst, to, to->sa_len);
|
||||
} else {
|
||||
ro = (struct route *)&net->ro;
|
||||
ro = (sctp_route_t *) & net->ro;
|
||||
}
|
||||
/* Now the address selection part */
|
||||
ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
|
||||
@ -3694,10 +3694,10 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
return (EINVAL);
|
||||
if (net == NULL) {
|
||||
memset(&ip6route, 0, sizeof(ip6route));
|
||||
ro = (struct route *)&ip6route;
|
||||
ro = (sctp_route_t *) & ip6route;
|
||||
memcpy(&ro->ro_dst, sin6, sin6->sin6_len);
|
||||
} else {
|
||||
ro = (struct route *)&net->ro;
|
||||
ro = (sctp_route_t *) & net->ro;
|
||||
}
|
||||
if (stcb != NULL) {
|
||||
if ((stcb->asoc.ecn_allowed) && ecn_ok) {
|
||||
@ -4100,7 +4100,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
/*
|
||||
* To optimize this we could put the scoping stuff into a
|
||||
* structure and remove the individual uint8's from the
|
||||
* assoc structure. Then we could just pass in the address
|
||||
* assoc structure. Then we could just sifa in the address
|
||||
* within the stcb.. but for now this is a quick hack to get
|
||||
* the address stuff teased apart.
|
||||
*/
|
||||
@ -4124,7 +4124,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
}
|
||||
initm->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr)));
|
||||
/*
|
||||
* We pass 0 here to NOT set IP_DF if its IPv4, we ignore the return
|
||||
* We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return
|
||||
* here since the timer will drive a retranmission.
|
||||
*/
|
||||
|
||||
@ -4523,7 +4523,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
struct sockaddr_storage store;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct route *ro;
|
||||
sctp_route_t *ro;
|
||||
struct ip *iph;
|
||||
struct ip6_hdr *ip6;
|
||||
struct sockaddr *to;
|
||||
@ -4536,10 +4536,11 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
int p_len;
|
||||
uint32_t vrf_id;
|
||||
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
if (stcb) {
|
||||
asoc = &stcb->asoc;
|
||||
vrf_id = asoc->vrf_id;
|
||||
} else {
|
||||
vrf_id = inp->def_vrf_id;
|
||||
asoc = NULL;
|
||||
}
|
||||
m_last = NULL;
|
||||
@ -4631,7 +4632,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
iph = mtod(init_pkt, struct ip *);
|
||||
if (iph->ip_v == IPVERSION) {
|
||||
struct sctp_ifa *addr;
|
||||
struct route iproute;
|
||||
sctp_route_t iproute;
|
||||
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(struct sockaddr_in);
|
||||
@ -4733,7 +4734,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
/* local from address */
|
||||
memset(&iproute6, 0, sizeof(iproute6));
|
||||
ro = (struct route *)&iproute6;
|
||||
ro = (sctp_route_t *) & iproute6;
|
||||
memcpy(&ro->ro_dst, sin6, sizeof(*sin6));
|
||||
addr = sctp_source_address_selection(inp, NULL,
|
||||
ro, NULL, 0, vrf_id);
|
||||
@ -4782,7 +4783,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* did the selection.
|
||||
*/
|
||||
net->ro._s_addr = sctp_source_address_selection(inp,
|
||||
stcb, (struct route *)&net->ro,
|
||||
stcb, (sctp_route_t *) & net->ro,
|
||||
net, 0, vrf_id);
|
||||
if (net->ro._s_addr == NULL)
|
||||
return;
|
||||
@ -4806,7 +4807,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* did the selection.
|
||||
*/
|
||||
net->ro._s_addr = sctp_source_address_selection(inp,
|
||||
stcb, (struct route *)&net->ro,
|
||||
stcb, (sctp_route_t *) & net->ro,
|
||||
net, 0, vrf_id);
|
||||
if (net->ro._s_addr == NULL)
|
||||
return;
|
||||
@ -4999,7 +5000,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/*
|
||||
* To optimize this we could put the scoping stuff into a
|
||||
* structure and remove the individual uint8's from the stc
|
||||
* structure. Then we could just pass in the address within
|
||||
* structure. Then we could just sifa in the address within
|
||||
* the stc.. but for now this is a quick hack to get the
|
||||
* address stuff teased apart.
|
||||
*/
|
||||
@ -5093,7 +5094,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
|
||||
/*
|
||||
* We pass 0 here to NOT set IP_DF if its IPv4, we ignore the return
|
||||
* We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return
|
||||
* here since the timer will drive a retranmission.
|
||||
*/
|
||||
padval = p_len % 4;
|
||||
@ -5420,7 +5421,7 @@ sctp_msg_append(struct sctp_tcb *stcb,
|
||||
at = m;
|
||||
sctp_set_prsctp_policy(stcb, sp);
|
||||
/*
|
||||
* We could in theory (for sendall) pass the length in, but we would
|
||||
* We could in theory (for sendall) sifa the length in, but we would
|
||||
* still have to hunt through the chain since we need to setup the
|
||||
* tail_mbuf
|
||||
*/
|
||||
@ -9269,7 +9270,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh)
|
||||
comp_cp->sh.checksum = sctp_calculate_sum(mout, NULL, offset_out);
|
||||
}
|
||||
if (iph_out != NULL) {
|
||||
struct route ro;
|
||||
sctp_route_t ro;
|
||||
|
||||
bzero(&ro, sizeof ro);
|
||||
/* set IPv4 length */
|
||||
@ -10121,7 +10122,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
|
||||
abm->sh.checksum = sctp_calculate_sum(mout, NULL, iphlen_out);
|
||||
}
|
||||
if (iph_out != NULL) {
|
||||
struct route ro;
|
||||
sctp_route_t ro;
|
||||
|
||||
/* zap the stack pointer to the route */
|
||||
bzero(&ro, sizeof ro);
|
||||
@ -10226,7 +10227,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
|
||||
if (iph->ip_v == IPVERSION) {
|
||||
/* V4 */
|
||||
struct ip *out;
|
||||
struct route ro;
|
||||
sctp_route_t ro;
|
||||
|
||||
o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip));
|
||||
if (o_pak == NULL) {
|
||||
@ -10538,8 +10539,12 @@ sctp_sosend(struct socket *so,
|
||||
use_rcvinfo = 1;
|
||||
}
|
||||
}
|
||||
error = sctp_lower_sosend(so, addr, uio, top, control, flags,
|
||||
use_rcvinfo, &srcv, p);
|
||||
error = sctp_lower_sosend(so, addr, uio, top,
|
||||
control,
|
||||
flags,
|
||||
use_rcvinfo, &srcv
|
||||
,p
|
||||
);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -10711,7 +10716,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
* UDP style, we must go ahead and start the INIT
|
||||
* process
|
||||
*/
|
||||
uint32_t vrf;
|
||||
uint32_t vrf_id;
|
||||
|
||||
if ((use_rcvinfo) && (srcv) &&
|
||||
((srcv->sinfo_flags & SCTP_ABORT) ||
|
||||
@ -10725,8 +10730,9 @@ sctp_lower_sosend(struct socket *so,
|
||||
goto out_unlocked;
|
||||
}
|
||||
/* get an asoc/stcb struct */
|
||||
vrf = SCTP_DEFAULT_VRFID;
|
||||
stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf);
|
||||
|
||||
vrf_id = inp->def_vrf_id;
|
||||
stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id);
|
||||
if (stcb == NULL) {
|
||||
/* Error is setup for us in the call */
|
||||
goto out_unlocked;
|
||||
|
@ -71,7 +71,7 @@ int
|
||||
struct sctp_ifa *
|
||||
sctp_source_address_selection(struct sctp_inpcb *inp,
|
||||
struct sctp_tcb *stcb,
|
||||
struct route *ro, struct sctp_nets *net,
|
||||
sctp_route_t * ro, struct sctp_nets *net,
|
||||
int non_asoc_addr_ok, uint32_t vrf_id);
|
||||
|
||||
|
||||
|
@ -207,6 +207,7 @@ sctp_find_vrf(uint32_t vrfid)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sctp_free_ifa(struct sctp_ifa *sctp_ifap)
|
||||
{
|
||||
@ -215,6 +216,17 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap)
|
||||
ret = atomic_fetchadd_int(&sctp_ifap->refcount, -1);
|
||||
if (ret == 1) {
|
||||
/* We zero'd the count */
|
||||
#ifdef INVARIANTS
|
||||
if (sctp_ifap->in_ifa_list) {
|
||||
panic("Attempt to free item in a list");
|
||||
}
|
||||
#else
|
||||
if (sctp_ifap->in_ifa_list) {
|
||||
printf("in_ifa_list was not clear, fixing cnt\n");
|
||||
atomic_add_int(&sctp_ifap->refcount, 1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
SCTP_FREE(sctp_ifap);
|
||||
}
|
||||
}
|
||||
@ -349,6 +361,7 @@ sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index,
|
||||
sctp_ifap->refcount = 1;
|
||||
LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
|
||||
sctp_ifnp->ifa_count++;
|
||||
sctp_ifap->in_ifa_list = 1;
|
||||
vrf->total_ifa_count++;
|
||||
SCTP_IPI_ADDR_UNLOCK();
|
||||
return (sctp_ifap);
|
||||
@ -383,6 +396,7 @@ sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr,
|
||||
vrf->total_ifa_count--;
|
||||
LIST_REMOVE(sctp_ifap, next_bucket);
|
||||
LIST_REMOVE(sctp_ifap, next_ifa);
|
||||
sctp_ifap->in_ifa_list = 0;
|
||||
atomic_add_int(&sctp_ifnp->refcount, -1);
|
||||
} else {
|
||||
printf("Del Addr-ifn:%d Could not find address:",
|
||||
@ -412,7 +426,7 @@ sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr,
|
||||
|
||||
static struct sctp_tcb *
|
||||
sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
|
||||
struct sockaddr *to, struct sctp_nets **netp)
|
||||
struct sockaddr *to, struct sctp_nets **netp, uint32_t vrf_id)
|
||||
{
|
||||
/**** ASSUMSES THE CALLER holds the INP_INFO_RLOCK */
|
||||
|
||||
@ -462,6 +476,10 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
if (inp->def_vrf_id == vrf_id) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
/* check to see if the ep has one of the addresses */
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
|
||||
/* We are NOT bound all, so look further */
|
||||
@ -599,7 +617,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
|
||||
{
|
||||
struct sctpasochead *head;
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_tcb *stcb;
|
||||
struct sctp_tcb *stcb = NULL;
|
||||
struct sctp_nets *net;
|
||||
uint16_t rport;
|
||||
|
||||
@ -620,7 +638,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
|
||||
}
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
|
||||
/*
|
||||
/*-
|
||||
* Now either this guy is our listener or it's the
|
||||
* connector. If it is the one that issued the connect, then
|
||||
* it's only chance is to be the first TCB in the list. If
|
||||
@ -630,7 +648,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
|
||||
if ((inp->sctp_socket) && (inp->sctp_socket->so_qlimit)) {
|
||||
/* to is peer addr, from is my addr */
|
||||
stcb = sctp_tcb_special_locate(inp_p, remote, local,
|
||||
netp);
|
||||
netp, inp->def_vrf_id);
|
||||
if ((stcb != NULL) && (locked_tcb == NULL)) {
|
||||
/* we have a locked tcb, lower refcount */
|
||||
SCTP_INP_WLOCK(inp);
|
||||
@ -1131,9 +1149,9 @@ sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from,
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
if (find_tcp_pool) {
|
||||
if (inp_p != NULL) {
|
||||
retval = sctp_tcb_special_locate(inp_p, from, to, netp);
|
||||
retval = sctp_tcb_special_locate(inp_p, from, to, netp, vrf_id);
|
||||
} else {
|
||||
retval = sctp_tcb_special_locate(&inp, from, to, netp);
|
||||
retval = sctp_tcb_special_locate(&inp, from, to, netp, vrf_id);
|
||||
}
|
||||
if (retval != NULL) {
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
@ -1331,7 +1349,7 @@ sctp_findassoc_by_vtag(struct sockaddr *from, uint32_t vtag,
|
||||
struct sctp_tcb *
|
||||
sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
|
||||
struct sctphdr *sh, struct sctp_chunkhdr *ch,
|
||||
struct sctp_inpcb **inp_p, struct sctp_nets **netp)
|
||||
struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
|
||||
{
|
||||
int find_tcp_pool;
|
||||
struct ip *iph;
|
||||
@ -1340,9 +1358,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
|
||||
struct sockaddr *to = (struct sockaddr *)&to_store;
|
||||
struct sockaddr *from = (struct sockaddr *)&from_store;
|
||||
struct sctp_inpcb *inp;
|
||||
uint32_t vrf_id;
|
||||
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
iph = mtod(m, struct ip *);
|
||||
if (iph->ip_v == IPVERSION) {
|
||||
/* its IPv4 */
|
||||
@ -1871,6 +1887,7 @@ sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
|
||||
SCTP_INCR_LADDR_COUNT();
|
||||
bzero(laddr, sizeof(*laddr));
|
||||
laddr->ifa = oladdr->ifa;
|
||||
atomic_add_int(&laddr->ifa->refcount, 1);
|
||||
LIST_INSERT_HEAD(&new_inp->sctp_addr_list, laddr,
|
||||
sctp_nxt_addr);
|
||||
new_inp->laddr_count++;
|
||||
@ -2371,6 +2388,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
|
||||
struct sctp_queued_to_read *sq;
|
||||
|
||||
|
||||
int cnt;
|
||||
sctp_sharedkey_t *shared_key;
|
||||
|
||||
@ -2819,6 +2837,7 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
|
||||
net->ssthresh = stcb->asoc.peers_rwnd;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
int set_scope, int from)
|
||||
@ -2999,6 +3018,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
sin6->sin6_scope_id = 0;
|
||||
}
|
||||
rtalloc_ign((struct route *)&net->ro, 0UL);
|
||||
|
||||
if (newaddr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
@ -3070,15 +3090,13 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
netlook = TAILQ_NEXT(netfirst, sctp_next);
|
||||
if (netlook == NULL) {
|
||||
/* End of the list */
|
||||
TAILQ_INSERT_TAIL(&stcb->asoc.nets, net,
|
||||
sctp_next);
|
||||
TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
|
||||
break;
|
||||
} else if (netlook->ro.ro_rt == NULL) {
|
||||
/* next one has NO route */
|
||||
TAILQ_INSERT_BEFORE(netfirst, net, sctp_next);
|
||||
break;
|
||||
} else if (netlook->ro.ro_rt->rt_ifp !=
|
||||
net->ro.ro_rt->rt_ifp) {
|
||||
} else if (netlook->ro.ro_rt->rt_ifp != net->ro.ro_rt->rt_ifp) {
|
||||
TAILQ_INSERT_AFTER(&stcb->asoc.nets, netlook,
|
||||
net, sctp_next);
|
||||
break;
|
||||
@ -3268,6 +3286,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
SCTP_DECR_ASOC_COUNT();
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
*error = ENOBUFS;
|
||||
return (NULL);
|
||||
}
|
||||
@ -3458,6 +3477,7 @@ sctp_iterator_asoc_being_freed(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free the association after un-hashing the remote port.
|
||||
*/
|
||||
@ -5392,7 +5412,8 @@ sctp_drain()
|
||||
* flags and asoc_state. "af" (mandatory) is executed for all matching
|
||||
* assocs and "ef" (optional) is executed when the iterator completes.
|
||||
* "inpf" (optional) is executed for each new endpoint as it is being
|
||||
* iterated through.
|
||||
* iterated through. inpe (optional) is called when the inp completes
|
||||
* its way through all the stcbs.
|
||||
*/
|
||||
int
|
||||
sctp_initiate_iterator(inp_func inpf,
|
||||
|
@ -53,7 +53,6 @@ TAILQ_HEAD(sctp_streamhead, sctp_stream_queue_pending);
|
||||
#include <netinet/sctp_structs.h>
|
||||
#include <netinet/sctp_uio.h>
|
||||
#include <netinet/sctp_auth.h>
|
||||
#include <netinet/sctp_bsd_addr.h>
|
||||
|
||||
/*
|
||||
* PCB flags (in sctp_flags bitmask)
|
||||
@ -158,7 +157,7 @@ struct sctp_ifa {
|
||||
uint8_t src_is_loop;
|
||||
uint8_t src_is_priv;
|
||||
uint8_t src_is_glob;
|
||||
uint8_t resv;
|
||||
uint8_t in_ifa_list;
|
||||
};
|
||||
|
||||
struct sctp_laddr {
|
||||
@ -477,7 +476,7 @@ int sctp_inpcb_bind(struct socket *, struct sockaddr *, struct thread *);
|
||||
struct sctp_tcb *
|
||||
sctp_findassociation_addr(struct mbuf *, int, int,
|
||||
struct sctphdr *, struct sctp_chunkhdr *, struct sctp_inpcb **,
|
||||
struct sctp_nets **);
|
||||
struct sctp_nets **, uint32_t vrf_id);
|
||||
|
||||
struct sctp_tcb *
|
||||
sctp_findassociation_addr_sa(struct sockaddr *,
|
||||
|
@ -91,7 +91,7 @@ uint32_t sctp_chunkscale = SCTP_CHUNKQUEUE_SCALE;
|
||||
|
||||
uint32_t sctp_cmt_on_off = 0;
|
||||
uint32_t sctp_cmt_use_dac = 0;
|
||||
uint32_t sctp_max_retran_chunk = SCTPCTL_MAX_RETRAN_DEFAULT;
|
||||
uint32_t sctp_max_retran_chunk = SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT;
|
||||
|
||||
|
||||
uint32_t sctp_L2_abc_variable = 1;
|
||||
@ -486,18 +486,6 @@ SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_data_order, CTLFLAG_RW,
|
||||
&sctp_strict_data_order, 0,
|
||||
"Enforce strict data ordering, abort if control inside data");
|
||||
|
||||
SYSCTL_INT(_net_inet_sctp, OID_AUTO, min_residual, CTLFLAG_RW,
|
||||
&sctp_min_residual, 0,
|
||||
SCTPCTL_MIN_RESIDUAL_DESC);
|
||||
|
||||
|
||||
SYSCTL_INT(_net_inet_sctp, OID_AUTO, max_retran_chunk, CTLFLAG_RW,
|
||||
&sctp_max_retran_chunk, 0,
|
||||
SCTPCTL_MAX_RETRAN_DESC);
|
||||
|
||||
|
||||
|
||||
|
||||
SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
|
||||
&sctpstat, sctpstat,
|
||||
"SCTP statistics (struct sctps_stat, netinet/sctp.h");
|
||||
@ -506,6 +494,14 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,
|
||||
0, 0, sctp_assoclist,
|
||||
"S,xassoc", "List of active SCTP associations");
|
||||
|
||||
SYSCTL_INT(_net_inet_sctp, OID_AUTO, min_residual, CTLFLAG_RW,
|
||||
&sctp_min_residual, 0,
|
||||
SCTPCTL_MIN_RESIDUAL_DESC);
|
||||
|
||||
SYSCTL_INT(_net_inet_sctp, OID_AUTO, max_retran_chunk, CTLFLAG_RW,
|
||||
&sctp_max_retran_chunk, 0,
|
||||
SCTPCTL_MAX_RETRAN_CHUNK_DESC);
|
||||
|
||||
#ifdef SCTP_DEBUG
|
||||
SYSCTL_INT(_net_inet_sctp, OID_AUTO, debug, CTLFLAG_RW,
|
||||
&sctp_debug_on, 0, "Configure debug output");
|
||||
|
@ -376,20 +376,19 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTPCTL_STRICT_DATA_ORDER_MAX 1
|
||||
#define SCTPCTL_STRICT_DATA_ORDER_DEFAULT 0
|
||||
|
||||
/* min residual in in a data fragment leftover */
|
||||
/* min_residual: min residual in a data fragment leftover */
|
||||
#define SCTPCTL_MIN_REDIDUAL 49
|
||||
#define SCTPCTL_MIN_RESIDUAL_DESC "Minimum residual data chunk in second part of split"
|
||||
#define SCTPCTL_MIN_RESIDUAL_MIN 20
|
||||
#define SCTPCTL_MIN_RESIDUAL_MAX 65535
|
||||
#define SCTPCTL_MIN_RESIDUAL_DEFAULT 1452
|
||||
|
||||
/* min residual in in a data fragment leftover */
|
||||
#define SCTPCTL_MAX_RETRAN 50
|
||||
#define SCTPCTL_MAX_RETRAN_DESC "Maximum times a unlucky chunk can be retran'd before assoc abort "
|
||||
#define SCTPCTL_MAX_RETRAN_MIN 0
|
||||
#define SCTPCTL_MAX_RETRAN_MAX 65535
|
||||
#define SCTPCTL_MAX_RETRAN_DEFAULT 30
|
||||
|
||||
/* max_retran_chunk: max chunk retransmissions */
|
||||
#define SCTPCTL_MAX_RETRAN_CHUNK 50
|
||||
#define SCTPCTL_MAX_RETRAN_CHUNK_DESC "Maximum times an unlucky chunk can be retran'd before assoc abort"
|
||||
#define SCTPCTL_MAX_RETRAN_CHUNK_MIN 0
|
||||
#define SCTPCTL_MAX_RETRAN_CHUNK_MAX 65535
|
||||
#define SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT 30
|
||||
|
||||
|
||||
#ifdef SCTP_DEBUG
|
||||
@ -516,8 +515,8 @@ __FBSDID("$FreeBSD$");
|
||||
{ "add_more_on_output", CTLTYPE_INT }, \
|
||||
{ "sys_resource", CTLTYPE_INT }, \
|
||||
{ "asoc_resource", CTLTYPE_INT }, \
|
||||
{ "max_retran_chunk", CTLTYPE_INT }, \
|
||||
{ "min_residual", CTLTYPE_INT }, \
|
||||
{ "max_retran_chunk", CTLTYPE_INT }, \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -200,6 +200,7 @@ sctp_audit_retranmission_queue(struct sctp_association *asoc)
|
||||
#endif /* SCTP_DEBUG */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net, uint16_t threshold)
|
||||
@ -360,6 +361,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
(void)sa6_embedscope(sin6, ip6_use_defzone);
|
||||
}
|
||||
rtalloc_ign((struct route *)&alt->ro, 0UL);
|
||||
|
||||
if (sin6->sin6_family == AF_INET6) {
|
||||
(void)sa6_recoverscope(sin6);
|
||||
}
|
||||
|
@ -966,6 +966,7 @@ int
|
||||
sctp_lower_sosend(struct socket *so,
|
||||
struct sockaddr *addr,
|
||||
struct uio *uio,
|
||||
|
||||
struct mbuf *top,
|
||||
struct mbuf *control,
|
||||
int flags,
|
||||
|
@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
#include <netinet/sctp_sysctl.h>
|
||||
#include <netinet/sctp_output.h>
|
||||
#include <netinet/sctp_bsd_addr.h>
|
||||
#include <netinet/sctp_uio.h>
|
||||
#include <netinet/sctp_asconf.h>
|
||||
#include <netinet/sctputil.h>
|
||||
@ -302,6 +301,7 @@ sctp_ctlinput(cmd, sa, vip)
|
||||
struct sctphdr *sh;
|
||||
uint32_t vrf_id;
|
||||
|
||||
/* FIX, for non-bsd is this right? */
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
if (sa->sa_family != AF_INET ||
|
||||
((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
|
||||
@ -375,7 +375,10 @@ sctp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
int error;
|
||||
uint32_t vrf_id;
|
||||
|
||||
|
||||
/* FIX, for non-bsd is this right? */
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
|
||||
/*
|
||||
* XXXRW: Other instances of getcred use SUSER_ALLOWJAIL, as socket
|
||||
* visibility is scoped using cr_canseesocket(), which it is not
|
||||
@ -847,6 +850,7 @@ sctp_disconnect(struct socket *so)
|
||||
return (0);
|
||||
}
|
||||
/* not reached */
|
||||
printf("Not reached reached?\n");
|
||||
} else {
|
||||
/* UDP model does not support this */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
@ -889,6 +893,7 @@ sctp_shutdown(struct socket *so)
|
||||
* made after an abort or something. Nothing to do
|
||||
* now.
|
||||
*/
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
return (0);
|
||||
}
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
@ -1336,15 +1341,11 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
|
||||
SCTP_PCB_FLAGS_UNBOUND) {
|
||||
/* Bind a ephemeral port */
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
error = sctp_inpcb_bind(so, NULL, p);
|
||||
if (error) {
|
||||
goto out_now;
|
||||
}
|
||||
} else {
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
|
||||
/* FIX ME: do we want to pass in a vrf on the connect call? */
|
||||
vrf_id = inp->def_vrf_id;
|
||||
|
||||
@ -2251,6 +2252,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
if (hmaclist == NULL) {
|
||||
/* no HMACs to return */
|
||||
*optsize = sizeof(*shmac);
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
break;
|
||||
}
|
||||
/* is there room for all of the hmac ids? */
|
||||
@ -2382,7 +2384,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
printf("inp is NULL?\n");
|
||||
return EINVAL;
|
||||
}
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
vrf_id = inp->def_vrf_id;
|
||||
|
||||
error = 0;
|
||||
switch (optname) {
|
||||
@ -3555,8 +3557,6 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
|
||||
SCTP_INP_RLOCK(inp);
|
||||
stcb = LIST_FIRST(&inp->sctp_asoc_list);
|
||||
if (stcb)
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
} else {
|
||||
/*
|
||||
@ -3568,6 +3568,8 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
|
||||
if (stcb == NULL) {
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
} else {
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
}
|
||||
}
|
||||
if (stcb != NULL) {
|
||||
@ -3575,7 +3577,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
error = EALREADY;
|
||||
goto out_now;
|
||||
}
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
vrf_id = inp->def_vrf_id;
|
||||
/* We are GOOD to go */
|
||||
stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id);
|
||||
if (stcb == NULL) {
|
||||
@ -3594,12 +3596,11 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
sctp_initialize_auth_params(inp, stcb);
|
||||
|
||||
sctp_send_initiate(inp, stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
out_now:
|
||||
if (create_lock_on)
|
||||
SCTP_ASOC_CREATE_UNLOCK(inp);
|
||||
|
||||
if (stcb)
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
return error;
|
||||
}
|
||||
@ -3686,6 +3687,7 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
|
||||
}
|
||||
SCTP_INP_RLOCK(inp);
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
if (so->so_state & SS_ISDISCONNECTED) {
|
||||
@ -3808,11 +3810,10 @@ sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
goto notConn;
|
||||
}
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
|
||||
vrf_id = inp->def_vrf_id;
|
||||
sctp_ifa = sctp_source_address_selection(inp,
|
||||
stcb,
|
||||
(struct route *)&net->ro,
|
||||
(sctp_route_t *) & net->ro,
|
||||
net, 0, vrf_id);
|
||||
if (sctp_ifa) {
|
||||
sin->sin_addr = sctp_ifa->address.sin.sin_addr;
|
||||
|
@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/sctp_indata.h>/* for sctp_deliver_data() */
|
||||
#include <netinet/sctp_auth.h>
|
||||
#include <netinet/sctp_asconf.h>
|
||||
#include <netinet/sctp_bsd_addr.h>
|
||||
|
||||
#define NUMBER_OF_MTU_SIZES 18
|
||||
|
||||
@ -3708,7 +3707,7 @@ sctp_print_address(struct sockaddr *sa)
|
||||
char ip6buf[INET6_ADDRSTRLEN];
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)sa;
|
||||
printf("IPv6 address: %s:%d scope:%u\n",
|
||||
printf("IPv6 address: %s:port:%d scope:%u\n",
|
||||
ip6_sprintf(ip6buf, &sin6->sin6_addr),
|
||||
ntohs(sin6->sin6_port),
|
||||
sin6->sin6_scope_id);
|
||||
@ -3780,7 +3779,7 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
|
||||
struct sctp_queued_to_read *control, *nctl;
|
||||
struct sctp_readhead tmp_queue;
|
||||
struct mbuf *m;
|
||||
int error;
|
||||
int error = 0;
|
||||
|
||||
old_so = old_inp->sctp_socket;
|
||||
new_so = new_inp->sctp_socket;
|
||||
@ -4291,16 +4290,33 @@ sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
|
||||
struct sctp_ifalist *hash_head;
|
||||
uint32_t hash_of_addr;
|
||||
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL)
|
||||
return (NULL);
|
||||
|
||||
hash_of_addr = sctp_get_ifa_hash_val(addr);
|
||||
if (holds_lock == 0)
|
||||
SCTP_IPI_ADDR_LOCK();
|
||||
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
if (holds_lock == 0)
|
||||
SCTP_IPI_ADDR_UNLOCK();
|
||||
return (NULL);
|
||||
}
|
||||
hash_of_addr = sctp_get_ifa_hash_val(addr);
|
||||
|
||||
hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_hashmark)];
|
||||
if (hash_head == NULL) {
|
||||
printf("hash_of_addr:%x mask:%x table:%x - ",
|
||||
(u_int)hash_of_addr, (u_int)vrf->vrf_hashmark,
|
||||
(u_int)(hash_of_addr & vrf->vrf_hashmark));
|
||||
sctp_print_address(addr);
|
||||
printf("No such bucket for address\n");
|
||||
if (holds_lock == 0)
|
||||
SCTP_IPI_ADDR_UNLOCK();
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
LIST_FOREACH(sctp_ifap, hash_head, next_bucket) {
|
||||
if (sctp_ifap == NULL) {
|
||||
panic("Huh LIST_FOREACH corrupt");
|
||||
}
|
||||
if (addr->sa_family != sctp_ifap->address.sa.sa_family)
|
||||
continue;
|
||||
if (addr->sa_family == AF_INET) {
|
||||
|
@ -59,9 +59,7 @@ int
|
||||
sctp6_input(mp, offp, proto)
|
||||
struct mbuf **mp;
|
||||
int *offp;
|
||||
|
||||
int proto;
|
||||
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct ip6_hdr *ip6;
|
||||
@ -69,14 +67,15 @@ sctp6_input(mp, offp, proto)
|
||||
struct sctp_inpcb *in6p = NULL;
|
||||
struct sctp_nets *net;
|
||||
int refcount_up = 0;
|
||||
u_int32_t check, calc_check;
|
||||
uint32_t check, calc_check, vrf_id;
|
||||
struct inpcb *in6p_ip;
|
||||
struct sctp_chunkhdr *ch;
|
||||
int length, mlen, offset, iphlen;
|
||||
u_int8_t ecn_bits;
|
||||
uint8_t ecn_bits;
|
||||
struct sctp_tcb *stcb = NULL;
|
||||
int off = *offp;
|
||||
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
m = SCTP_HEADER_TO_CHAIN(*mp);
|
||||
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
@ -138,7 +137,7 @@ sctp6_input(mp, offp, proto)
|
||||
}
|
||||
#endif
|
||||
stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch),
|
||||
sh, ch, &in6p, &net);
|
||||
sh, ch, &in6p, &net, vrf_id);
|
||||
/* in6p's ref-count increased && stcb locked */
|
||||
if ((in6p) && (stcb)) {
|
||||
sctp_send_packet_dropped(stcb, net, m, iphlen, 1);
|
||||
@ -159,7 +158,7 @@ sctp6_input(mp, offp, proto)
|
||||
* IP/SCTP/first chunk header...
|
||||
*/
|
||||
stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch),
|
||||
sh, ch, &in6p, &net);
|
||||
sh, ch, &in6p, &net, vrf_id);
|
||||
/* in6p's ref-count increased */
|
||||
if (in6p == NULL) {
|
||||
struct sctp_init_chunk *init_chk, chunk_buf;
|
||||
@ -173,7 +172,7 @@ sctp6_input(mp, offp, proto)
|
||||
*/
|
||||
init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
|
||||
iphlen + sizeof(*sh), sizeof(*init_chk),
|
||||
(u_int8_t *) & chunk_buf);
|
||||
(uint8_t *) & chunk_buf);
|
||||
sh->v_tag = init_chk->init.initiate_tag;
|
||||
}
|
||||
if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
|
||||
@ -248,7 +247,7 @@ sctp6_notify_mbuf(struct sctp_inpcb *inp,
|
||||
struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net)
|
||||
{
|
||||
u_int32_t nxtsz;
|
||||
uint32_t nxtsz;
|
||||
|
||||
if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
|
||||
(icmp6 == NULL) || (sh == NULL)) {
|
||||
@ -285,12 +284,12 @@ sctp6_notify_mbuf(struct sctp_inpcb *inp,
|
||||
/* now off to subtract IP_DF flag if needed */
|
||||
|
||||
TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) {
|
||||
if ((u_int32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) {
|
||||
if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) {
|
||||
chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
|
||||
}
|
||||
}
|
||||
TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
|
||||
if ((u_int32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) {
|
||||
if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) {
|
||||
/*
|
||||
* For this guy we also mark for immediate
|
||||
* resend since we sent to big of chunk
|
||||
@ -939,7 +938,7 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
return (ECONNRESET); /* I made the same as TCP since we are
|
||||
* not setup? */
|
||||
}
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
vrf_id = inp->def_vrf_id;
|
||||
SCTP_ASOC_CREATE_LOCK(inp);
|
||||
SCTP_INP_RLOCK(inp);
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
|
||||
@ -1095,9 +1094,8 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
||||
/* punt */
|
||||
goto notConn6;
|
||||
}
|
||||
vrf_id = SCTP_DEFAULT_VRFID;
|
||||
|
||||
sctp_ifa = sctp_source_address_selection(inp, stcb, (struct route *)&net->ro, net, 0, vrf_id);
|
||||
vrf_id = inp->def_vrf_id;
|
||||
sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *) & net->ro, net, 0, vrf_id);
|
||||
if (sctp_ifa) {
|
||||
sin6->sin6_addr = sctp_ifa->address.sin6.sin6_addr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user