diff options
author | tuexen <tuexen@FreeBSD.org> | 2016-01-30 12:58:38 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2016-01-30 12:58:38 +0000 |
commit | 9aecdeee5e3f9ced484d9481c0f053d9ff59986e (patch) | |
tree | ca9af5b05d1af61bcdb8025acfae0bd69ed6aa46 /sys/netinet | |
parent | 2b5e197c218584bbca74465ecdce077370e4b687 (diff) | |
download | FreeBSD-src-9aecdeee5e3f9ced484d9481c0f053d9ff59986e.zip FreeBSD-src-9aecdeee5e3f9ced484d9481c0f053d9ff59986e.tar.gz |
Don't allow a remote encapsulation port change during the
SCTP restart procedure.
MFC after: 3 days
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/sctp_input.c | 8 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 50 | ||||
-rw-r--r-- | sys/netinet/sctp_output.h | 3 |
3 files changed, 41 insertions, 20 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 1dbb6cf..a1e79e4 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -85,7 +85,7 @@ static void sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_init_chunk *cp, struct sctp_inpcb *inp, - struct sctp_tcb *stcb, int *abort_no_unlock, + struct sctp_tcb *stcb, struct sctp_nets *net, int *abort_no_unlock, uint8_t mflowtype, uint32_t mflowid, uint32_t vrf_id, uint16_t port) { @@ -198,8 +198,8 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, 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, src, dst, - sh, cp, + sctp_send_initiate_ack(inp, stcb, net, m, iphlen, offset, + src, dst, sh, cp, mflowtype, mflowid, vrf_id, port, ((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED)); @@ -4840,7 +4840,7 @@ process_control_chunks: } sctp_handle_init(m, iphlen, *offset, src, dst, sh, (struct sctp_init_chunk *)ch, inp, - stcb, &abort_no_unlock, + stcb, *netp, &abort_no_unlock, mflowtype, mflowid, vrf_id, port); *offset = length; diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 21e45de..0172610 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -5484,7 +5484,8 @@ sctp_are_there_new_addresses(struct sctp_association *asoc, */ void sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, - struct mbuf *init_pkt, int iphlen, int offset, + struct sctp_nets *src_net, struct mbuf *init_pkt, + int iphlen, int offset, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_init_chunk *init_chk, uint8_t mflowtype, uint32_t mflowid, @@ -5528,20 +5529,39 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, asoc = NULL; } if ((asoc != NULL) && - (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) && - (sctp_are_there_new_addresses(asoc, init_pkt, offset, src))) { - /* new addresses, out of here in non-cookie-wait states */ - /* - * Send a ABORT, we don't add the new address error clause - * though we even set the T bit and copy in the 0 tag.. this - * looks no different than if no listener was present. - */ - op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), - "Address added"); - sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err, - mflowtype, mflowid, inp->fibnum, - vrf_id, port); - return; + (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT)) { + if (sctp_are_there_new_addresses(asoc, init_pkt, offset, src)) { + /* + * new addresses, out of here in non-cookie-wait + * states + * + * Send an ABORT, without the new address error cause. + * This looks no different than if no listener was + * present. + */ + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "Address added"); + sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err, + mflowtype, mflowid, inp->fibnum, + vrf_id, port); + return; + } + if (src_net != NULL && (src_net->port != port)) { + /* + * change of remote encapsulation port, out of here + * in non-cookie-wait states + * + * Send an ABORT, without an specific error cause. This + * looks no different than if no listener was + * present. + */ + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "Remote encapsulation port changed"); + sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err, + mflowtype, mflowid, inp->fibnum, + vrf_id, port); + return; + } } abort_flag = 0; op_err = sctp_arethere_unrecognized_parameters(init_pkt, diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index d7222c4..b2441a6 100644 --- a/sys/netinet/sctp_output.h +++ b/sys/netinet/sctp_output.h @@ -80,7 +80,8 @@ sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *, int ); void -sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *, +sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, + struct sctp_nets *, struct mbuf *, int, int, struct sockaddr *, struct sockaddr *, struct sctphdr *, struct sctp_init_chunk *, |