diff options
Diffstat (limited to 'sys/netinet/sctp_input.c')
-rw-r--r-- | sys/netinet/sctp_input.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 3b50590..4c1a98c 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; @@ -5684,9 +5684,18 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt stcb = sctp_findassociation_addr(m, offset, src, dst, sh, ch, &inp, &net, vrf_id); #if defined(INET) || defined(INET6) - if ((net != NULL) && (port != 0)) { + if ((ch->chunk_type != SCTP_INITIATION) && + (net != NULL) && (net->port != port)) { if (net->port == 0) { - sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); + /* UDP encapsulation turned on. */ + net->mtu -= sizeof(struct udphdr); + if (stcb->asoc.smallest_mtu > net->mtu) { + sctp_pathmtu_adjustment(stcb, net->mtu); + } + } else if (port == 0) { + /* UDP encapsulation turned off. */ + net->mtu += sizeof(struct udphdr); + /* XXX Update smallest_mtu */ } net->port = port; } @@ -5715,9 +5724,18 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt stcb = sctp_findassociation_addr(m, offset, src, dst, sh, ch, &inp, &net, vrf_id); #if defined(INET) || defined(INET6) - if ((net != NULL) && (port != 0)) { + if ((ch->chunk_type != SCTP_INITIATION) && + (net != NULL) && (net->port != port)) { if (net->port == 0) { - sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); + /* UDP encapsulation turned on. */ + net->mtu -= sizeof(struct udphdr); + if (stcb->asoc.smallest_mtu > net->mtu) { + sctp_pathmtu_adjustment(stcb, net->mtu); + } + } else if (port == 0) { + /* UDP encapsulation turned off. */ + net->mtu += sizeof(struct udphdr); + /* XXX Update smallest_mtu */ } net->port = port; } @@ -5827,9 +5845,18 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt */ inp = stcb->sctp_ep; #if defined(INET) || defined(INET6) - if ((net != NULL) && (port != 0)) { + if ((ch->chunk_type != SCTP_INITIATION) && + (net != NULL) && (net->port != port)) { if (net->port == 0) { - sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); + /* UDP encapsulation turned on. */ + net->mtu -= sizeof(struct udphdr); + if (stcb->asoc.smallest_mtu > net->mtu) { + sctp_pathmtu_adjustment(stcb, net->mtu); + } + } else if (port == 0) { + /* UDP encapsulation turned off. */ + net->mtu += sizeof(struct udphdr); + /* XXX Update smallest_mtu */ } net->port = port; } |