@@ -211,51 +211,6 @@ void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
211211}
212212EXPORT_SYMBOL_GPL (svc_xprt_init );
213213
214- static struct svc_xprt * __svc_xpo_create (struct svc_xprt_class * xcl ,
215- struct svc_serv * serv ,
216- struct net * net ,
217- const int family ,
218- const unsigned short port ,
219- int flags )
220- {
221- struct sockaddr_in sin = {
222- .sin_family = AF_INET ,
223- .sin_addr .s_addr = htonl (INADDR_ANY ),
224- .sin_port = htons (port ),
225- };
226- #if IS_ENABLED (CONFIG_IPV6 )
227- struct sockaddr_in6 sin6 = {
228- .sin6_family = AF_INET6 ,
229- .sin6_addr = IN6ADDR_ANY_INIT ,
230- .sin6_port = htons (port ),
231- };
232- #endif
233- struct svc_xprt * xprt ;
234- struct sockaddr * sap ;
235- size_t len ;
236-
237- switch (family ) {
238- case PF_INET :
239- sap = (struct sockaddr * )& sin ;
240- len = sizeof (sin );
241- break ;
242- #if IS_ENABLED (CONFIG_IPV6 )
243- case PF_INET6 :
244- sap = (struct sockaddr * )& sin6 ;
245- len = sizeof (sin6 );
246- break ;
247- #endif
248- default :
249- return ERR_PTR (- EAFNOSUPPORT );
250- }
251-
252- xprt = xcl -> xcl_ops -> xpo_create (serv , net , sap , len , flags );
253- if (IS_ERR (xprt ))
254- trace_svc_xprt_create_err (serv -> sv_program -> pg_name ,
255- xcl -> xcl_name , sap , len , xprt );
256- return xprt ;
257- }
258-
259214/**
260215 * svc_xprt_received - start next receiver thread
261216 * @xprt: controlling transport
@@ -294,9 +249,8 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new)
294249}
295250
296251static int _svc_xprt_create (struct svc_serv * serv , const char * xprt_name ,
297- struct net * net , const int family ,
298- const unsigned short port , int flags ,
299- const struct cred * cred )
252+ struct net * net , struct sockaddr * sap ,
253+ size_t len , int flags , const struct cred * cred )
300254{
301255 struct svc_xprt_class * xcl ;
302256
@@ -312,8 +266,11 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
312266 goto err ;
313267
314268 spin_unlock (& svc_xprt_class_lock );
315- newxprt = __svc_xpo_create ( xcl , serv , net , family , port , flags );
269+ newxprt = xcl -> xcl_ops -> xpo_create ( serv , net , sap , len , flags );
316270 if (IS_ERR (newxprt )) {
271+ trace_svc_xprt_create_err (serv -> sv_program -> pg_name ,
272+ xcl -> xcl_name , sap , len ,
273+ newxprt );
317274 module_put (xcl -> xcl_owner );
318275 return PTR_ERR (newxprt );
319276 }
@@ -329,6 +286,48 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
329286 return - EPROTONOSUPPORT ;
330287}
331288
289+ /**
290+ * svc_xprt_create_from_sa - Add a new listener to @serv from socket address
291+ * @serv: target RPC service
292+ * @xprt_name: transport class name
293+ * @net: network namespace
294+ * @sap: socket address pointer
295+ * @flags: SVC_SOCK flags
296+ * @cred: credential to bind to this transport
297+ *
298+ * Return local xprt port on success or %-EPROTONOSUPPORT on failure
299+ */
300+ int svc_xprt_create_from_sa (struct svc_serv * serv , const char * xprt_name ,
301+ struct net * net , struct sockaddr * sap ,
302+ int flags , const struct cred * cred )
303+ {
304+ size_t len ;
305+ int err ;
306+
307+ switch (sap -> sa_family ) {
308+ case AF_INET :
309+ len = sizeof (struct sockaddr_in );
310+ break ;
311+ #if IS_ENABLED (CONFIG_IPV6 )
312+ case AF_INET6 :
313+ len = sizeof (struct sockaddr_in6 );
314+ break ;
315+ #endif
316+ default :
317+ return - EAFNOSUPPORT ;
318+ }
319+
320+ err = _svc_xprt_create (serv , xprt_name , net , sap , len , flags , cred );
321+ if (err == - EPROTONOSUPPORT ) {
322+ request_module ("svc%s" , xprt_name );
323+ err = _svc_xprt_create (serv , xprt_name , net , sap , len , flags ,
324+ cred );
325+ }
326+
327+ return err ;
328+ }
329+ EXPORT_SYMBOL_GPL (svc_xprt_create_from_sa );
330+
332331/**
333332 * svc_xprt_create - Add a new listener to @serv
334333 * @serv: target RPC service
@@ -339,23 +338,41 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
339338 * @flags: SVC_SOCK flags
340339 * @cred: credential to bind to this transport
341340 *
342- * Return values:
343- * %0: New listener added successfully
344- * %-EPROTONOSUPPORT: Requested transport type not supported
341+ * Return local xprt port on success or %-EPROTONOSUPPORT on failure
345342 */
346343int svc_xprt_create (struct svc_serv * serv , const char * xprt_name ,
347344 struct net * net , const int family ,
348345 const unsigned short port , int flags ,
349346 const struct cred * cred )
350347{
351- int err ;
348+ struct sockaddr_in sin = {
349+ .sin_family = AF_INET ,
350+ .sin_addr .s_addr = htonl (INADDR_ANY ),
351+ .sin_port = htons (port ),
352+ };
353+ #if IS_ENABLED (CONFIG_IPV6 )
354+ struct sockaddr_in6 sin6 = {
355+ .sin6_family = AF_INET6 ,
356+ .sin6_addr = IN6ADDR_ANY_INIT ,
357+ .sin6_port = htons (port ),
358+ };
359+ #endif
360+ struct sockaddr * sap ;
352361
353- err = _svc_xprt_create (serv , xprt_name , net , family , port , flags , cred );
354- if (err == - EPROTONOSUPPORT ) {
355- request_module ("svc%s" , xprt_name );
356- err = _svc_xprt_create (serv , xprt_name , net , family , port , flags , cred );
362+ switch (family ) {
363+ case PF_INET :
364+ sap = (struct sockaddr * )& sin ;
365+ break ;
366+ #if IS_ENABLED (CONFIG_IPV6 )
367+ case PF_INET6 :
368+ sap = (struct sockaddr * )& sin6 ;
369+ break ;
370+ #endif
371+ default :
372+ return - EAFNOSUPPORT ;
357373 }
358- return err ;
374+
375+ return svc_xprt_create_from_sa (serv , xprt_name , net , sap , flags , cred );
359376}
360377EXPORT_SYMBOL_GPL (svc_xprt_create );
361378
0 commit comments