sunrpc: reply AUTH_BADCRED to RPCSEC_GSS with unknown service
[safe/jmp/linux-2.6] / net / sunrpc / xprtsock.c
index eee5ac9..62438f3 100644 (file)
@@ -299,11 +299,34 @@ static inline struct sockaddr_in6 *xs_addr_in6(struct rpc_xprt *xprt)
 static void xs_format_common_peer_addresses(struct rpc_xprt *xprt)
 {
        struct sockaddr *sap = xs_addr(xprt);
+       struct sockaddr_in6 *sin6;
+       struct sockaddr_in *sin;
        char buf[128];
 
        (void)rpc_ntop(sap, buf, sizeof(buf));
        xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL);
 
+       switch (sap->sa_family) {
+       case AF_INET:
+               sin = xs_addr_in(xprt);
+               (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x",
+                                       NIPQUAD(sin->sin_addr.s_addr));
+               break;
+       case AF_INET6:
+               sin6 = xs_addr_in6(xprt);
+               (void)snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr);
+               break;
+       default:
+               BUG();
+       }
+       xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL);
+}
+
+static void xs_format_common_peer_ports(struct rpc_xprt *xprt)
+{
+       struct sockaddr *sap = xs_addr(xprt);
+       char buf[128];
+
        (void)snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
        xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL);
 
@@ -311,37 +334,22 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt)
        xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
 }
 
-static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
-                                         const char *protocol,
-                                         const char *netid)
+static void xs_format_peer_addresses(struct rpc_xprt *xprt,
+                                    const char *protocol,
+                                    const char *netid)
 {
-       struct sockaddr_in *sin = xs_addr_in(xprt);
-       char buf[16];
-
        xprt->address_strings[RPC_DISPLAY_PROTO] = protocol;
        xprt->address_strings[RPC_DISPLAY_NETID] = netid;
-
-       (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x",
-                               NIPQUAD(sin->sin_addr.s_addr));
-       xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL);
-
        xs_format_common_peer_addresses(xprt);
+       xs_format_common_peer_ports(xprt);
 }
 
-static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
-                                         const char *protocol,
-                                         const char *netid)
+static void xs_update_peer_port(struct rpc_xprt *xprt)
 {
-       struct sockaddr_in6 *sin6 = xs_addr_in6(xprt);
-       char buf[48];
-
-       xprt->address_strings[RPC_DISPLAY_PROTO] = protocol;
-       xprt->address_strings[RPC_DISPLAY_NETID] = netid;
+       kfree(xprt->address_strings[RPC_DISPLAY_HEX_PORT]);
+       kfree(xprt->address_strings[RPC_DISPLAY_PORT]);
 
-       (void)snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr);
-       xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL);
-
-       xs_format_common_peer_addresses(xprt);
+       xs_format_common_peer_ports(xprt);
 }
 
 static void xs_free_peer_addresses(struct rpc_xprt *xprt)
@@ -1522,20 +1530,10 @@ static unsigned short xs_get_random_port(void)
  */
 static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
 {
-       struct sockaddr *addr = xs_addr(xprt);
-
        dprintk("RPC:       setting port for xprt %p to %u\n", xprt, port);
 
-       switch (addr->sa_family) {
-       case AF_INET:
-               ((struct sockaddr_in *)addr)->sin_port = htons(port);
-               break;
-       case AF_INET6:
-               ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
-               break;
-       default:
-               BUG();
-       }
+       rpc_set_port(xs_addr(xprt), port);
+       xs_update_peer_port(xprt);
 }
 
 static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket *sock)
@@ -2216,7 +2214,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
 
                INIT_DELAYED_WORK(&transport->connect_worker,
                                        xs_udp_connect_worker4);
-               xs_format_ipv4_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP);
+               xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP);
                break;
        case AF_INET6:
                if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
@@ -2224,7 +2222,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
 
                INIT_DELAYED_WORK(&transport->connect_worker,
                                        xs_udp_connect_worker6);
-               xs_format_ipv6_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6);
+               xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6);
                break;
        default:
                kfree(xprt);
@@ -2288,15 +2286,17 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
                if (((struct sockaddr_in *)addr)->sin_port != htons(0))
                        xprt_set_bound(xprt);
 
-               INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4);
-               xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
+               INIT_DELAYED_WORK(&transport->connect_worker,
+                                       xs_tcp_connect_worker4);
+               xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
                break;
        case AF_INET6:
                if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
                        xprt_set_bound(xprt);
 
-               INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6);
-               xs_format_ipv6_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6);
+               INIT_DELAYED_WORK(&transport->connect_worker,
+                                       xs_tcp_connect_worker6);
+               xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6);
                break;
        default:
                kfree(xprt);
@@ -2371,3 +2371,55 @@ void cleanup_socket_xprt(void)
        xprt_unregister_transport(&xs_udp_transport);
        xprt_unregister_transport(&xs_tcp_transport);
 }
+
+static int param_set_uint_minmax(const char *val, struct kernel_param *kp,
+               unsigned int min, unsigned int max)
+{
+       unsigned long num;
+       int ret;
+
+       if (!val)
+               return -EINVAL;
+       ret = strict_strtoul(val, 0, &num);
+       if (ret == -EINVAL || num < min || num > max)
+               return -EINVAL;
+       *((unsigned int *)kp->arg) = num;
+       return 0;
+}
+
+static int param_set_portnr(const char *val, struct kernel_param *kp)
+{
+       return param_set_uint_minmax(val, kp,
+                       RPC_MIN_RESVPORT,
+                       RPC_MAX_RESVPORT);
+}
+
+static int param_get_portnr(char *buffer, struct kernel_param *kp)
+{
+       return param_get_uint(buffer, kp);
+}
+#define param_check_portnr(name, p) \
+       __param_check(name, p, unsigned int);
+
+module_param_named(min_resvport, xprt_min_resvport, portnr, 0644);
+module_param_named(max_resvport, xprt_max_resvport, portnr, 0644);
+
+static int param_set_slot_table_size(const char *val, struct kernel_param *kp)
+{
+       return param_set_uint_minmax(val, kp,
+                       RPC_MIN_SLOT_TABLE,
+                       RPC_MAX_SLOT_TABLE);
+}
+
+static int param_get_slot_table_size(char *buffer, struct kernel_param *kp)
+{
+       return param_get_uint(buffer, kp);
+}
+#define param_check_slot_table_size(name, p) \
+       __param_check(name, p, unsigned int);
+
+module_param_named(tcp_slot_table_entries, xprt_tcp_slot_table_entries,
+                  slot_table_size, 0644);
+module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries,
+                  slot_table_size, 0644);
+