summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/structs.h1
-rw-r--r--net/sctp/input.c16
-rw-r--r--net/sctp/transport.c41
3 files changed, 44 insertions, 14 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 5e81984b847..dc0e70cb0f8 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1006,6 +1006,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
unsigned long sctp_transport_timeout(struct sctp_transport *);
void sctp_transport_reset(struct sctp_transport *);
+void sctp_transport_update_pmtu(struct sctp_transport *, u32);
/* This is the structure we use to queue packets as they come into
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 885109fb3dd..45d6a644cf0 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -371,20 +371,8 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
return;
if (t->param_flags & SPP_PMTUD_ENABLE) {
- if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
- printk(KERN_WARNING "%s: Reported pmtu %d too low, "
- "using default minimum of %d\n",
- __FUNCTION__, pmtu,
- SCTP_DEFAULT_MINSEGMENT);
- /* Use default minimum segment size and disable
- * pmtu discovery on this transport.
- */
- t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
- t->param_flags = (t->param_flags & ~SPP_PMTUD) |
- SPP_PMTUD_DISABLE;
- } else {
- t->pathmtu = pmtu;
- }
+ /* Update transports view of the MTU */
+ sctp_transport_update_pmtu(t, pmtu);
/* Update association pmtu. */
sctp_assoc_sync_pmtu(asoc);
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 961df275d5b..e14c271cf28 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -241,6 +241,47 @@ void sctp_transport_pmtu(struct sctp_transport *transport)
transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
}
+/* this is a complete rip-off from __sk_dst_check
+ * the cookie is always 0 since this is how it's used in the
+ * pmtu code
+ */
+static struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
+{
+ struct dst_entry *dst = t->dst;
+
+ if (dst && dst->obsolete && dst->ops->check(dst, 0) == NULL) {
+ dst_release(t->dst);
+ t->dst = NULL;
+ return NULL;
+ }
+
+ return dst;
+}
+
+void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
+{
+ struct dst_entry *dst;
+
+ if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
+ printk(KERN_WARNING "%s: Reported pmtu %d too low, "
+ "using default minimum of %d\n",
+ __FUNCTION__, pmtu,
+ SCTP_DEFAULT_MINSEGMENT);
+ /* Use default minimum segment size and disable
+ * pmtu discovery on this transport.
+ */
+ t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
+ t->param_flags = (t->param_flags & ~SPP_PMTUD) |
+ SPP_PMTUD_DISABLE;
+ } else {
+ t->pathmtu = pmtu;
+ }
+
+ dst = sctp_transport_dst_check(t);
+ if (dst)
+ dst->ops->update_pmtu(dst, pmtu);
+}
+
/* Caches the dst entry and source address for a transport's destination
* address.
*/