net: use the macros defined for the members of flowi
[linux-3.10.git] / net / rxrpc / ar-peer.c
index 69ac355..a53fb25 100644 (file)
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/icmp.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <net/ip.h>
+#include <net/route.h>
 #include "ar-internal.h"
 
 static LIST_HEAD(rxrpc_peers);
@@ -28,6 +30,47 @@ static DECLARE_WAIT_QUEUE_HEAD(rxrpc_peer_wq);
 static void rxrpc_destroy_peer(struct work_struct *work);
 
 /*
+ * assess the MTU size for the network interface through which this peer is
+ * reached
+ */
+static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
+{
+       struct rtable *rt;
+       struct flowi fl;
+       int ret;
+
+       peer->if_mtu = 1500;
+
+       memset(&fl, 0, sizeof(fl));
+
+       switch (peer->srx.transport.family) {
+       case AF_INET:
+               fl.oif = 0;
+               fl.proto = IPPROTO_UDP,
+               fl.fl4_dst = peer->srx.transport.sin.sin_addr.s_addr;
+               fl.fl4_src = 0;
+               fl.fl4_tos = 0;
+               /* assume AFS.CM talking to AFS.FS */
+               fl.fl_ip_sport = htons(7001);
+               fl.fl_ip_dport = htons(7000);
+               break;
+       default:
+               BUG();
+       }
+
+       ret = ip_route_output_key(&init_net, &rt, &fl);
+       if (ret < 0) {
+               _leave(" [route err %d]", ret);
+               return;
+       }
+
+       peer->if_mtu = dst_mtu(&rt->dst);
+       dst_release(&rt->dst);
+
+       _leave(" [if_mtu %u]", peer->if_mtu);
+}
+
+/*
  * allocate a new peer
  */
 static struct rxrpc_peer *rxrpc_alloc_peer(struct sockaddr_rxrpc *srx,
@@ -47,7 +90,8 @@ static struct rxrpc_peer *rxrpc_alloc_peer(struct sockaddr_rxrpc *srx,
                peer->debug_id = atomic_inc_return(&rxrpc_debug_id);
                memcpy(&peer->srx, srx, sizeof(*srx));
 
-               peer->mtu = peer->if_mtu = 65535;
+               rxrpc_assess_MTU_size(peer);
+               peer->mtu = peer->if_mtu;
 
                if (srx->transport.family == AF_INET) {
                        peer->hdrsize = sizeof(struct iphdr);
@@ -80,10 +124,10 @@ struct rxrpc_peer *rxrpc_get_peer(struct sockaddr_rxrpc *srx, gfp_t gfp)
        const char *new = "old";
        int usage;
 
-       _enter("{%d,%d,%u.%u.%u.%u+%hu}",
+       _enter("{%d,%d,%pI4+%hu}",
               srx->transport_type,
               srx->transport_len,
-              NIPQUAD(srx->transport.sin.sin_addr),
+              &srx->transport.sin.sin_addr,
               ntohs(srx->transport.sin.sin_port));
 
        /* search the peer list first */
@@ -134,12 +178,12 @@ struct rxrpc_peer *rxrpc_get_peer(struct sockaddr_rxrpc *srx, gfp_t gfp)
        new = "new";
 
 success:
-       _net("PEER %s %d {%d,%u,%u.%u.%u.%u+%hu}",
+       _net("PEER %s %d {%d,%u,%pI4+%hu}",
             new,
             peer->debug_id,
             peer->srx.transport_type,
             peer->srx.transport.family,
-            NIPQUAD(peer->srx.transport.sin.sin_addr),
+            &peer->srx.transport.sin.sin_addr,
             ntohs(peer->srx.transport.sin.sin_port));
 
        _leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
@@ -219,7 +263,7 @@ void rxrpc_put_peer(struct rxrpc_peer *peer)
                return;
        }
 
-       schedule_work(&peer->destroyer);
+       rxrpc_queue_work(&peer->destroyer);
        _leave("");
 }