]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - include/linux/lockd/lockd.h
NLM: nlm_privileged_requester() doesn't recognize mapped loopback address
[mv-sheeva.git] / include / linux / lockd / lockd.h
index b56d5aa9b194c0d87296b303874d331b84246413..80d7e8a8257d4e578f39d48c82800289847b9619 100644 (file)
@@ -43,12 +43,13 @@ struct nlm_host {
        struct sockaddr_storage h_addr;         /* peer address */
        size_t                  h_addrlen;
        struct sockaddr_storage h_srcaddr;      /* our address (optional) */
-       struct rpc_clnt *       h_rpcclnt;      /* RPC client to talk to peer */
-       char *                  h_name;         /* remote hostname */
+       struct rpc_clnt         *h_rpcclnt;     /* RPC client to talk to peer */
+       char                    *h_name;                /* remote hostname */
        u32                     h_version;      /* interface version */
        unsigned short          h_proto;        /* transport proto */
        unsigned short          h_reclaiming : 1,
                                h_server     : 1, /* server side, not client side */
+                               h_noresvport : 1,
                                h_inuse      : 1;
        wait_queue_head_t       h_gracewait;    /* wait while reclaiming */
        struct rw_semaphore     h_rwsem;        /* Reboot recovery lock */
@@ -63,21 +64,29 @@ struct nlm_host {
        spinlock_t              h_lock;
        struct list_head        h_granted;      /* Locks in GRANTED state */
        struct list_head        h_reclaim;      /* Locks in RECLAIM state */
-       struct nsm_handle *     h_nsmhandle;    /* NSM status handle */
-
-       char                    h_addrbuf[48],  /* address eyecatchers */
-                               h_srcaddrbuf[48];
+       struct nsm_handle       *h_nsmhandle;   /* NSM status handle */
+       char                    *h_addrbuf;     /* address eyecatcher */
 };
 
+/*
+ * The largest string sm_addrbuf should hold is a full-size IPv6 address
+ * (no "::" anywhere) with a scope ID.  The buffer size is computed to
+ * hold eight groups of colon-separated four-hex-digit numbers, a
+ * percent sign, a scope id (at most 32 bits, in decimal), and NUL.
+ */
+#define NSM_ADDRBUF            ((8 * 4 + 7) + (1 + 10) + 1)
+
 struct nsm_handle {
        struct list_head        sm_link;
        atomic_t                sm_count;
-       char *                  sm_name;
+       char                    *sm_mon_name;
+       char                    *sm_name;
        struct sockaddr_storage sm_addr;
        size_t                  sm_addrlen;
        unsigned int            sm_monitored : 1,
                                sm_sticky : 1;  /* don't unmonitor */
-       char                    sm_addrbuf[48]; /* address eyecatcher */
+       struct nsm_private      sm_priv;
+       char                    sm_addrbuf[NSM_ADDRBUF];
 };
 
 /*
@@ -103,16 +112,6 @@ static inline struct sockaddr *nlm_srcaddr(const struct nlm_host *host)
        return (struct sockaddr *)&host->h_srcaddr;
 }
 
-static inline struct sockaddr_in *nsm_addr_in(const struct nsm_handle *handle)
-{
-       return (struct sockaddr_in *)&handle->sm_addr;
-}
-
-static inline struct sockaddr *nsm_addr(const struct nsm_handle *handle)
-{
-       return (struct sockaddr *)&handle->sm_addr;
-}
-
 /*
  * Map an fl_owner_t into a unique 32-bit "pid"
  */
@@ -196,6 +195,7 @@ extern struct svc_procedure nlmsvc_procedures4[];
 extern int                     nlmsvc_grace_period;
 extern unsigned long           nlmsvc_timeout;
 extern int                     nsm_use_hostnames;
+extern int                     nsm_local_state;
 
 /*
  * Lockd client functions
@@ -220,7 +220,8 @@ struct nlm_host  *nlmclnt_lookup_host(const struct sockaddr *sap,
                                        const size_t salen,
                                        const unsigned short protocol,
                                        const u32 version,
-                                       const char *hostname);
+                                       const char *hostname,
+                                       int noresvport);
 struct nlm_host  *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
                                        const char *hostname,
                                        const size_t hostname_len);
@@ -229,10 +230,20 @@ void                nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void             nlm_release_host(struct nlm_host *);
 void             nlm_shutdown_hosts(void);
-extern void      nlm_host_rebooted(const struct sockaddr_in *, const char *,
-                                       unsigned int, u32);
-void             nsm_release(struct nsm_handle *);
+void             nlm_host_rebooted(const struct nlm_reboot *);
 
+/*
+ * Host monitoring
+ */
+int              nsm_monitor(const struct nlm_host *host);
+void             nsm_unmonitor(const struct nlm_host *host);
+
+struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
+                                       const size_t salen,
+                                       const char *hostname,
+                                       const size_t hostname_len);
+struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info);
+void             nsm_release(struct nsm_handle *nsm);
 
 /*
  * This is used in garbage collection and resource reclaim
@@ -288,8 +299,14 @@ static inline int __nlm_privileged_request4(const struct sockaddr *sap)
 static inline int __nlm_privileged_request6(const struct sockaddr *sap)
 {
        const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
-       return (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LOOPBACK) &&
-                       (ntohs(sin6->sin6_port) < 1024);
+
+       if (ntohs(sin6->sin6_port) > 1023)
+               return 0;
+
+       if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED)
+               return ipv4_is_loopback(sin6->sin6_addr.s6_addr32[3]);
+
+       return ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LOOPBACK;
 }
 #else  /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
 static inline int __nlm_privileged_request6(const struct sockaddr *sap)