Commit 8a479491 authored by Vlad Yasevich's avatar Vlad Yasevich Committed by Vladislav Yasevich

[SCTP] Flag a pmtu change request

Currently, if the socket is owned by the user, we drop the ICMP
message.  As a result SCTP forgets that path MTU changed and
never adjusting it's estimate.  This causes all subsequent
packets to be fragmented.  With this patch, we'll flag the association
that it needs to udpate it's estimate based on the already updated
routing information.
Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Acked-by: default avatarSridhar Samudrala <sri@us.ibm.com>
parent c910b47e
...@@ -503,6 +503,13 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu) ...@@ -503,6 +503,13 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
return frag; return frag;
} }
static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc)
{
sctp_assoc_sync_pmtu(asoc);
asoc->pmtu_pending = 0;
}
/* Walk through a list of TLV parameters. Don't trust the /* Walk through a list of TLV parameters. Don't trust the
* individual parameter lengths and instead depend on * individual parameter lengths and instead depend on
* the chunk length to indicate when to stop. Make sure * the chunk length to indicate when to stop. Make sure
......
...@@ -912,6 +912,9 @@ struct sctp_transport { ...@@ -912,6 +912,9 @@ struct sctp_transport {
*/ */
__u16 pathmaxrxt; __u16 pathmaxrxt;
/* is the Path MTU update pending on this tranport */
__u8 pmtu_pending;
/* PMTU : The current known path MTU. */ /* PMTU : The current known path MTU. */
__u32 pathmtu; __u32 pathmtu;
...@@ -1566,6 +1569,9 @@ struct sctp_association { ...@@ -1566,6 +1569,9 @@ struct sctp_association {
*/ */
__u16 pathmaxrxt; __u16 pathmaxrxt;
/* Flag that path mtu update is pending */
__u8 pmtu_pending;
/* Association : The smallest PMTU discovered for all of the /* Association : The smallest PMTU discovered for all of the
* PMTU : peer's transport addresses. * PMTU : peer's transport addresses.
*/ */
......
...@@ -1231,6 +1231,10 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc) ...@@ -1231,6 +1231,10 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
/* Get the lowest pmtu of all the transports. */ /* Get the lowest pmtu of all the transports. */
list_for_each(pos, &asoc->peer.transport_addr_list) { list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, struct sctp_transport, transports); t = list_entry(pos, struct sctp_transport, transports);
if (t->pmtu_pending && t->dst) {
sctp_transport_update_pmtu(t, dst_mtu(t->dst));
t->pmtu_pending = 0;
}
if (!pmtu || (t->pathmtu < pmtu)) if (!pmtu || (t->pathmtu < pmtu))
pmtu = t->pathmtu; pmtu = t->pathmtu;
} }
......
...@@ -367,9 +367,15 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb) ...@@ -367,9 +367,15 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
struct sctp_transport *t, __u32 pmtu) struct sctp_transport *t, __u32 pmtu)
{ {
if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu)) if (!t || (t->pathmtu == pmtu))
return; return;
if (sock_owned_by_user(sk)) {
asoc->pmtu_pending = 1;
t->pmtu_pending = 1;
return;
}
if (t->param_flags & SPP_PMTUD_ENABLE) { if (t->param_flags & SPP_PMTUD_ENABLE) {
/* Update transports view of the MTU */ /* Update transports view of the MTU */
sctp_transport_update_pmtu(t, pmtu); sctp_transport_update_pmtu(t, pmtu);
......
...@@ -1662,6 +1662,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -1662,6 +1662,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_free; goto out_free;
} }
if (asoc->pmtu_pending)
sctp_assoc_pending_pmtu(asoc);
/* If fragmentation is disabled and the message length exceeds the /* If fragmentation is disabled and the message length exceeds the
* association fragmentation point, return EMSGSIZE. The I-D * association fragmentation point, return EMSGSIZE. The I-D
* does not specify what this error is, but this looks like * does not specify what this error is, but this looks like
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment