diff options
-rw-r--r-- | include/net/sctp/sctp.h | 7 | ||||
-rw-r--r-- | include/net/sctp/structs.h | 6 | ||||
-rw-r--r-- | net/sctp/associola.c | 4 | ||||
-rw-r--r-- | net/sctp/input.c | 8 | ||||
-rw-r--r-- | net/sctp/socket.c | 3 |
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 | ||
506 | static 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) | |||
367 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | 367 | void 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 |