aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth_gss
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-01-19 12:42:37 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-31 19:28:15 -0500
commita1db410d0bbadc49943f0fcddb21702ceb429396 (patch)
tree09f1a94d7c4ef70d6122f936b1fa309996f170ee /net/sunrpc/auth_gss
parent73393232d6a425b6bb4cee590e3e66fc52532a15 (diff)
SUNRPC: create GSS auth cache per network namespace
This patch makes GSS auth cache details allocated and registered per network namespace context. Thus with this patch rsi_cache and rsc_cache contents for network namespace "X" are controlled from proc file system mount for the same network namespace "X". Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Acked-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc/auth_gss')
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c21
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c165
2 files changed, 136 insertions, 50 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 5ebb602cabe0..cb2e56452748 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1662,6 +1662,21 @@ static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
1662 .release_pipe = gss_pipe_release, 1662 .release_pipe = gss_pipe_release,
1663}; 1663};
1664 1664
1665static __net_init int rpcsec_gss_init_net(struct net *net)
1666{
1667 return gss_svc_init_net(net);
1668}
1669
1670static __net_exit void rpcsec_gss_exit_net(struct net *net)
1671{
1672 gss_svc_shutdown_net(net);
1673}
1674
1675static struct pernet_operations rpcsec_gss_net_ops = {
1676 .init = rpcsec_gss_init_net,
1677 .exit = rpcsec_gss_exit_net,
1678};
1679
1665/* 1680/*
1666 * Initialize RPCSEC_GSS module 1681 * Initialize RPCSEC_GSS module
1667 */ 1682 */
@@ -1675,8 +1690,13 @@ static int __init init_rpcsec_gss(void)
1675 err = gss_svc_init(); 1690 err = gss_svc_init();
1676 if (err) 1691 if (err)
1677 goto out_unregister; 1692 goto out_unregister;
1693 err = register_pernet_subsys(&rpcsec_gss_net_ops);
1694 if (err)
1695 goto out_svc_exit;
1678 rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); 1696 rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
1679 return 0; 1697 return 0;
1698out_svc_exit:
1699 gss_svc_shutdown();
1680out_unregister: 1700out_unregister:
1681 rpcauth_unregister(&authgss_ops); 1701 rpcauth_unregister(&authgss_ops);
1682out: 1702out:
@@ -1685,6 +1705,7 @@ out:
1685 1705
1686static void __exit exit_rpcsec_gss(void) 1706static void __exit exit_rpcsec_gss(void)
1687{ 1707{
1708 unregister_pernet_subsys(&rpcsec_gss_net_ops);
1688 gss_svc_shutdown(); 1709 gss_svc_shutdown();
1689 rpcauth_unregister(&authgss_ops); 1710 rpcauth_unregister(&authgss_ops);
1690 rcu_barrier(); /* Wait for completion of call_rcu()'s */ 1711 rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 8d0f7d3c71c8..1600cfb1618c 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -48,6 +48,8 @@
48#include <linux/sunrpc/svcauth_gss.h> 48#include <linux/sunrpc/svcauth_gss.h>
49#include <linux/sunrpc/cache.h> 49#include <linux/sunrpc/cache.h>
50 50
51#include "../netns.h"
52
51#ifdef RPC_DEBUG 53#ifdef RPC_DEBUG
52# define RPCDBG_FACILITY RPCDBG_AUTH 54# define RPCDBG_FACILITY RPCDBG_AUTH
53#endif 55#endif
@@ -75,10 +77,8 @@ struct rsi {
75 int major_status, minor_status; 77 int major_status, minor_status;
76}; 78};
77 79
78static struct cache_head *rsi_table[RSI_HASHMAX]; 80static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
79static struct cache_detail rsi_cache; 81static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item);
80static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
81static struct rsi *rsi_lookup(struct rsi *item);
82 82
83static void rsi_free(struct rsi *rsii) 83static void rsi_free(struct rsi *rsii)
84{ 84{
@@ -216,7 +216,7 @@ static int rsi_parse(struct cache_detail *cd,
216 if (dup_to_netobj(&rsii.in_token, buf, len)) 216 if (dup_to_netobj(&rsii.in_token, buf, len))
217 goto out; 217 goto out;
218 218
219 rsip = rsi_lookup(&rsii); 219 rsip = rsi_lookup(cd, &rsii);
220 if (!rsip) 220 if (!rsip)
221 goto out; 221 goto out;
222 222
@@ -258,21 +258,20 @@ static int rsi_parse(struct cache_detail *cd,
258 if (dup_to_netobj(&rsii.out_token, buf, len)) 258 if (dup_to_netobj(&rsii.out_token, buf, len))
259 goto out; 259 goto out;
260 rsii.h.expiry_time = expiry; 260 rsii.h.expiry_time = expiry;
261 rsip = rsi_update(&rsii, rsip); 261 rsip = rsi_update(cd, &rsii, rsip);
262 status = 0; 262 status = 0;
263out: 263out:
264 rsi_free(&rsii); 264 rsi_free(&rsii);
265 if (rsip) 265 if (rsip)
266 cache_put(&rsip->h, &rsi_cache); 266 cache_put(&rsip->h, cd);
267 else 267 else
268 status = -ENOMEM; 268 status = -ENOMEM;
269 return status; 269 return status;
270} 270}
271 271
272static struct cache_detail rsi_cache = { 272static struct cache_detail rsi_cache_template = {
273 .owner = THIS_MODULE, 273 .owner = THIS_MODULE,
274 .hash_size = RSI_HASHMAX, 274 .hash_size = RSI_HASHMAX,
275 .hash_table = rsi_table,
276 .name = "auth.rpcsec.init", 275 .name = "auth.rpcsec.init",
277 .cache_put = rsi_put, 276 .cache_put = rsi_put,
278 .cache_upcall = rsi_upcall, 277 .cache_upcall = rsi_upcall,
@@ -283,24 +282,24 @@ static struct cache_detail rsi_cache = {
283 .alloc = rsi_alloc, 282 .alloc = rsi_alloc,
284}; 283};
285 284
286static struct rsi *rsi_lookup(struct rsi *item) 285static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item)
287{ 286{
288 struct cache_head *ch; 287 struct cache_head *ch;
289 int hash = rsi_hash(item); 288 int hash = rsi_hash(item);
290 289
291 ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash); 290 ch = sunrpc_cache_lookup(cd, &item->h, hash);
292 if (ch) 291 if (ch)
293 return container_of(ch, struct rsi, h); 292 return container_of(ch, struct rsi, h);
294 else 293 else
295 return NULL; 294 return NULL;
296} 295}
297 296
298static struct rsi *rsi_update(struct rsi *new, struct rsi *old) 297static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old)
299{ 298{
300 struct cache_head *ch; 299 struct cache_head *ch;
301 int hash = rsi_hash(new); 300 int hash = rsi_hash(new);
302 301
303 ch = sunrpc_cache_update(&rsi_cache, &new->h, 302 ch = sunrpc_cache_update(cd, &new->h,
304 &old->h, hash); 303 &old->h, hash);
305 if (ch) 304 if (ch)
306 return container_of(ch, struct rsi, h); 305 return container_of(ch, struct rsi, h);
@@ -339,10 +338,8 @@ struct rsc {
339 char *client_name; 338 char *client_name;
340}; 339};
341 340
342static struct cache_head *rsc_table[RSC_HASHMAX]; 341static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
343static struct cache_detail rsc_cache; 342static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item);
344static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
345static struct rsc *rsc_lookup(struct rsc *item);
346 343
347static void rsc_free(struct rsc *rsci) 344static void rsc_free(struct rsc *rsci)
348{ 345{
@@ -444,7 +441,7 @@ static int rsc_parse(struct cache_detail *cd,
444 if (expiry == 0) 441 if (expiry == 0)
445 goto out; 442 goto out;
446 443
447 rscp = rsc_lookup(&rsci); 444 rscp = rsc_lookup(cd, &rsci);
448 if (!rscp) 445 if (!rscp)
449 goto out; 446 goto out;
450 447
@@ -506,22 +503,21 @@ static int rsc_parse(struct cache_detail *cd,
506 503
507 } 504 }
508 rsci.h.expiry_time = expiry; 505 rsci.h.expiry_time = expiry;
509 rscp = rsc_update(&rsci, rscp); 506 rscp = rsc_update(cd, &rsci, rscp);
510 status = 0; 507 status = 0;
511out: 508out:
512 gss_mech_put(gm); 509 gss_mech_put(gm);
513 rsc_free(&rsci); 510 rsc_free(&rsci);
514 if (rscp) 511 if (rscp)
515 cache_put(&rscp->h, &rsc_cache); 512 cache_put(&rscp->h, cd);
516 else 513 else
517 status = -ENOMEM; 514 status = -ENOMEM;
518 return status; 515 return status;
519} 516}
520 517
521static struct cache_detail rsc_cache = { 518static struct cache_detail rsc_cache_template = {
522 .owner = THIS_MODULE, 519 .owner = THIS_MODULE,
523 .hash_size = RSC_HASHMAX, 520 .hash_size = RSC_HASHMAX,
524 .hash_table = rsc_table,
525 .name = "auth.rpcsec.context", 521 .name = "auth.rpcsec.context",
526 .cache_put = rsc_put, 522 .cache_put = rsc_put,
527 .cache_parse = rsc_parse, 523 .cache_parse = rsc_parse,
@@ -531,24 +527,24 @@ static struct cache_detail rsc_cache = {
531 .alloc = rsc_alloc, 527 .alloc = rsc_alloc,
532}; 528};
533 529
534static struct rsc *rsc_lookup(struct rsc *item) 530static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
535{ 531{
536 struct cache_head *ch; 532 struct cache_head *ch;
537 int hash = rsc_hash(item); 533 int hash = rsc_hash(item);
538 534
539 ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash); 535 ch = sunrpc_cache_lookup(cd, &item->h, hash);
540 if (ch) 536 if (ch)
541 return container_of(ch, struct rsc, h); 537 return container_of(ch, struct rsc, h);
542 else 538 else
543 return NULL; 539 return NULL;
544} 540}
545 541
546static struct rsc *rsc_update(struct rsc *new, struct rsc *old) 542static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old)
547{ 543{
548 struct cache_head *ch; 544 struct cache_head *ch;
549 int hash = rsc_hash(new); 545 int hash = rsc_hash(new);
550 546
551 ch = sunrpc_cache_update(&rsc_cache, &new->h, 547 ch = sunrpc_cache_update(cd, &new->h,
552 &old->h, hash); 548 &old->h, hash);
553 if (ch) 549 if (ch)
554 return container_of(ch, struct rsc, h); 550 return container_of(ch, struct rsc, h);
@@ -558,7 +554,7 @@ static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
558 554
559 555
560static struct rsc * 556static struct rsc *
561gss_svc_searchbyctx(struct xdr_netobj *handle) 557gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle)
562{ 558{
563 struct rsc rsci; 559 struct rsc rsci;
564 struct rsc *found; 560 struct rsc *found;
@@ -566,11 +562,11 @@ gss_svc_searchbyctx(struct xdr_netobj *handle)
566 memset(&rsci, 0, sizeof(rsci)); 562 memset(&rsci, 0, sizeof(rsci));
567 if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) 563 if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
568 return NULL; 564 return NULL;
569 found = rsc_lookup(&rsci); 565 found = rsc_lookup(cd, &rsci);
570 rsc_free(&rsci); 566 rsc_free(&rsci);
571 if (!found) 567 if (!found)
572 return NULL; 568 return NULL;
573 if (cache_check(&rsc_cache, &found->h, NULL)) 569 if (cache_check(cd, &found->h, NULL))
574 return NULL; 570 return NULL;
575 return found; 571 return found;
576} 572}
@@ -968,20 +964,20 @@ svcauth_gss_set_client(struct svc_rqst *rqstp)
968} 964}
969 965
970static inline int 966static inline int
971gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) 967gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, struct rsi *rsip)
972{ 968{
973 struct rsc *rsci; 969 struct rsc *rsci;
974 int rc; 970 int rc;
975 971
976 if (rsip->major_status != GSS_S_COMPLETE) 972 if (rsip->major_status != GSS_S_COMPLETE)
977 return gss_write_null_verf(rqstp); 973 return gss_write_null_verf(rqstp);
978 rsci = gss_svc_searchbyctx(&rsip->out_handle); 974 rsci = gss_svc_searchbyctx(cd, &rsip->out_handle);
979 if (rsci == NULL) { 975 if (rsci == NULL) {
980 rsip->major_status = GSS_S_NO_CONTEXT; 976 rsip->major_status = GSS_S_NO_CONTEXT;
981 return gss_write_null_verf(rqstp); 977 return gss_write_null_verf(rqstp);
982 } 978 }
983 rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); 979 rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
984 cache_put(&rsci->h, &rsc_cache); 980 cache_put(&rsci->h, cd);
985 return rc; 981 return rc;
986} 982}
987 983
@@ -1000,6 +996,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
1000 struct xdr_netobj tmpobj; 996 struct xdr_netobj tmpobj;
1001 struct rsi *rsip, rsikey; 997 struct rsi *rsip, rsikey;
1002 int ret; 998 int ret;
999 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
1003 1000
1004 /* Read the verifier; should be NULL: */ 1001 /* Read the verifier; should be NULL: */
1005 *authp = rpc_autherr_badverf; 1002 *authp = rpc_autherr_badverf;
@@ -1028,17 +1025,17 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
1028 } 1025 }
1029 1026
1030 /* Perform upcall, or find upcall result: */ 1027 /* Perform upcall, or find upcall result: */
1031 rsip = rsi_lookup(&rsikey); 1028 rsip = rsi_lookup(sn->rsi_cache, &rsikey);
1032 rsi_free(&rsikey); 1029 rsi_free(&rsikey);
1033 if (!rsip) 1030 if (!rsip)
1034 return SVC_CLOSE; 1031 return SVC_CLOSE;
1035 if (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) 1032 if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0)
1036 /* No upcall result: */ 1033 /* No upcall result: */
1037 return SVC_CLOSE; 1034 return SVC_CLOSE;
1038 1035
1039 ret = SVC_CLOSE; 1036 ret = SVC_CLOSE;
1040 /* Got an answer to the upcall; use it: */ 1037 /* Got an answer to the upcall; use it: */
1041 if (gss_write_init_verf(rqstp, rsip)) 1038 if (gss_write_init_verf(sn->rsc_cache, rqstp, rsip))
1042 goto out; 1039 goto out;
1043 if (resv->iov_len + 4 > PAGE_SIZE) 1040 if (resv->iov_len + 4 > PAGE_SIZE)
1044 goto out; 1041 goto out;
@@ -1055,7 +1052,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
1055 1052
1056 ret = SVC_COMPLETE; 1053 ret = SVC_COMPLETE;
1057out: 1054out:
1058 cache_put(&rsip->h, &rsi_cache); 1055 cache_put(&rsip->h, sn->rsi_cache);
1059 return ret; 1056 return ret;
1060} 1057}
1061 1058
@@ -1079,6 +1076,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1079 __be32 *rpcstart; 1076 __be32 *rpcstart;
1080 __be32 *reject_stat = resv->iov_base + resv->iov_len; 1077 __be32 *reject_stat = resv->iov_base + resv->iov_len;
1081 int ret; 1078 int ret;
1079 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
1082 1080
1083 dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n", 1081 dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",
1084 argv->iov_len); 1082 argv->iov_len);
@@ -1129,7 +1127,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1129 case RPC_GSS_PROC_DESTROY: 1127 case RPC_GSS_PROC_DESTROY:
1130 /* Look up the context, and check the verifier: */ 1128 /* Look up the context, and check the verifier: */
1131 *authp = rpcsec_gsserr_credproblem; 1129 *authp = rpcsec_gsserr_credproblem;
1132 rsci = gss_svc_searchbyctx(&gc->gc_ctx); 1130 rsci = gss_svc_searchbyctx(sn->rsc_cache, &gc->gc_ctx);
1133 if (!rsci) 1131 if (!rsci)
1134 goto auth_err; 1132 goto auth_err;
1135 switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) { 1133 switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) {
@@ -1209,7 +1207,7 @@ drop:
1209 ret = SVC_DROP; 1207 ret = SVC_DROP;
1210out: 1208out:
1211 if (rsci) 1209 if (rsci)
1212 cache_put(&rsci->h, &rsc_cache); 1210 cache_put(&rsci->h, sn->rsc_cache);
1213 return ret; 1211 return ret;
1214} 1212}
1215 1213
@@ -1362,6 +1360,7 @@ svcauth_gss_release(struct svc_rqst *rqstp)
1362 struct rpc_gss_wire_cred *gc = &gsd->clcred; 1360 struct rpc_gss_wire_cred *gc = &gsd->clcred;
1363 struct xdr_buf *resbuf = &rqstp->rq_res; 1361 struct xdr_buf *resbuf = &rqstp->rq_res;
1364 int stat = -EINVAL; 1362 int stat = -EINVAL;
1363 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
1365 1364
1366 if (gc->gc_proc != RPC_GSS_PROC_DATA) 1365 if (gc->gc_proc != RPC_GSS_PROC_DATA)
1367 goto out; 1366 goto out;
@@ -1404,7 +1403,7 @@ out_err:
1404 put_group_info(rqstp->rq_cred.cr_group_info); 1403 put_group_info(rqstp->rq_cred.cr_group_info);
1405 rqstp->rq_cred.cr_group_info = NULL; 1404 rqstp->rq_cred.cr_group_info = NULL;
1406 if (gsd->rsci) 1405 if (gsd->rsci)
1407 cache_put(&gsd->rsci->h, &rsc_cache); 1406 cache_put(&gsd->rsci->h, sn->rsc_cache);
1408 gsd->rsci = NULL; 1407 gsd->rsci = NULL;
1409 1408
1410 return stat; 1409 return stat;
@@ -1429,30 +1428,96 @@ static struct auth_ops svcauthops_gss = {
1429 .set_client = svcauth_gss_set_client, 1428 .set_client = svcauth_gss_set_client,
1430}; 1429};
1431 1430
1431static int rsi_cache_create_net(struct net *net)
1432{
1433 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1434 struct cache_detail *cd;
1435 int err;
1436
1437 cd = cache_create_net(&rsi_cache_template, net);
1438 if (IS_ERR(cd))
1439 return PTR_ERR(cd);
1440 err = cache_register_net(cd, net);
1441 if (err) {
1442 cache_destroy_net(cd, net);
1443 return err;
1444 }
1445 sn->rsi_cache = cd;
1446 return 0;
1447}
1448
1449static void rsi_cache_destroy_net(struct net *net)
1450{
1451 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1452 struct cache_detail *cd = sn->rsi_cache;
1453
1454 sn->rsi_cache = NULL;
1455 cache_purge(cd);
1456 cache_unregister_net(cd, net);
1457 cache_destroy_net(cd, net);
1458}
1459
1460static int rsc_cache_create_net(struct net *net)
1461{
1462 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1463 struct cache_detail *cd;
1464 int err;
1465
1466 cd = cache_create_net(&rsc_cache_template, net);
1467 if (IS_ERR(cd))
1468 return PTR_ERR(cd);
1469 err = cache_register_net(cd, net);
1470 if (err) {
1471 cache_destroy_net(cd, net);
1472 return err;
1473 }
1474 sn->rsc_cache = cd;
1475 return 0;
1476}
1477
1478static void rsc_cache_destroy_net(struct net *net)
1479{
1480 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1481 struct cache_detail *cd = sn->rsc_cache;
1482
1483 sn->rsc_cache = NULL;
1484 cache_purge(cd);
1485 cache_unregister_net(cd, net);
1486 cache_destroy_net(cd, net);
1487}
1488
1432int 1489int
1433gss_svc_init(void) 1490gss_svc_init_net(struct net *net)
1434{ 1491{
1435 int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); 1492 int rv;
1493
1494 rv = rsc_cache_create_net(net);
1436 if (rv) 1495 if (rv)
1437 return rv; 1496 return rv;
1438 rv = cache_register(&rsc_cache); 1497 rv = rsi_cache_create_net(net);
1439 if (rv) 1498 if (rv)
1440 goto out1; 1499 goto out1;
1441 rv = cache_register(&rsi_cache);
1442 if (rv)
1443 goto out2;
1444 return 0; 1500 return 0;
1445out2:
1446 cache_unregister(&rsc_cache);
1447out1: 1501out1:
1448 svc_auth_unregister(RPC_AUTH_GSS); 1502 rsc_cache_destroy_net(net);
1449 return rv; 1503 return rv;
1450} 1504}
1451 1505
1452void 1506void
1507gss_svc_shutdown_net(struct net *net)
1508{
1509 rsi_cache_destroy_net(net);
1510 rsc_cache_destroy_net(net);
1511}
1512
1513int
1514gss_svc_init(void)
1515{
1516 return svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
1517}
1518
1519void
1453gss_svc_shutdown(void) 1520gss_svc_shutdown(void)
1454{ 1521{
1455 cache_unregister(&rsc_cache);
1456 cache_unregister(&rsi_cache);
1457 svc_auth_unregister(RPC_AUTH_GSS); 1522 svc_auth_unregister(RPC_AUTH_GSS);
1458} 1523}