From owner-svn-src-stable-9@FreeBSD.ORG Sun Jul 8 16:14:42 2012 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id D19E8106566C; Sun, 8 Jul 2012 16:14:42 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BA1738FC0C; Sun, 8 Jul 2012 16:14:42 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q68GEggK061484; Sun, 8 Jul 2012 16:14:42 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q68GEgST061474; Sun, 8 Jul 2012 16:14:42 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201207081614.q68GEgST061474@svn.freebsd.org> From: Michael Tuexen Date: Sun, 8 Jul 2012 16:14:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r238253 - in stable/9/sys: netinet netinet6 X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Jul 2012 16:14:43 -0000 Author: tuexen Date: Sun Jul 8 16:14:42 2012 New Revision: 238253 URL: http://svn.freebsd.org/changeset/base/238253 Log: MFC r237049: 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. Approved by: re@ Modified: stable/9/sys/netinet/sctp_indata.c stable/9/sys/netinet/sctp_indata.h stable/9/sys/netinet/sctp_input.c stable/9/sys/netinet/sctp_input.h stable/9/sys/netinet/sctp_output.c stable/9/sys/netinet/sctp_output.h stable/9/sys/netinet/sctputil.c stable/9/sys/netinet/sctputil.h stable/9/sys/netinet6/sctp6_usrreq.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/netinet/sctp_indata.c ============================================================================== --- stable/9/sys/netinet/sctp_indata.c Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctp_indata.c Sun Jul 8 16:14:42 2012 (r238253) @@ -2516,8 +2516,10 @@ doit_again: int sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, - struct sctphdr *sh, struct sctp_inpcb *inp, struct sctp_tcb *stcb, - struct sctp_nets *net, uint32_t * high_tsn) + struct sctphdr *sh, struct sctp_inpcb *inp, + struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t * high_tsn, + uint8_t use_mflowid, uint32_t mflowid, + uint32_t vrf_id, uint16_t port) { struct sctp_data_chunk *ch, chunk_buf; struct sctp_association *asoc; @@ -2625,7 +2627,9 @@ sctp_process_data(struct mbuf **mm, int } stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19; sctp_abort_association(inp, stcb, m, iphlen, sh, - op_err, 0, net->port); + op_err, + use_mflowid, mflowid, + vrf_id, port); return (2); } #ifdef SCTP_AUDITING_ENABLED @@ -2689,7 +2693,11 @@ sctp_process_data(struct mbuf **mm, int struct mbuf *op_err; op_err = sctp_generate_invmanparam(SCTP_CAUSE_PROTOCOL_VIOLATION); - sctp_abort_association(inp, stcb, m, iphlen, sh, op_err, 0, net->port); + sctp_abort_association(inp, stcb, + m, iphlen, + sh, op_err, + use_mflowid, mflowid, + vrf_id, port); return (2); } break; Modified: stable/9/sys/netinet/sctp_indata.h ============================================================================== --- stable/9/sys/netinet/sctp_indata.h Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctp_indata.h Sun Jul 8 16:14:42 2012 (r238253) @@ -113,7 +113,9 @@ void int sctp_process_data(struct mbuf **, int, int *, int, struct sctphdr *, struct sctp_inpcb *, struct sctp_tcb *, - struct sctp_nets *, uint32_t *); + struct sctp_nets *, uint32_t *, + uint8_t, uint32_t, + uint32_t, uint16_t); void sctp_slide_mapping_arrays(struct sctp_tcb *stcb); Modified: stable/9/sys/netinet/sctp_input.c ============================================================================== --- stable/9/sys/netinet/sctp_input.c Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctp_input.c Sun Jul 8 16:14:42 2012 (r238253) @@ -81,8 +81,10 @@ sctp_stop_all_cookie_timers(struct sctp_ /* 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 iph 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 iph /* 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 iph /* 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 iph /* 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 iph /* 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 iph 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 iph * 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 iph 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 * 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, in 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, in 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 * } 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 /* 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 /* 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 /* 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 /* 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 /* 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 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, 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 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 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 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 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 * 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, 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, 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, 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, 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, /* 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, 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, - ¬ification, vrf_id, auth_skipped, auth_offset, auth_len, port); + ¬ification, 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, 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 */ 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 /* 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 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 * 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 } /* 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, 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, 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, } 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 @@ -5989,7 +6077,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) { @@ -5999,7 +6089,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; @@ -6028,7 +6120,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); Modified: stable/9/sys/netinet/sctp_input.h ============================================================================== --- stable/9/sys/netinet/sctp_input.h Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctp_input.h Sun Jul 8 16:14:42 2012 (r238253) @@ -39,8 +39,11 @@ __FBSDID("$FreeBSD$"); #if defined(_KERNEL) || defined(__Userspace__) 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, uint16_t); + struct sctphdr *, struct sctp_chunkhdr *, + struct sctp_inpcb *, struct sctp_tcb *, + struct sctp_nets *, uint8_t, + uint8_t, uint32_t, + uint32_t, uint16_t); struct sctp_stream_reset_out_request * sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, Modified: stable/9/sys/netinet/sctp_output.c ============================================================================== --- stable/9/sys/netinet/sctp_output.c Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctp_output.c Sun Jul 8 16:14:42 2012 (r238253) @@ -3859,13 +3859,13 @@ sctp_lowlevel_chunk_output(struct sctp_i uint16_t dest_port, uint32_t v_tag, uint16_t port, + union sctp_sockstore *over_addr, + uint8_t use_mflowid, uint32_t mflowid, #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) - int so_locked SCTP_UNUSED, + int so_locked SCTP_UNUSED #else - int so_locked, + int so_locked #endif - union sctp_sockstore *over_addr, - struct mbuf *init ) /* nofragment_flag to tell if IP_DF should be set (IPv4 only) */ { @@ -3951,8 +3951,8 @@ sctp_lowlevel_chunk_output(struct sctp_i m->m_pkthdr.flowid = net->flowid; m->m_flags |= M_FLOWID; } else { - if ((init != NULL) && (init->m_flags & M_FLOWID)) { - m->m_pkthdr.flowid = init->m_pkthdr.flowid; + if (use_mflowid != 0) { + m->m_pkthdr.flowid = mflowid; m->m_flags |= M_FLOWID; } } @@ -4243,8 +4243,8 @@ sctp_lowlevel_chunk_output(struct sctp_i m->m_pkthdr.flowid = net->flowid; m->m_flags |= M_FLOWID; } else { - if ((init != NULL) && (init->m_flags & M_FLOWID)) { - m->m_pkthdr.flowid = init->m_pkthdr.flowid; + if (use_mflowid != 0) { + m->m_pkthdr.flowid = mflowid; m->m_flags |= M_FLOWID; } } @@ -4841,7 +4841,9 @@ sctp_send_initiate(struct sctp_inpcb *in (struct sockaddr *)&net->ro._l_addr, m, 0, NULL, 0, 0, 0, 0, inp->sctp_lport, stcb->rport, htonl(0), - net->port, so_locked, NULL, NULL); + net->port, NULL, + 0, 0, + so_locked); SCTPDBG(SCTP_DEBUG_OUTPUT4, "lowlevel_output - %d\n", ret); SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks); (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time); @@ -5370,8 +5372,10 @@ sctp_are_there_new_addresses(struct sctp */ 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, uint16_t port, int hold_inp_lock) + struct mbuf *init_pkt, int iphlen, int offset, + struct sctphdr *sh, struct sctp_init_chunk *init_chk, + uint8_t use_mflowid, uint32_t mflowid, + uint32_t vrf_id, uint16_t port, int hold_inp_lock) { struct sctp_association *asoc; struct mbuf *m, *m_at, *m_tmp, *m_cookie, *op_err, *mp_last; @@ -5422,7 +5426,9 @@ sctp_send_initiate_ack(struct sctp_inpcb * 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, port); + sctp_send_abort(init_pkt, iphlen, sh, 0, NULL, + use_mflowid, mflowid, + vrf_id, port); return; } abort_flag = 0; @@ -5432,7 +5438,9 @@ sctp_send_initiate_ack(struct sctp_inpcb if (abort_flag) { do_a_abort: sctp_send_abort(init_pkt, iphlen, sh, - init_chk->init.initiate_tag, op_err, vrf_id, port); + init_chk->init.initiate_tag, op_err, + use_mflowid, mflowid, + vrf_id, port); return; } m = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); @@ -6034,7 +6042,9 @@ do_a_abort: (void)sctp_lowlevel_chunk_output(inp, NULL, NULL, to, m, 0, NULL, 0, 0, 0, 0, inp->sctp_lport, sh->src_port, init_chk->init.initiate_tag, - port, SCTP_SO_NOT_LOCKED, over_addr, init_pkt); + port, over_addr, + use_mflowid, mflowid, + SCTP_SO_NOT_LOCKED); SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks); } @@ -8116,7 +8126,9 @@ again_one_more_time: no_fragmentflg, 0, asconf, inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag), - net->port, so_locked, NULL, NULL))) { + net->port, NULL, + 0, 0, + so_locked))) { if (error == ENOBUFS) { asoc->ifp_had_enobuf = 1; SCTP_STAT_INCR(sctps_lowlevelerr); @@ -8388,7 +8400,9 @@ again_one_more_time: no_fragmentflg, 0, asconf, inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag), - net->port, so_locked, NULL, NULL))) { + net->port, NULL, + 0, 0, + so_locked))) { if (error == ENOBUFS) { asoc->ifp_had_enobuf = 1; SCTP_STAT_INCR(sctps_lowlevelerr); @@ -8727,7 +8741,9 @@ no_data_fill: asconf, inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag), - net->port, so_locked, NULL, NULL))) { + net->port, NULL, + 0, 0, + so_locked))) { /* error, we could not output */ if (error == ENOBUFS) { SCTP_STAT_INCR(sctps_lowlevelerr); @@ -9429,7 +9445,9 @@ sctp_chunk_retransmission(struct sctp_in auth_offset, auth, stcb->asoc.authinfo.active_keyid, no_fragmentflg, 0, 0, inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag), - chk->whoTo->port, so_locked, NULL, NULL))) { + chk->whoTo->port, NULL, + 0, 0, + so_locked))) { SCTP_STAT_INCR(sctps_lowlevelerr); return (error); } @@ -9694,7 +9712,9 @@ one_chunk_around: auth_offset, auth, auth_keyid, no_fragmentflg, 0, 0, inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag), - net->port, so_locked, NULL, NULL))) { + net->port, NULL, + 0, 0, + so_locked))) { /* error, we could not output */ SCTP_STAT_INCR(sctps_lowlevelerr); return (error); @@ -10812,7 +10832,9 @@ sctp_send_abort_tcb(struct sctp_tcb *stc (struct sockaddr *)&net->ro._l_addr, m_out, auth_offset, auth, stcb->asoc.authinfo.active_keyid, 1, 0, 0, stcb->sctp_ep->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag), - stcb->asoc.primary_destination->port, so_locked, NULL, NULL); + stcb->asoc.primary_destination->port, NULL, + 0, 0, + so_locked); SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks); } @@ -10849,14 +10871,18 @@ sctp_send_shutdown_complete(struct sctp_ m_shutdown_comp, 0, NULL, 0, 1, 0, 0, stcb->sctp_ep->sctp_lport, stcb->rport, htonl(vtag), - net->port, SCTP_SO_NOT_LOCKED, NULL, NULL); + net->port, NULL, + 0, 0, + SCTP_SO_NOT_LOCKED); SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks); return; } static void sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag, - uint8_t type, struct mbuf *cause, uint32_t vrf_id, uint16_t port) + uint8_t type, struct mbuf *cause, + uint8_t use_mflowid, uint32_t mflowid, + uint32_t vrf_id, uint16_t port) { struct mbuf *o_pak; struct mbuf *mout; @@ -10929,8 +10955,8 @@ sctp_send_resp_msg(struct mbuf *m, struc SCTP_BUF_RESV_UF(mout, max_linkhdr); SCTP_BUF_LEN(mout) = len; SCTP_BUF_NEXT(mout) = cause; - if (m->m_flags & M_FLOWID) { - mout->m_pkthdr.flowid = m->m_pkthdr.flowid; + if (use_mflowid != 0) { + mout->m_pkthdr.flowid = mflowid; mout->m_flags |= M_FLOWID; } #ifdef INET @@ -11110,9 +11136,12 @@ sctp_send_resp_msg(struct mbuf *m, struc void sctp_send_shutdown_complete2(struct mbuf *m, struct sctphdr *sh, + uint8_t use_mflowid, uint32_t mflowid, uint32_t vrf_id, uint16_t port) { - sctp_send_resp_msg(m, sh, 0, SCTP_SHUTDOWN_COMPLETE, NULL, vrf_id, port); + sctp_send_resp_msg(m, sh, 0, SCTP_SHUTDOWN_COMPLETE, NULL, + use_mflowid, mflowid, + vrf_id, port); } void @@ -11944,7 +11973,9 @@ skip_stuff: void sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag, - struct mbuf *cause, uint32_t vrf_id, uint16_t port) + struct mbuf *cause, + uint8_t use_mflowid, uint32_t mflowid, + uint32_t vrf_id, uint16_t port) { /* Don't respond to an ABORT with an ABORT. */ if (sctp_is_there_an_abort_here(m, iphlen, &vtag)) { @@ -11952,15 +11983,21 @@ sctp_send_abort(struct mbuf *m, int iphl sctp_m_freem(cause); return; } - sctp_send_resp_msg(m, sh, vtag, SCTP_ABORT_ASSOCIATION, cause, vrf_id, port); + sctp_send_resp_msg(m, sh, vtag, SCTP_ABORT_ASSOCIATION, cause, + use_mflowid, mflowid, + vrf_id, port); return; } void sctp_send_operr_to(struct mbuf *m, struct sctphdr *sh, uint32_t vtag, - struct mbuf *cause, uint32_t vrf_id, uint16_t port) + struct mbuf *cause, + uint8_t use_mflowid, uint32_t mflowid, + uint32_t vrf_id, uint16_t port) { - sctp_send_resp_msg(m, sh, vtag, SCTP_OPERATION_ERROR, cause, vrf_id, port); + sctp_send_resp_msg(m, sh, vtag, SCTP_OPERATION_ERROR, cause, + use_mflowid, mflowid, + vrf_id, port); return; } Modified: stable/9/sys/netinet/sctp_output.h ============================================================================== --- stable/9/sys/netinet/sctp_output.h Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctp_output.h Sun Jul 8 16:14:42 2012 (r238253) @@ -83,8 +83,9 @@ sctp_send_initiate(struct sctp_inpcb *, ); void -sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, - struct mbuf *, int, int, struct sctphdr *, struct sctp_init_chunk *, +sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *, + int, int, struct sctphdr *, struct sctp_init_chunk *, + uint8_t, uint32_t, uint32_t, uint16_t, int); struct mbuf * @@ -116,6 +117,7 @@ void sctp_send_shutdown_complete(struct void sctp_send_shutdown_complete2(struct mbuf *, struct sctphdr *, + uint8_t, uint32_t, uint32_t, uint16_t); void sctp_send_asconf(struct sctp_tcb *, struct sctp_nets *, int addr_locked); @@ -202,15 +204,19 @@ sctp_send_str_reset_req(struct sctp_tcb void sctp_send_abort(struct mbuf *, int, struct sctphdr *, uint32_t, - struct mbuf *, uint32_t, uint16_t); + struct mbuf *, + uint8_t, uint32_t, + uint32_t, uint16_t); void sctp_send_operr_to(struct mbuf *, struct sctphdr *, uint32_t, - struct mbuf *, uint32_t, uint16_t); + struct mbuf *, + uint8_t, uint32_t, + uint32_t, uint16_t); #endif /* _KERNEL || __Userspace__ */ -#if defined(_KERNEL) || defined (__Userspace__) +#if defined(_KERNEL) || defined(__Userspace__) int sctp_sosend(struct socket *so, struct sockaddr *addr, Modified: stable/9/sys/netinet/sctputil.c ============================================================================== --- stable/9/sys/netinet/sctputil.c Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctputil.c Sun Jul 8 16:14:42 2012 (r238253) @@ -3823,7 +3823,9 @@ sctp_abort_notification(struct sctp_tcb void sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, - struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err, + struct mbuf *m, int iphlen, struct sctphdr *sh, + struct mbuf *op_err, + uint8_t use_mflowid, uint32_t mflowid, uint32_t vrf_id, uint16_t port) { uint32_t vtag; @@ -3842,7 +3844,9 @@ sctp_abort_association(struct sctp_inpcb vrf_id = stcb->asoc.vrf_id; stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; } - sctp_send_abort(m, iphlen, sh, vtag, op_err, vrf_id, port); + sctp_send_abort(m, iphlen, sh, vtag, op_err, + use_mflowid, mflowid, + vrf_id, port); if (stcb != NULL) { /* Ok, now lets free it */ #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) @@ -3992,7 +3996,9 @@ sctp_abort_an_association(struct sctp_in void sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, - struct sctp_inpcb *inp, uint32_t vrf_id, uint16_t port) + struct sctp_inpcb *inp, + uint8_t use_mflowid, uint32_t mflowid, + uint32_t vrf_id, uint16_t port) { struct sctp_chunkhdr *ch, chunk_buf; unsigned int chk_length; @@ -4035,7 +4041,9 @@ sctp_handle_ootb(struct mbuf *m, int iph */ return; case SCTP_SHUTDOWN_ACK: - sctp_send_shutdown_complete2(m, sh, vrf_id, port); + sctp_send_shutdown_complete2(m, sh, + use_mflowid, mflowid, + vrf_id, port); return; default: break; @@ -4047,7 +4055,9 @@ sctp_handle_ootb(struct mbuf *m, int iph if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && (contains_init_chunk == 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); } } Modified: stable/9/sys/netinet/sctputil.h ============================================================================== --- stable/9/sys/netinet/sctputil.h Sun Jul 8 16:12:59 2012 (r238252) +++ stable/9/sys/netinet/sctputil.h Sun Jul 8 16:14:42 2012 (r238253) @@ -185,8 +185,10 @@ sctp_abort_notification(struct sctp_tcb /* 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, uint16_t); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***