aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/sctp.h7
-rw-r--r--include/net/sctp/structs.h6
-rw-r--r--net/sctp/associola.c4
-rw-r--r--net/sctp/input.c8
-rw-r--r--net/sctp/socket.c3
5 files changed, 27 insertions, 1 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index dda72bf5b9b4..16baef4dab7e 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -503,6 +503,13 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
503 return frag; 503 return frag;
504} 504}
505 505
506static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc)
507{
508
509 sctp_assoc_sync_pmtu(asoc);
510 asoc->pmtu_pending = 0;
511}
512
506/* Walk through a list of TLV parameters. Don't trust the 513/* Walk through a list of TLV parameters. Don't trust the
507 * individual parameter lengths and instead depend on 514 * individual parameter lengths and instead depend on
508 * the chunk length to indicate when to stop. Make sure 515 * the chunk length to indicate when to stop. Make sure
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index dc0e70cb0f8b..ee4559b11302 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -912,6 +912,9 @@ struct sctp_transport {
912 */ 912 */
913 __u16 pathmaxrxt; 913 __u16 pathmaxrxt;
914 914
915 /* is the Path MTU update pending on this tranport */
916 __u8 pmtu_pending;
917
915 /* PMTU : The current known path MTU. */ 918 /* PMTU : The current known path MTU. */
916 __u32 pathmtu; 919 __u32 pathmtu;
917 920
@@ -1566,6 +1569,9 @@ struct sctp_association {
1566 */ 1569 */
1567 __u16 pathmaxrxt; 1570 __u16 pathmaxrxt;
1568 1571
1572 /* Flag that path mtu update is pending */
1573 __u8 pmtu_pending;
1574
1569 /* Association : The smallest PMTU discovered for all of the 1575 /* Association : The smallest PMTU discovered for all of the
1570 * PMTU : peer's transport addresses. 1576 * PMTU : peer's transport addresses.
1571 */ 1577 */
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index df94e3cdfba3..498edb0cd4e5 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1231,6 +1231,10 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
1231 /* Get the lowest pmtu of all the transports. */ 1231 /* Get the lowest pmtu of all the transports. */
1232 list_for_each(pos, &asoc->peer.transport_addr_list) { 1232 list_for_each(pos, &asoc->peer.transport_addr_list) {
1233 t = list_entry(pos, struct sctp_transport, transports); 1233 t = list_entry(pos, struct sctp_transport, transports);
1234 if (t->pmtu_pending && t->dst) {
1235 sctp_transport_update_pmtu(t, dst_mtu(t->dst));
1236 t->pmtu_pending = 0;
1237 }
1234 if (!pmtu || (t->pathmtu < pmtu)) 1238 if (!pmtu || (t->pathmtu < pmtu))
1235 pmtu = t->pathmtu; 1239 pmtu = t->pathmtu;
1236 } 1240 }
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 45d6a644cf06..d57ff7f3c576 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -367,9 +367,15 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
367void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, 367void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
368 struct sctp_transport *t, __u32 pmtu) 368 struct sctp_transport *t, __u32 pmtu)
369{ 369{
370 if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu)) 370 if (!t || (t->pathmtu == pmtu))
371 return; 371 return;
372 372
373 if (sock_owned_by_user(sk)) {
374 asoc->pmtu_pending = 1;
375 t->pmtu_pending = 1;
376 return;
377 }
378
373 if (t->param_flags & SPP_PMTUD_ENABLE) { 379 if (t->param_flags & SPP_PMTUD_ENABLE) {
374 /* Update transports view of the MTU */ 380 /* Update transports view of the MTU */
375 sctp_transport_update_pmtu(t, pmtu); 381 sctp_transport_update_pmtu(t, pmtu);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 45510c46c223..6edaaa009d62 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1662,6 +1662,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1662 goto out_free; 1662 goto out_free;
1663 } 1663 }
1664 1664
1665 if (asoc->pmtu_pending)
1666 sctp_assoc_pending_pmtu(asoc);
1667
1665 /* If fragmentation is disabled and the message length exceeds the 1668 /* If fragmentation is disabled and the message length exceeds the
1666 * association fragmentation point, return EMSGSIZE. The I-D 1669 * association fragmentation point, return EMSGSIZE. The I-D
1667 * does not specify what this error is, but this looks like 1670 * does not specify what this error is, but this looks like