diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-16 06:57:14 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-16 06:57:14 -0400 |
commit | 02f3d4ce9e81434a365f4643020b0402f6fe3332 (patch) | |
tree | 8fd12d62c3d92ed090d1d7e5f92750bef951b914 /net/sctp | |
parent | 35ad9b9cf7d8a2e6259a0d24022e910adb6f3489 (diff) |
sctp: Adjust PMTU updates to accomodate route invalidation.
This adjusts the call to dst_ops->update_pmtu() so that we can
transparently handle the fact that, in the future, the dst itself can
be invalidated by the PMTU update (when we have non-host routes cached
in sockets).
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/associola.c | 4 | ||||
-rw-r--r-- | net/sctp/input.c | 4 | ||||
-rw-r--r-- | net/sctp/output.c | 2 | ||||
-rw-r--r-- | net/sctp/socket.c | 6 | ||||
-rw-r--r-- | net/sctp/transport.c | 12 |
5 files changed, 18 insertions, 10 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index b16517ee1aaf..8cf348e62e74 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -1360,7 +1360,7 @@ struct sctp_transport *sctp_assoc_choose_alter_transport( | |||
1360 | /* Update the association's pmtu and frag_point by going through all the | 1360 | /* Update the association's pmtu and frag_point by going through all the |
1361 | * transports. This routine is called when a transport's PMTU has changed. | 1361 | * transports. This routine is called when a transport's PMTU has changed. |
1362 | */ | 1362 | */ |
1363 | void sctp_assoc_sync_pmtu(struct sctp_association *asoc) | 1363 | void sctp_assoc_sync_pmtu(struct sock *sk, struct sctp_association *asoc) |
1364 | { | 1364 | { |
1365 | struct sctp_transport *t; | 1365 | struct sctp_transport *t; |
1366 | __u32 pmtu = 0; | 1366 | __u32 pmtu = 0; |
@@ -1372,7 +1372,7 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc) | |||
1372 | list_for_each_entry(t, &asoc->peer.transport_addr_list, | 1372 | list_for_each_entry(t, &asoc->peer.transport_addr_list, |
1373 | transports) { | 1373 | transports) { |
1374 | if (t->pmtu_pending && t->dst) { | 1374 | if (t->pmtu_pending && t->dst) { |
1375 | sctp_transport_update_pmtu(t, dst_mtu(t->dst)); | 1375 | sctp_transport_update_pmtu(sk, t, dst_mtu(t->dst)); |
1376 | t->pmtu_pending = 0; | 1376 | t->pmtu_pending = 0; |
1377 | } | 1377 | } |
1378 | if (!pmtu || (t->pathmtu < pmtu)) | 1378 | if (!pmtu || (t->pathmtu < pmtu)) |
diff --git a/net/sctp/input.c b/net/sctp/input.c index f050d45faa98..a67bc31f49fd 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -408,10 +408,10 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
408 | 408 | ||
409 | if (t->param_flags & SPP_PMTUD_ENABLE) { | 409 | if (t->param_flags & SPP_PMTUD_ENABLE) { |
410 | /* Update transports view of the MTU */ | 410 | /* Update transports view of the MTU */ |
411 | sctp_transport_update_pmtu(t, pmtu); | 411 | sctp_transport_update_pmtu(sk, t, pmtu); |
412 | 412 | ||
413 | /* Update association pmtu. */ | 413 | /* Update association pmtu. */ |
414 | sctp_assoc_sync_pmtu(asoc); | 414 | sctp_assoc_sync_pmtu(sk, asoc); |
415 | } | 415 | } |
416 | 416 | ||
417 | /* Retransmit with the new pmtu setting. | 417 | /* Retransmit with the new pmtu setting. |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 539f35d07f4e..838e18b4d7ea 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -410,7 +410,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
410 | if (!sctp_transport_dst_check(tp)) { | 410 | if (!sctp_transport_dst_check(tp)) { |
411 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | 411 | sctp_transport_route(tp, NULL, sctp_sk(sk)); |
412 | if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { | 412 | if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { |
413 | sctp_assoc_sync_pmtu(asoc); | 413 | sctp_assoc_sync_pmtu(sk, asoc); |
414 | } | 414 | } |
415 | } | 415 | } |
416 | dst = dst_clone(tp->dst); | 416 | dst = dst_clone(tp->dst); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b3b8a8d813eb..74bd3c47350a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1853,7 +1853,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1853 | } | 1853 | } |
1854 | 1854 | ||
1855 | if (asoc->pmtu_pending) | 1855 | if (asoc->pmtu_pending) |
1856 | sctp_assoc_pending_pmtu(asoc); | 1856 | sctp_assoc_pending_pmtu(sk, asoc); |
1857 | 1857 | ||
1858 | /* If fragmentation is disabled and the message length exceeds the | 1858 | /* If fragmentation is disabled and the message length exceeds the |
1859 | * association fragmentation point, return EMSGSIZE. The I-D | 1859 | * association fragmentation point, return EMSGSIZE. The I-D |
@@ -2365,7 +2365,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2365 | if ((params->spp_flags & SPP_PMTUD_DISABLE) && params->spp_pathmtu) { | 2365 | if ((params->spp_flags & SPP_PMTUD_DISABLE) && params->spp_pathmtu) { |
2366 | if (trans) { | 2366 | if (trans) { |
2367 | trans->pathmtu = params->spp_pathmtu; | 2367 | trans->pathmtu = params->spp_pathmtu; |
2368 | sctp_assoc_sync_pmtu(asoc); | 2368 | sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc); |
2369 | } else if (asoc) { | 2369 | } else if (asoc) { |
2370 | asoc->pathmtu = params->spp_pathmtu; | 2370 | asoc->pathmtu = params->spp_pathmtu; |
2371 | sctp_frag_point(asoc, params->spp_pathmtu); | 2371 | sctp_frag_point(asoc, params->spp_pathmtu); |
@@ -2382,7 +2382,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2382 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; | 2382 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; |
2383 | if (update) { | 2383 | if (update) { |
2384 | sctp_transport_pmtu(trans, sctp_opt2sk(sp)); | 2384 | sctp_transport_pmtu(trans, sctp_opt2sk(sp)); |
2385 | sctp_assoc_sync_pmtu(asoc); | 2385 | sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc); |
2386 | } | 2386 | } |
2387 | } else if (asoc) { | 2387 | } else if (asoc) { |
2388 | asoc->param_flags = | 2388 | asoc->param_flags = |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 1dcceb6e0ce6..e69e1a2175a4 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -228,7 +228,7 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) | |||
228 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | 228 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
229 | } | 229 | } |
230 | 230 | ||
231 | void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) | 231 | void sctp_transport_update_pmtu(struct sock *sk, struct sctp_transport *t, u32 pmtu) |
232 | { | 232 | { |
233 | struct dst_entry *dst; | 233 | struct dst_entry *dst; |
234 | 234 | ||
@@ -245,8 +245,16 @@ void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) | |||
245 | } | 245 | } |
246 | 246 | ||
247 | dst = sctp_transport_dst_check(t); | 247 | dst = sctp_transport_dst_check(t); |
248 | if (dst) | 248 | if (!dst) |
249 | t->af_specific->get_dst(t, &t->saddr, &t->fl, sk); | ||
250 | |||
251 | if (dst) { | ||
249 | dst->ops->update_pmtu(dst, pmtu); | 252 | dst->ops->update_pmtu(dst, pmtu); |
253 | |||
254 | dst = sctp_transport_dst_check(t); | ||
255 | if (!dst) | ||
256 | t->af_specific->get_dst(t, &t->saddr, &t->fl, sk); | ||
257 | } | ||
250 | } | 258 | } |
251 | 259 | ||
252 | /* Caches the dst entry and source address for a transport's destination | 260 | /* Caches the dst entry and source address for a transport's destination |