diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/specs/nfsd.yaml index 642268819c6f..9ae37bf3ea71 100644 --- a/Documentation/netlink/specs/nfsd.yaml +++ b/Documentation/netlink/specs/nfsd.yaml @@ -42,6 +42,15 @@ definitions: - none - tls - mtls + - + type: flags + name: rpcbind-flags + doc: >- + Constraints that apply to an rpcbind registration. no-udp means the + kernel would not have registered this program and version over UDP, + so the caller must skip the udp and udp6 netids for it. + entries: + - no-udp attribute-sets: - @@ -159,6 +168,23 @@ attribute-sets: - name: transport-name type: string + - + name: rpcbind + attributes: + - + name: program + type: u32 + doc: RPC program number to register. + - + name: version + type: u32 + doc: RPC version number to register. + - + name: flags + type: u32 + enum: rpcbind-flags + enum-as-flags: true + doc: Constraints on the listeners this entry applies to. - name: server-sock attributes: @@ -167,6 +193,24 @@ attribute-sets: type: nest nested-attributes: sock multi-attr: true + - + name: userspace-rpcbind + type: flag + doc: >- + The caller registers the listeners with rpcbind itself, so the + kernel must not do it. The kernel echoes this attribute in the + reply when it accepts the request. Ownership cannot change while + a server exists. + - + name: rpcbind + type: nest + nested-attributes: rpcbind + multi-attr: true + doc: >- + A program and version that the caller should register for every + listener reported in the same reply, except the netids that flags + rules out. Reply only. NLM is absent because lockd still + registers itself. - name: pool-mode attributes: @@ -483,13 +527,22 @@ operations: - version - name: listener-set - doc: set nfs running sockets + doc: >- + set nfs running sockets. A request that carries userspace-rpcbind + is answered with a reply rather than a bare ack, and the addr list + in that reply names only the listeners that have an rpcbind netid. attribute-set: server-sock flags: [admin-perm] do: request: attributes: - addr + - userspace-rpcbind + reply: + attributes: + - addr + - userspace-rpcbind + - rpcbind - name: listener-get doc: get nfs running listeners diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c index eba8b353f412..88a4a4ffcb7f 100644 --- a/fs/nfsd/netlink.c +++ b/fs/nfsd/netlink.c @@ -79,8 +79,9 @@ static const struct nla_policy nfsd_version_set_nl_policy[NFSD_A_SERVER_PROTO_VE }; /* NFSD_CMD_LISTENER_SET - do */ -static const struct nla_policy nfsd_listener_set_nl_policy[NFSD_A_SERVER_SOCK_ADDR + 1] = { +static const struct nla_policy nfsd_listener_set_nl_policy[NFSD_A_SERVER_SOCK_USERSPACE_RPCBIND + 1] = { [NFSD_A_SERVER_SOCK_ADDR] = NLA_POLICY_NESTED(nfsd_sock_nl_policy), + [NFSD_A_SERVER_SOCK_USERSPACE_RPCBIND] = { .type = NLA_FLAG, }, }; /* NFSD_CMD_POOL_MODE_SET - do */ @@ -153,7 +154,7 @@ static const struct genl_split_ops nfsd_nl_ops[] = { .cmd = NFSD_CMD_LISTENER_SET, .doit = nfsd_nl_listener_set_doit, .policy = nfsd_listener_set_nl_policy, - .maxattr = NFSD_A_SERVER_SOCK_ADDR, + .maxattr = NFSD_A_SERVER_SOCK_USERSPACE_RPCBIND, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_netlink.h index 87da1d0bb21e..c125af0cc6a5 100644 --- a/include/uapi/linux/nfsd_netlink.h +++ b/include/uapi/linux/nfsd_netlink.h @@ -50,6 +50,15 @@ enum nfsd_xprtsec_mode { NFSD_XPRTSEC_MODE_MTLS = 4, }; +/* + * Constraints that apply to an rpcbind registration. no-udp means the kernel + * would not have registered this program and version over UDP, so the caller + * must skip the udp and udp6 netids for it. + */ +enum nfsd_rpcbind_flags { + NFSD_RPCBIND_FLAGS_NO_UDP = 1, +}; + enum { NFSD_A_CACHE_NOTIFY_CACHE_TYPE = 1, @@ -113,8 +122,19 @@ enum { NFSD_A_SOCK_MAX = (__NFSD_A_SOCK_MAX - 1) }; +enum { + NFSD_A_RPCBIND_PROGRAM = 1, + NFSD_A_RPCBIND_VERSION, + NFSD_A_RPCBIND_FLAGS, + + __NFSD_A_RPCBIND_MAX, + NFSD_A_RPCBIND_MAX = (__NFSD_A_RPCBIND_MAX - 1) +}; + enum { NFSD_A_SERVER_SOCK_ADDR = 1, + NFSD_A_SERVER_SOCK_USERSPACE_RPCBIND, + NFSD_A_SERVER_SOCK_RPCBIND, __NFSD_A_SERVER_SOCK_MAX, NFSD_A_SERVER_SOCK_MAX = (__NFSD_A_SERVER_SOCK_MAX - 1)