summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_input.c
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2012-06-14 06:54:48 +0000
committertuexen <tuexen@FreeBSD.org>2012-06-14 06:54:48 +0000
commite8af2861381f0efb48f7fbe22c15024d2f0cbe0d (patch)
tree832c543f2b46d4372a3097dc0c95719bfb27a97e /sys/netinet/sctp_input.c
parenta65a9620af9a7fc5136edbcf7488e62299d44e0c (diff)
downloadFreeBSD-src-e8af2861381f0efb48f7fbe22c15024d2f0cbe0d.zip
FreeBSD-src-e8af2861381f0efb48f7fbe22c15024d2f0cbe0d.tar.gz
Pass flowid explicitly through the stack instead of taking it from
the mbuf chain at different places. While there: Fix several bugs related to VRFs. MFC after: 3 days
Diffstat (limited to 'sys/netinet/sctp_input.c')
-rw-r--r--sys/netinet/sctp_input.c188
1 files changed, 141 insertions, 47 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 9833d8e..f934c74 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -81,8 +81,10 @@ sctp_stop_all_cookie_timers(struct sctp_tcb *stcb)
/* INIT handler */
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,
- int *abort_no_unlock, uint32_t vrf_id, uint16_t port)
+ struct sctp_init_chunk *cp, struct sctp_inpcb *inp,
+ struct sctp_tcb *stcb, int *abort_no_unlock,
+ uint8_t use_mflowid, uint32_t mflowid,
+ uint32_t vrf_id, uint16_t port)
{
struct sctp_init *init;
struct mbuf *op_err;
@@ -96,6 +98,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(inp, stcb, m, iphlen, sh, op_err,
+ use_mflowid, mflowid,
vrf_id, port);
if (stcb)
*abort_no_unlock = 1;
@@ -107,6 +110,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,
+ use_mflowid, mflowid,
vrf_id, port);
if (stcb)
*abort_no_unlock = 1;
@@ -116,6 +120,7 @@ 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,
+ use_mflowid, mflowid,
vrf_id, port);
if (stcb)
*abort_no_unlock = 1;
@@ -125,6 +130,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,
+ use_mflowid, mflowid,
vrf_id, port);
if (stcb)
*abort_no_unlock = 1;
@@ -134,6 +140,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,
+ use_mflowid, mflowid,
vrf_id, port);
if (stcb)
*abort_no_unlock = 1;
@@ -142,7 +149,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
offset + ntohs(cp->ch.chunk_length))) {
/* auth parameter(s) error... send abort */
- sctp_abort_association(inp, stcb, m, iphlen, sh, NULL, vrf_id, port);
+ sctp_abort_association(inp, stcb, m, iphlen, sh, NULL,
+ use_mflowid, mflowid,
+ vrf_id, port);
if (stcb)
*abort_no_unlock = 1;
goto outnow;
@@ -169,7 +178,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
* state :-)
*/
if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
- sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port);
+ sctp_send_abort(m, iphlen, sh, 0, NULL,
+ use_mflowid, mflowid,
+ vrf_id, port);
}
goto outnow;
}
@@ -180,7 +191,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
} else {
SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n");
- sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp, vrf_id, port,
+ sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp,
+ use_mflowid, mflowid,
+ vrf_id, port,
((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED));
}
outnow:
@@ -406,9 +419,11 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
* INIT-ACK message processing/consumption returns value < 0 on error
*/
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)
+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,
+ uint8_t use_mflowid, uint32_t mflowid,
+ uint32_t vrf_id)
{
struct sctp_association *asoc;
struct mbuf *op_err;
@@ -445,8 +460,9 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
SCTPDBG(SCTP_DEBUG_INPUT1,
"Load addresses from INIT causes an abort %d\n",
retval);
- sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
- NULL, 0, net->port);
+ sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, NULL,
+ use_mflowid, mflowid,
+ vrf_id, net->port);
*abort_no_unlock = 1;
return (-1);
}
@@ -520,7 +536,9 @@ 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, vrf_id, net->port);
+ sh, op_err,
+ use_mflowid, mflowid,
+ vrf_id, net->port);
*abort_no_unlock = 1;
}
return (retval);
@@ -1260,9 +1278,11 @@ 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)
+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,
+ uint8_t use_mflowid, uint32_t mflowid,
+ uint32_t vrf_id)
{
struct sctp_init_ack *init_ack;
struct mbuf *op_err;
@@ -1279,7 +1299,9 @@ 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, net->port);
+ op_err,
+ use_mflowid, mflowid,
+ vrf_id, net->port);
*abort_no_unlock = 1;
return (-1);
}
@@ -1289,7 +1311,9 @@ 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, net->port);
+ op_err,
+ use_mflowid, mflowid,
+ vrf_id, net->port);
*abort_no_unlock = 1;
return (-1);
}
@@ -1297,7 +1321,9 @@ 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, net->port);
+ op_err,
+ use_mflowid, mflowid,
+ vrf_id, net->port);
*abort_no_unlock = 1;
return (-1);
}
@@ -1305,7 +1331,9 @@ 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, net->port);
+ op_err,
+ use_mflowid, mflowid,
+ vrf_id, net->port);
*abort_no_unlock = 1;
return (-1);
}
@@ -1313,7 +1341,9 @@ 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, net->port);
+ op_err,
+ use_mflowid, mflowid,
+ vrf_id, net->port);
*abort_no_unlock = 1;
return (-1);
}
@@ -1336,7 +1366,9 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
stcb, 0, (void *)stcb->asoc.primary_destination, SCTP_SO_NOT_LOCKED);
}
if (sctp_process_init_ack(m, iphlen, offset, sh, cp, stcb,
- net, abort_no_unlock, vrf_id) < 0) {
+ net, abort_no_unlock,
+ use_mflowid, mflowid,
+ vrf_id) < 0) {
/* error in parsing parameters */
return (-1);
}
@@ -1391,6 +1423,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,
+ uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port);
@@ -1405,7 +1438,9 @@ 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 **netp,
struct sockaddr *init_src, int *notification,
- uint32_t vrf_id, int auth_skipped, uint32_t auth_offset, uint32_t auth_len, uint16_t port)
+ int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
+ uint8_t use_mflowid, uint32_t mflowid,
+ uint32_t vrf_id, uint16_t port)
{
struct sctp_association *asoc;
struct sctp_init_chunk *init_cp, init_buf;
@@ -1443,6 +1478,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, sh, cookie->peers_vtag, op_err,
+ use_mflowid, mflowid,
vrf_id, net->port);
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 2;
@@ -1667,7 +1703,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_NAT_COLLIDING_STATE);
ph->param_length = htons(sizeof(struct sctp_paramhdr));
- sctp_send_abort(m, iphlen, sh, 0, op_err, vrf_id, port);
+ sctp_send_abort(m, iphlen, sh, 0, op_err,
+ use_mflowid, mflowid,
+ vrf_id, port);
return (NULL);
}
if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
@@ -1832,6 +1870,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
return (sctp_process_cookie_new(m, iphlen, offset, sh, cookie, cookie_len,
inp, netp, init_src, notification,
auth_skipped, auth_offset, auth_len,
+ use_mflowid, mflowid,
vrf_id, port));
}
/*
@@ -1962,12 +2001,13 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
* cookie-echo chunk length: length of the cookie chunk to: where the init
* was from returns a new TCB
*/
-struct sctp_tcb *
+static struct sctp_tcb *
sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
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,
+ uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
struct sctp_tcb *stcb;
@@ -2062,7 +2102,9 @@ 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, port);
+ sh, op_err,
+ use_mflowid, mflowid,
+ vrf_id, port);
return (NULL);
}
/* get the correct sctp_nets */
@@ -2088,7 +2130,9 @@ 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, port);
+ sh, op_err,
+ use_mflowid, mflowid,
+ vrf_id, port);
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_TCB_UNLOCK(stcb);
SCTP_SOCKET_LOCK(so, 1);
@@ -2335,7 +2379,9 @@ 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, uint16_t port)
+ struct sctp_tcb **locked_tcb,
+ uint8_t use_mflowid, uint32_t mflowid,
+ uint32_t vrf_id, uint16_t port)
{
struct sctp_state_cookie *cookie;
struct sctp_tcb *l_stcb = *stcb;
@@ -2571,6 +2617,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, sh, cookie->peers_vtag, op_err,
+ use_mflowid, mflowid,
vrf_id, port);
return (NULL);
}
@@ -2658,21 +2705,25 @@ 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, &notification,
- auth_skipped, auth_offset, auth_len, vrf_id, port);
+ auth_skipped, auth_offset, auth_len,
+ use_mflowid, mflowid,
+ vrf_id, port);
} 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,
- &notification, vrf_id, auth_skipped, auth_offset, auth_len, port);
+ &notification, auth_skipped, auth_offset, auth_len,
+ use_mflowid, mflowid,
+ vrf_id, port);
}
if (*stcb == NULL) {
/* still no TCB... must be bad cookie-echo */
return (NULL);
}
- if ((*netp != NULL) && (m->m_flags & M_FLOWID)) {
- (*netp)->flowid = m->m_pkthdr.flowid;
+ if ((*netp != NULL) && (use_mflowid != 0)) {
+ (*netp)->flowid = mflowid;
#ifdef INVARIANTS
(*netp)->flowidset = 1;
#endif
@@ -2745,7 +2796,9 @@ 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, port);
+ sh, op_err,
+ use_mflowid, mflowid,
+ vrf_id, port);
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
pcb_so = SCTP_INP_SO(*inp_p);
atomic_add_int(&(*stcb)->asoc.refcnt, 1);
@@ -4361,6 +4414,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,
+ uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
struct sctp_association *asoc;
@@ -4517,6 +4571,7 @@ __attribute__((noinline))
if (stcb == NULL) {
/* no association, so it's out of the blue... */
sctp_handle_ootb(m, iphlen, *offset, sh, inp,
+ use_mflowid, mflowid,
vrf_id, port);
*offset = length;
if (locked_tcb) {
@@ -4554,6 +4609,7 @@ __attribute__((noinline))
SCTP_TCB_UNLOCK(locked_tcb);
}
sctp_handle_ootb(m, iphlen, *offset, sh, inp,
+ use_mflowid, mflowid,
vrf_id, port);
return (NULL);
}
@@ -4695,7 +4751,9 @@ process_control_chunks:
if ((num_chunks > 1) ||
(length - *offset > (int)SCTP_SIZE32(chk_length))) {
sctp_abort_association(inp, stcb, m,
- iphlen, sh, NULL, vrf_id, port);
+ iphlen, sh, NULL,
+ use_mflowid, mflowid,
+ vrf_id, port);
*offset = length;
return (NULL);
}
@@ -4705,13 +4763,17 @@ process_control_chunks:
op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
sctp_abort_association(inp, stcb, m,
- iphlen, sh, op_err, vrf_id, port);
+ iphlen, sh, op_err,
+ use_mflowid, mflowid,
+ vrf_id, port);
*offset = length;
return (NULL);
}
sctp_handle_init(m, iphlen, *offset, sh,
(struct sctp_init_chunk *)ch, inp,
- stcb, &abort_no_unlock, vrf_id, port);
+ stcb, &abort_no_unlock,
+ use_mflowid, mflowid,
+ vrf_id, port);
*offset = length;
if ((!abort_no_unlock) && (locked_tcb)) {
SCTP_TCB_UNLOCK(locked_tcb);
@@ -4760,7 +4822,11 @@ 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);
+ (struct sctp_init_ack_chunk *)ch,
+ stcb, *netp,
+ &abort_no_unlock,
+ use_mflowid, mflowid,
+ vrf_id);
} else {
ret = -1;
}
@@ -5066,7 +5132,9 @@ process_control_chunks:
op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
sctp_abort_association(inp, stcb, m,
- iphlen, sh, op_err, vrf_id, port);
+ iphlen, sh, op_err,
+ use_mflowid, mflowid,
+ vrf_id, port);
}
*offset = length;
return (NULL);
@@ -5098,6 +5166,8 @@ process_control_chunks:
auth_offset,
auth_len,
&locked_tcb,
+ use_mflowid,
+ mflowid,
vrf_id,
port);
} else {
@@ -5550,8 +5620,10 @@ __attribute__((noinline))
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, uint16_t port)
+ struct sctp_inpcb *inp, struct sctp_tcb *stcb,
+ struct sctp_nets *net, uint8_t ecn_bits,
+ uint8_t use_mflowid, uint32_t mflowid,
+ uint32_t vrf_id, uint16_t port)
{
/*
* Control chunk processing
@@ -5587,6 +5659,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
*/
SCTP_TCB_UNLOCK(stcb);
sctp_handle_ootb(m, iphlen, offset, sh, inp,
+ use_mflowid, mflowid,
vrf_id, port);
goto out_now;
}
@@ -5595,7 +5668,9 @@ 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, port);
+ inp, stcb, &net, &fwd_tsn_seen,
+ use_mflowid, mflowid,
+ vrf_id, port);
if (stcb) {
/*
* This covers us if the cookie-echo was there and
@@ -5631,6 +5706,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,
+ use_mflowid, mflowid,
vrf_id, port);
goto out_now;
}
@@ -5700,6 +5776,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,
+ use_mflowid, mflowid,
vrf_id, port);
SCTP_TCB_UNLOCK(stcb);
goto out_now;
@@ -5720,7 +5797,9 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
}
/* plow through the data chunks while length > offset */
retval = sctp_process_data(mm, iphlen, &offset, length, sh,
- inp, stcb, net, &high_tsn);
+ inp, stcb, net, &high_tsn,
+ use_mflowid, mflowid,
+ vrf_id, port);
if (retval == 2) {
/*
* The association aborted, NO UNLOCK needed since
@@ -5820,6 +5899,8 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
struct sctp_chunkhdr *ch;
int refcount_up = 0;
int length, mlen, offset;
+ uint32_t mflowid;
+ uint8_t use_mflowid;
#if !defined(SCTP_WITH_NO_CSUM)
uint32_t check, calc_check;
@@ -5855,6 +5936,13 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
sctp_packet_log(m, mlen);
#endif
+ if (m->m_flags & M_FLOWID) {
+ mflowid = m->m_pkthdr.flowid;
+ use_mflowid = 1;
+ } else {
+ mflowid = 0;
+ use_mflowid = 0;
+ }
/*
* Must take out the iphlen, since mlen expects this (only effect lb
* case)
@@ -5926,8 +6014,8 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
}
net->port = port;
}
- if ((net != NULL) && (m->m_flags & M_FLOWID)) {
- net->flowid = m->m_pkthdr.flowid;
+ if ((net != NULL) && (use_mflowid != 0)) {
+ net->flowid = mflowid;
#ifdef INVARIANTS
net->flowidset = 1;
#endif
@@ -5961,8 +6049,8 @@ sctp_skip_csum_4:
}
net->port = port;
}
- if ((net != NULL) && (m->m_flags & M_FLOWID)) {
- net->flowid = m->m_pkthdr.flowid;
+ if ((net != NULL) && (use_mflowid != 0)) {
+ net->flowid = mflowid;
#ifdef INVARIANTS
net->flowidset = 1;
#endif
@@ -5996,7 +6084,9 @@ sctp_skip_csum_4:
sh->v_tag = init_chk->init.initiate_tag;
}
if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
- sctp_send_shutdown_complete2(m, sh, vrf_id, port);
+ sctp_send_shutdown_complete2(m, sh,
+ use_mflowid, mflowid,
+ vrf_id, port);
goto bad;
}
if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
@@ -6006,7 +6096,9 @@ sctp_skip_csum_4:
if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
(ch->chunk_type != SCTP_INIT))) {
- sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port);
+ sctp_send_abort(m, iphlen, sh, 0, NULL,
+ use_mflowid, mflowid,
+ vrf_id, port);
}
}
goto bad;
@@ -6035,7 +6127,9 @@ 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, port);
+ inp, stcb, net, ecn_bits,
+ use_mflowid, mflowid,
+ vrf_id, port);
/* inp's ref-count reduced && stcb unlocked */
if (m) {
sctp_m_freem(m);
OpenPOWER on IntegriCloud