
Declaration of structures for encode and decode of OP_SECINFO. Encode and 
decode routines. MAX_SECINFO_LIST define is shared by struct svc_export.

Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Usha Ketineni <uketinen@us.ibm.com>
---

---

 linux-2.6.18-rc5-andros/fs/nfsd/nfs4xdr.c         |   52 ++++++++++++++++++++++
 linux-2.6.18-rc5-andros/include/linux/nfsd/xdr4.h |   19 ++++++++
 2 files changed, 71 insertions(+)

diff -puN fs/nfsd/nfs4xdr.c~nfsd4-secinfo-xdr fs/nfsd/nfs4xdr.c
--- linux-2.6.18-rc5/fs/nfsd/nfs4xdr.c~nfsd4-secinfo-xdr	2006-10-11 17:36:45.000000000 -0400
+++ linux-2.6.18-rc5-andros/fs/nfsd/nfs4xdr.c	2006-10-11 17:36:45.000000000 -0400
@@ -822,6 +822,21 @@ nfsd4_decode_renew(struct nfsd4_compound
 }
 
 static int
+nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, struct nfsd4_secinfo *secinfo)
+{
+	DECODE_HEAD;
+
+	READ_BUF(4);
+	READ32(secinfo->len);
+	READ_BUF(secinfo->len);
+	SAVEMEM(secinfo->name, secinfo->len);
+	if ((status = check_filename(secinfo->name, secinfo->len, nfserr_noent)))
+		return status;
+
+	DECODE_TAIL;
+}
+
+static int
 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
 {
 	DECODE_HEAD;
@@ -1134,6 +1149,9 @@ nfsd4_decode_compound(struct nfsd4_compo
 		case OP_SAVEFH:
 			op->status = nfs_ok;
 			break;
+		case OP_SECINFO:
+			op->status = nfsd4_decode_secinfo(argp, &op->u.secinfo);
+			break;
 		case OP_SETATTR:
 			op->status = nfsd4_decode_setattr(argp, &op->u.setattr);
 			break;
@@ -2414,6 +2432,37 @@ nfsd4_encode_rename(struct nfsd4_compoun
 	}
 }
 
+static void
+nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_secinfo *secinfo)
+{
+	int i = 0;
+	ENCODE_HEAD;
+
+	if (!nfserr) {
+		RESERVE_SPACE(4);
+		WRITE32(secinfo->nmech);
+		ADJUST_ARGS();
+		for (i = 0; i < secinfo->nmech; i++) {
+			RESERVE_SPACE(4);
+			WRITE32(secinfo->mechs[i].flavor);
+			ADJUST_ARGS();
+			if (secinfo->mechs[i].flavor == RPC_AUTH_GSS) {
+				RESERVE_SPACE(4 + secinfo->mechs[i].st.oid.len);
+				WRITE32(secinfo->mechs[i].st.oid.len);
+				WRITEMEM(secinfo->mechs[i].st.oid.data,
+				secinfo->mechs[i].st.oid.len);
+				ADJUST_ARGS();
+				RESERVE_SPACE(4);
+				WRITE32(secinfo->mechs[i].st.qop);
+				ADJUST_ARGS();
+				RESERVE_SPACE(4);
+				WRITE32(secinfo->mechs[i].st.service);
+				ADJUST_ARGS();
+			}
+		}
+	}
+}
+
 /*
  * The SETATTR encode routine is special -- it always encodes a bitmap,
  * regardless of the error status.
@@ -2554,6 +2603,9 @@ nfsd4_encode_operation(struct nfsd4_comp
 		break;
 	case OP_SAVEFH:
 		break;
+	case OP_SECINFO:
+		nfsd4_encode_secinfo(resp, op->status, &op->u.secinfo);
+		break;
 	case OP_SETATTR:
 		nfsd4_encode_setattr(resp, op->status, &op->u.setattr);
 		break;
diff -puN include/linux/nfsd/xdr4.h~nfsd4-secinfo-xdr include/linux/nfsd/xdr4.h
--- linux-2.6.18-rc5/include/linux/nfsd/xdr4.h~nfsd4-secinfo-xdr	2006-10-11 17:36:45.000000000 -0400
+++ linux-2.6.18-rc5-andros/include/linux/nfsd/xdr4.h	2006-10-11 17:36:45.000000000 -0400
@@ -288,6 +288,24 @@ struct nfsd4_rename {
 	struct nfsd4_change_info  rn_tinfo; /* response */
 };
 
+struct sec_triple {
+	struct xdr_netobj oid;
+	u32 qop;
+	u32 service;
+};
+
+struct sec_mech_info {
+	u32 flavor;
+	struct sec_triple st;
+};
+
+struct nfsd4_secinfo {
+	u32 len;					/* request */
+	char *name;					/* request */
+	u32 nmech;					/* response */
+	struct sec_mech_info mechs[MAX_SECINFO_LIST];	/* response */
+};
+
 struct nfsd4_setattr {
 	stateid_t	sa_stateid;         /* request */
 	u32		sa_bmval[2];        /* request */
@@ -361,6 +379,7 @@ struct nfsd4_op {
 		struct nfsd4_remove		remove;
 		struct nfsd4_rename		rename;
 		clientid_t			renew;
+		struct nfsd4_secinfo		secinfo;
 		struct nfsd4_setattr		setattr;
 		struct nfsd4_setclientid	setclientid;
 		struct nfsd4_setclientid_confirm setclientid_confirm;
_
