SUNRPC: add a new svc_find_listener helper
authorJeff Layton <jlayton@kernel.org>
Tue, 23 Apr 2024 13:25:43 +0000 (15:25 +0200)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 6 May 2024 13:07:22 +0000 (09:07 -0400)
svc_find_listener will return the transport instance pointer for the
endpoint accepting connections/peer traffic from the specified transport
class and matching sockaddr.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/linux/sunrpc/svc_xprt.h
net/sunrpc/svc_xprt.c

index 0d9b10dbe07d19a636af443c714407b609cbac34..0981e35a9fedae1307610e0c5098de044fa18968 100644 (file)
@@ -150,6 +150,8 @@ void        svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt);
 void   svc_xprt_close(struct svc_xprt *xprt);
 int    svc_port_is_privileged(struct sockaddr *sin);
 int    svc_print_xprts(char *buf, int maxlen);
+struct svc_xprt *svc_find_listener(struct svc_serv *serv, const char *xcl_name,
+                                  struct net *net, const struct sockaddr *sa);
 struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
                        struct net *net, const sa_family_t af,
                        const unsigned short port);
index 463fe544ae285e208ea0696c8f88419073ab18f3..34a3626c56b1b933e7d38cb9dc7364f93f47ea33 100644 (file)
@@ -1276,6 +1276,40 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
        return dr;
 }
 
+/**
+ * svc_find_listener - find an RPC transport instance
+ * @serv: pointer to svc_serv to search
+ * @xcl_name: C string containing transport's class name
+ * @net: owner net pointer
+ * @sa: sockaddr containing address
+ *
+ * Return the transport instance pointer for the endpoint accepting
+ * connections/peer traffic from the specified transport class,
+ * and matching sockaddr.
+ */
+struct svc_xprt *svc_find_listener(struct svc_serv *serv, const char *xcl_name,
+                                  struct net *net, const struct sockaddr *sa)
+{
+       struct svc_xprt *xprt;
+       struct svc_xprt *found = NULL;
+
+       spin_lock_bh(&serv->sv_lock);
+       list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
+               if (xprt->xpt_net != net)
+                       continue;
+               if (strcmp(xprt->xpt_class->xcl_name, xcl_name))
+                       continue;
+               if (!rpc_cmp_addr_port(sa, (struct sockaddr *)&xprt->xpt_local))
+                       continue;
+               found = xprt;
+               svc_xprt_get(xprt);
+               break;
+       }
+       spin_unlock_bh(&serv->sv_lock);
+       return found;
+}
+EXPORT_SYMBOL_GPL(svc_find_listener);
+
 /**
  * svc_find_xprt - find an RPC transport instance
  * @serv: pointer to svc_serv to search