diff options
Diffstat (limited to 'net/rxrpc/ar-peer.c')
-rw-r--r-- | net/rxrpc/ar-peer.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c index d399de4a7fe2..ce08b78647ce 100644 --- a/net/rxrpc/ar-peer.c +++ b/net/rxrpc/ar-peer.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <net/sock.h> | 19 | #include <net/sock.h> |
20 | #include <net/af_rxrpc.h> | 20 | #include <net/af_rxrpc.h> |
21 | #include <net/ip.h> | 21 | #include <net/ip.h> |
22 | #include <net/route.h> | ||
22 | #include "ar-internal.h" | 23 | #include "ar-internal.h" |
23 | 24 | ||
24 | static LIST_HEAD(rxrpc_peers); | 25 | static LIST_HEAD(rxrpc_peers); |
@@ -28,6 +29,47 @@ static DECLARE_WAIT_QUEUE_HEAD(rxrpc_peer_wq); | |||
28 | static void rxrpc_destroy_peer(struct work_struct *work); | 29 | static void rxrpc_destroy_peer(struct work_struct *work); |
29 | 30 | ||
30 | /* | 31 | /* |
32 | * assess the MTU size for the network interface through which this peer is | ||
33 | * reached | ||
34 | */ | ||
35 | static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) | ||
36 | { | ||
37 | struct rtable *rt; | ||
38 | struct flowi fl; | ||
39 | int ret; | ||
40 | |||
41 | peer->if_mtu = 1500; | ||
42 | |||
43 | memset(&fl, 0, sizeof(fl)); | ||
44 | |||
45 | switch (peer->srx.transport.family) { | ||
46 | case AF_INET: | ||
47 | fl.oif = 0; | ||
48 | fl.proto = IPPROTO_UDP, | ||
49 | fl.nl_u.ip4_u.saddr = 0; | ||
50 | fl.nl_u.ip4_u.daddr = peer->srx.transport.sin.sin_addr.s_addr; | ||
51 | fl.nl_u.ip4_u.tos = 0; | ||
52 | /* assume AFS.CM talking to AFS.FS */ | ||
53 | fl.uli_u.ports.sport = htons(7001); | ||
54 | fl.uli_u.ports.dport = htons(7000); | ||
55 | break; | ||
56 | default: | ||
57 | BUG(); | ||
58 | } | ||
59 | |||
60 | ret = ip_route_output_key(&rt, &fl); | ||
61 | if (ret < 0) { | ||
62 | kleave(" [route err %d]", ret); | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | peer->if_mtu = dst_mtu(&rt->u.dst); | ||
67 | dst_release(&rt->u.dst); | ||
68 | |||
69 | kleave(" [if_mtu %u]", peer->if_mtu); | ||
70 | } | ||
71 | |||
72 | /* | ||
31 | * allocate a new peer | 73 | * allocate a new peer |
32 | */ | 74 | */ |
33 | static struct rxrpc_peer *rxrpc_alloc_peer(struct sockaddr_rxrpc *srx, | 75 | static struct rxrpc_peer *rxrpc_alloc_peer(struct sockaddr_rxrpc *srx, |
@@ -47,7 +89,8 @@ static struct rxrpc_peer *rxrpc_alloc_peer(struct sockaddr_rxrpc *srx, | |||
47 | peer->debug_id = atomic_inc_return(&rxrpc_debug_id); | 89 | peer->debug_id = atomic_inc_return(&rxrpc_debug_id); |
48 | memcpy(&peer->srx, srx, sizeof(*srx)); | 90 | memcpy(&peer->srx, srx, sizeof(*srx)); |
49 | 91 | ||
50 | peer->mtu = peer->if_mtu = 65535; | 92 | rxrpc_assess_MTU_size(peer); |
93 | peer->mtu = peer->if_mtu; | ||
51 | 94 | ||
52 | if (srx->transport.family == AF_INET) { | 95 | if (srx->transport.family == AF_INET) { |
53 | peer->hdrsize = sizeof(struct iphdr); | 96 | peer->hdrsize = sizeof(struct iphdr); |