forked from mirrors/linux
		
	libceph, ceph: implement msgr2.1 protocol (crc and secure modes)
Implement msgr2.1 wire protocol, available since nautilus 14.2.11 and octopus 15.2.5. msgr2.0 wire protocol is not implemented -- it has several security, integrity and robustness issues and therefore considered deprecated. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
		
							parent
							
								
									00498b9941
								
							
						
					
					
						commit
						cd1a677cad
					
				
					 15 changed files with 4356 additions and 31 deletions
				
			
		| 
						 | 
					@ -5014,7 +5014,7 @@ void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newmap = ceph_mdsmap_decode(&p, end, false);
 | 
						newmap = ceph_mdsmap_decode(&p, end, ceph_msgr2(mdsc->fsc->client));
 | 
				
			||||||
	if (IS_ERR(newmap)) {
 | 
						if (IS_ERR(newmap)) {
 | 
				
			||||||
		err = PTR_ERR(newmap);
 | 
							err = PTR_ERR(newmap);
 | 
				
			||||||
		goto bad_unlock;
 | 
							goto bad_unlock;
 | 
				
			||||||
| 
						 | 
					@ -5196,6 +5196,80 @@ static int invalidate_authorizer(struct ceph_connection *con)
 | 
				
			||||||
	return ceph_monc_validate_auth(&mdsc->fsc->client->monc);
 | 
						return ceph_monc_validate_auth(&mdsc->fsc->client->monc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mds_get_auth_request(struct ceph_connection *con,
 | 
				
			||||||
 | 
									void *buf, int *buf_len,
 | 
				
			||||||
 | 
									void **authorizer, int *authorizer_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mds_session *s = con->private;
 | 
				
			||||||
 | 
						struct ceph_auth_client *ac = s->s_mdsc->fsc->client->monc.auth;
 | 
				
			||||||
 | 
						struct ceph_auth_handshake *auth = &s->s_auth;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ceph_auth_get_authorizer(ac, auth, CEPH_ENTITY_TYPE_MDS,
 | 
				
			||||||
 | 
									       buf, buf_len);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*authorizer = auth->authorizer_buf;
 | 
				
			||||||
 | 
						*authorizer_len = auth->authorizer_buf_len;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mds_handle_auth_reply_more(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      void *reply, int reply_len,
 | 
				
			||||||
 | 
									      void *buf, int *buf_len,
 | 
				
			||||||
 | 
									      void **authorizer, int *authorizer_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mds_session *s = con->private;
 | 
				
			||||||
 | 
						struct ceph_auth_client *ac = s->s_mdsc->fsc->client->monc.auth;
 | 
				
			||||||
 | 
						struct ceph_auth_handshake *auth = &s->s_auth;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ceph_auth_handle_svc_reply_more(ac, auth, reply, reply_len,
 | 
				
			||||||
 | 
										      buf, buf_len);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*authorizer = auth->authorizer_buf;
 | 
				
			||||||
 | 
						*authorizer_len = auth->authorizer_buf_len;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mds_handle_auth_done(struct ceph_connection *con,
 | 
				
			||||||
 | 
									u64 global_id, void *reply, int reply_len,
 | 
				
			||||||
 | 
									u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									u8 *con_secret, int *con_secret_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mds_session *s = con->private;
 | 
				
			||||||
 | 
						struct ceph_auth_client *ac = s->s_mdsc->fsc->client->monc.auth;
 | 
				
			||||||
 | 
						struct ceph_auth_handshake *auth = &s->s_auth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ceph_auth_handle_svc_reply_done(ac, auth, reply, reply_len,
 | 
				
			||||||
 | 
										       session_key, session_key_len,
 | 
				
			||||||
 | 
										       con_secret, con_secret_len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mds_handle_auth_bad_method(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      int used_proto, int result,
 | 
				
			||||||
 | 
									      const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									      const int *allowed_modes, int mode_cnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mds_session *s = con->private;
 | 
				
			||||||
 | 
						struct ceph_mon_client *monc = &s->s_mdsc->fsc->client->monc;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ceph_auth_handle_bad_authorizer(monc->auth, CEPH_ENTITY_TYPE_MDS,
 | 
				
			||||||
 | 
										    used_proto, result,
 | 
				
			||||||
 | 
										    allowed_protos, proto_cnt,
 | 
				
			||||||
 | 
										    allowed_modes, mode_cnt)) {
 | 
				
			||||||
 | 
							ret = ceph_monc_validate_auth(monc);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return -EACCES;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct ceph_msg *mds_alloc_msg(struct ceph_connection *con,
 | 
					static struct ceph_msg *mds_alloc_msg(struct ceph_connection *con,
 | 
				
			||||||
				struct ceph_msg_header *hdr, int *skip)
 | 
									struct ceph_msg_header *hdr, int *skip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -5245,6 +5319,10 @@ static const struct ceph_connection_operations mds_con_ops = {
 | 
				
			||||||
	.alloc_msg = mds_alloc_msg,
 | 
						.alloc_msg = mds_alloc_msg,
 | 
				
			||||||
	.sign_message = mds_sign_message,
 | 
						.sign_message = mds_sign_message,
 | 
				
			||||||
	.check_message_signature = mds_check_message_signature,
 | 
						.check_message_signature = mds_check_message_signature,
 | 
				
			||||||
 | 
						.get_auth_request = mds_get_auth_request,
 | 
				
			||||||
 | 
						.handle_auth_reply_more = mds_handle_auth_reply_more,
 | 
				
			||||||
 | 
						.handle_auth_done = mds_handle_auth_done,
 | 
				
			||||||
 | 
						.handle_auth_bad_method = mds_handle_auth_bad_method,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* eof */
 | 
					/* eof */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,8 +120,12 @@ int ceph_auth_entity_name_encode(const char *name, void **p, void *end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int ceph_build_auth(struct ceph_auth_client *ac,
 | 
					extern int ceph_build_auth(struct ceph_auth_client *ac,
 | 
				
			||||||
		    void *msg_buf, size_t msg_len);
 | 
							    void *msg_buf, size_t msg_len);
 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac);
 | 
					extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int __ceph_auth_get_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
								       struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
								       int peer_type, bool force_new,
 | 
				
			||||||
 | 
								       int *proto, int *pref_mode, int *fallb_mode);
 | 
				
			||||||
extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
 | 
					extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
				       int peer_type,
 | 
									       int peer_type,
 | 
				
			||||||
				       struct ceph_auth_handshake *auth);
 | 
									       struct ceph_auth_handshake *auth);
 | 
				
			||||||
| 
						 | 
					@ -157,4 +161,34 @@ int ceph_auth_check_message_signature(struct ceph_auth_handshake *auth,
 | 
				
			||||||
		return auth->check_message_signature(auth, msg);
 | 
							return auth->check_message_signature(auth, msg);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_auth_get_request(struct ceph_auth_client *ac, void *buf, int buf_len);
 | 
				
			||||||
 | 
					int ceph_auth_handle_reply_more(struct ceph_auth_client *ac, void *reply,
 | 
				
			||||||
 | 
									int reply_len, void *buf, int buf_len);
 | 
				
			||||||
 | 
					int ceph_auth_handle_reply_done(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									u64 global_id, void *reply, int reply_len,
 | 
				
			||||||
 | 
									u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									u8 *con_secret, int *con_secret_len);
 | 
				
			||||||
 | 
					bool ceph_auth_handle_bad_method(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									 int used_proto, int result,
 | 
				
			||||||
 | 
									 const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									 const int *allowed_modes, int mode_cnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_auth_get_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
								     struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
								     int peer_type, void *buf, int *buf_len);
 | 
				
			||||||
 | 
					int ceph_auth_handle_svc_reply_more(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									    struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
									    void *reply, int reply_len,
 | 
				
			||||||
 | 
									    void *buf, int *buf_len);
 | 
				
			||||||
 | 
					int ceph_auth_handle_svc_reply_done(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									    struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
									    void *reply, int reply_len,
 | 
				
			||||||
 | 
									    u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									    u8 *con_secret, int *con_secret_len);
 | 
				
			||||||
 | 
					bool ceph_auth_handle_bad_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									     int peer_type, int used_proto, int result,
 | 
				
			||||||
 | 
									     const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									     const int *allowed_modes, int mode_cnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,10 @@ struct ceph_dir_layout {
 | 
				
			||||||
#define CEPH_AUTH_NONE	 	0x1
 | 
					#define CEPH_AUTH_NONE	 	0x1
 | 
				
			||||||
#define CEPH_AUTH_CEPHX	 	0x2
 | 
					#define CEPH_AUTH_CEPHX	 	0x2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CEPH_AUTH_MODE_NONE		0
 | 
				
			||||||
 | 
					#define CEPH_AUTH_MODE_AUTHORIZER	1
 | 
				
			||||||
 | 
					#define CEPH_AUTH_MODE_MON		10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* msgr2 protocol modes */
 | 
					/* msgr2 protocol modes */
 | 
				
			||||||
#define CEPH_CON_MODE_UNKNOWN	0x0
 | 
					#define CEPH_CON_MODE_UNKNOWN	0x0
 | 
				
			||||||
#define CEPH_CON_MODE_CRC	0x1
 | 
					#define CEPH_CON_MODE_CRC	0x1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -221,6 +221,7 @@ static inline void ceph_encode_timespec64(struct ceph_timespec *tv,
 | 
				
			||||||
#define CEPH_ENTITY_ADDR_TYPE_NONE	0
 | 
					#define CEPH_ENTITY_ADDR_TYPE_NONE	0
 | 
				
			||||||
#define CEPH_ENTITY_ADDR_TYPE_LEGACY	__cpu_to_le32(1)
 | 
					#define CEPH_ENTITY_ADDR_TYPE_LEGACY	__cpu_to_le32(1)
 | 
				
			||||||
#define CEPH_ENTITY_ADDR_TYPE_MSGR2	__cpu_to_le32(2)
 | 
					#define CEPH_ENTITY_ADDR_TYPE_MSGR2	__cpu_to_le32(2)
 | 
				
			||||||
 | 
					#define CEPH_ENTITY_ADDR_TYPE_ANY	__cpu_to_le32(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void ceph_encode_banner_addr(struct ceph_entity_addr *a)
 | 
					static inline void ceph_encode_banner_addr(struct ceph_entity_addr *a)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -243,6 +244,9 @@ extern int ceph_decode_entity_addr(void **p, void *end,
 | 
				
			||||||
int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
 | 
					int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
 | 
				
			||||||
			       struct ceph_entity_addr *addr);
 | 
								       struct ceph_entity_addr *addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_entity_addr_encoding_len(const struct ceph_entity_addr *addr);
 | 
				
			||||||
 | 
					void ceph_encode_entity_addr(void **p, const struct ceph_entity_addr *addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * encoders
 | 
					 * encoders
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,10 +31,10 @@
 | 
				
			||||||
#define CEPH_OPT_FSID             (1<<0)
 | 
					#define CEPH_OPT_FSID             (1<<0)
 | 
				
			||||||
#define CEPH_OPT_NOSHARE          (1<<1) /* don't share client with other sbs */
 | 
					#define CEPH_OPT_NOSHARE          (1<<1) /* don't share client with other sbs */
 | 
				
			||||||
#define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
 | 
					#define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
 | 
				
			||||||
#define CEPH_OPT_NOCRC            (1<<3) /* no data crc on writes */
 | 
					#define CEPH_OPT_NOCRC            (1<<3) /* no data crc on writes (msgr1) */
 | 
				
			||||||
#define CEPH_OPT_NOMSGAUTH	  (1<<4) /* don't require msg signing feat */
 | 
					#define CEPH_OPT_NOMSGAUTH	  (1<<4) /* don't require msg signing feat */
 | 
				
			||||||
#define CEPH_OPT_TCP_NODELAY	  (1<<5) /* TCP_NODELAY on TCP sockets */
 | 
					#define CEPH_OPT_TCP_NODELAY	  (1<<5) /* TCP_NODELAY on TCP sockets */
 | 
				
			||||||
#define CEPH_OPT_NOMSGSIGN	  (1<<6) /* don't sign msgs */
 | 
					#define CEPH_OPT_NOMSGSIGN	  (1<<6) /* don't sign msgs (msgr1) */
 | 
				
			||||||
#define CEPH_OPT_ABORT_ON_FULL	  (1<<7) /* abort w/ ENOSPC when full */
 | 
					#define CEPH_OPT_ABORT_ON_FULL	  (1<<7) /* abort w/ ENOSPC when full */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CEPH_OPT_DEFAULT   (CEPH_OPT_TCP_NODELAY)
 | 
					#define CEPH_OPT_DEFAULT   (CEPH_OPT_TCP_NODELAY)
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,7 @@ struct ceph_options {
 | 
				
			||||||
#define CEPH_MONC_HUNT_BACKOFF		2
 | 
					#define CEPH_MONC_HUNT_BACKOFF		2
 | 
				
			||||||
#define CEPH_MONC_HUNT_MAX_MULT		10
 | 
					#define CEPH_MONC_HUNT_MAX_MULT		10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CEPH_MSG_MAX_CONTROL_LEN (16*1024*1024)
 | 
				
			||||||
#define CEPH_MSG_MAX_FRONT_LEN	(16*1024*1024)
 | 
					#define CEPH_MSG_MAX_FRONT_LEN	(16*1024*1024)
 | 
				
			||||||
#define CEPH_MSG_MAX_MIDDLE_LEN	(16*1024*1024)
 | 
					#define CEPH_MSG_MAX_MIDDLE_LEN	(16*1024*1024)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,6 +153,10 @@ struct ceph_client {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define from_msgr(ms)	container_of(ms, struct ceph_client, msgr)
 | 
					#define from_msgr(ms)	container_of(ms, struct ceph_client, msgr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool ceph_msgr2(struct ceph_client *client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return client->options->con_modes[0] != CEPH_CON_MODE_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * snapshots
 | 
					 * snapshots
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@
 | 
				
			||||||
#define __FS_CEPH_MESSENGER_H
 | 
					#define __FS_CEPH_MESSENGER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/bvec.h>
 | 
					#include <linux/bvec.h>
 | 
				
			||||||
 | 
					#include <linux/crypto.h>
 | 
				
			||||||
#include <linux/kref.h>
 | 
					#include <linux/kref.h>
 | 
				
			||||||
#include <linux/mutex.h>
 | 
					#include <linux/mutex.h>
 | 
				
			||||||
#include <linux/net.h>
 | 
					#include <linux/net.h>
 | 
				
			||||||
| 
						 | 
					@ -52,6 +53,23 @@ struct ceph_connection_operations {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int (*sign_message) (struct ceph_msg *msg);
 | 
						int (*sign_message) (struct ceph_msg *msg);
 | 
				
			||||||
	int (*check_message_signature) (struct ceph_msg *msg);
 | 
						int (*check_message_signature) (struct ceph_msg *msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* msgr2 authentication exchange */
 | 
				
			||||||
 | 
						int (*get_auth_request)(struct ceph_connection *con,
 | 
				
			||||||
 | 
									void *buf, int *buf_len,
 | 
				
			||||||
 | 
									void **authorizer, int *authorizer_len);
 | 
				
			||||||
 | 
						int (*handle_auth_reply_more)(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      void *reply, int reply_len,
 | 
				
			||||||
 | 
									      void *buf, int *buf_len,
 | 
				
			||||||
 | 
									      void **authorizer, int *authorizer_len);
 | 
				
			||||||
 | 
						int (*handle_auth_done)(struct ceph_connection *con,
 | 
				
			||||||
 | 
									u64 global_id, void *reply, int reply_len,
 | 
				
			||||||
 | 
									u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									u8 *con_secret, int *con_secret_len);
 | 
				
			||||||
 | 
						int (*handle_auth_bad_method)(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      int used_proto, int result,
 | 
				
			||||||
 | 
									      const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									      const int *allowed_modes, int mode_cnt);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* use format string %s%lld */
 | 
					/* use format string %s%lld */
 | 
				
			||||||
| 
						 | 
					@ -246,8 +264,15 @@ struct ceph_msg {
 | 
				
			||||||
#define CEPH_CON_S_PREOPEN		2
 | 
					#define CEPH_CON_S_PREOPEN		2
 | 
				
			||||||
#define CEPH_CON_S_V1_BANNER		3
 | 
					#define CEPH_CON_S_V1_BANNER		3
 | 
				
			||||||
#define CEPH_CON_S_V1_CONNECT_MSG	4
 | 
					#define CEPH_CON_S_V1_CONNECT_MSG	4
 | 
				
			||||||
#define CEPH_CON_S_OPEN			5
 | 
					#define CEPH_CON_S_V2_BANNER_PREFIX	5
 | 
				
			||||||
#define CEPH_CON_S_STANDBY		6
 | 
					#define CEPH_CON_S_V2_BANNER_PAYLOAD	6
 | 
				
			||||||
 | 
					#define CEPH_CON_S_V2_HELLO		7
 | 
				
			||||||
 | 
					#define CEPH_CON_S_V2_AUTH		8
 | 
				
			||||||
 | 
					#define CEPH_CON_S_V2_AUTH_SIGNATURE	9
 | 
				
			||||||
 | 
					#define CEPH_CON_S_V2_SESSION_CONNECT	10
 | 
				
			||||||
 | 
					#define CEPH_CON_S_V2_SESSION_RECONNECT	11
 | 
				
			||||||
 | 
					#define CEPH_CON_S_OPEN			12
 | 
				
			||||||
 | 
					#define CEPH_CON_S_STANDBY		13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * ceph_connection flag bits
 | 
					 * ceph_connection flag bits
 | 
				
			||||||
| 
						 | 
					@ -301,6 +326,99 @@ struct ceph_connection_v1_info {
 | 
				
			||||||
	u32 peer_global_seq;  /* peer's global seq for this connection */
 | 
						u32 peer_global_seq;  /* peer's global seq for this connection */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CEPH_CRC_LEN			4
 | 
				
			||||||
 | 
					#define CEPH_GCM_KEY_LEN		16
 | 
				
			||||||
 | 
					#define CEPH_GCM_IV_LEN			sizeof(struct ceph_gcm_nonce)
 | 
				
			||||||
 | 
					#define CEPH_GCM_BLOCK_LEN		16
 | 
				
			||||||
 | 
					#define CEPH_GCM_TAG_LEN		16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CEPH_PREAMBLE_LEN		32
 | 
				
			||||||
 | 
					#define CEPH_PREAMBLE_INLINE_LEN	48
 | 
				
			||||||
 | 
					#define CEPH_PREAMBLE_PLAIN_LEN		CEPH_PREAMBLE_LEN
 | 
				
			||||||
 | 
					#define CEPH_PREAMBLE_SECURE_LEN	(CEPH_PREAMBLE_LEN +		\
 | 
				
			||||||
 | 
										 CEPH_PREAMBLE_INLINE_LEN +	\
 | 
				
			||||||
 | 
										 CEPH_GCM_TAG_LEN)
 | 
				
			||||||
 | 
					#define CEPH_EPILOGUE_PLAIN_LEN		(1 + 3 * CEPH_CRC_LEN)
 | 
				
			||||||
 | 
					#define CEPH_EPILOGUE_SECURE_LEN	(CEPH_GCM_BLOCK_LEN + CEPH_GCM_TAG_LEN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CEPH_FRAME_MAX_SEGMENT_COUNT	4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ceph_frame_desc {
 | 
				
			||||||
 | 
						int fd_tag;  /* FRAME_TAG_* */
 | 
				
			||||||
 | 
						int fd_seg_cnt;
 | 
				
			||||||
 | 
						int fd_lens[CEPH_FRAME_MAX_SEGMENT_COUNT];  /* logical */
 | 
				
			||||||
 | 
						int fd_aligns[CEPH_FRAME_MAX_SEGMENT_COUNT];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ceph_gcm_nonce {
 | 
				
			||||||
 | 
						__le32 fixed;
 | 
				
			||||||
 | 
						__le64 counter __packed;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ceph_connection_v2_info {
 | 
				
			||||||
 | 
						struct iov_iter in_iter;
 | 
				
			||||||
 | 
						struct kvec in_kvecs[5];  /* recvmsg */
 | 
				
			||||||
 | 
						struct bio_vec in_bvec;  /* recvmsg (in_cursor) */
 | 
				
			||||||
 | 
						int in_kvec_cnt;
 | 
				
			||||||
 | 
						int in_state;  /* IN_S_* */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct iov_iter out_iter;
 | 
				
			||||||
 | 
						struct kvec out_kvecs[8];  /* sendmsg */
 | 
				
			||||||
 | 
						struct bio_vec out_bvec;  /* sendpage (out_cursor, out_zero),
 | 
				
			||||||
 | 
									     sendmsg (out_enc_pages) */
 | 
				
			||||||
 | 
						int out_kvec_cnt;
 | 
				
			||||||
 | 
						int out_state;  /* OUT_S_* */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int out_zero;  /* # of zero bytes to send */
 | 
				
			||||||
 | 
						bool out_iter_sendpage;  /* use sendpage if possible */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct ceph_frame_desc in_desc;
 | 
				
			||||||
 | 
						struct ceph_msg_data_cursor in_cursor;
 | 
				
			||||||
 | 
						struct ceph_msg_data_cursor out_cursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct crypto_shash *hmac_tfm;  /* post-auth signature */
 | 
				
			||||||
 | 
						struct crypto_aead *gcm_tfm;  /* on-wire encryption */
 | 
				
			||||||
 | 
						struct aead_request *gcm_req;
 | 
				
			||||||
 | 
						struct crypto_wait gcm_wait;
 | 
				
			||||||
 | 
						struct ceph_gcm_nonce in_gcm_nonce;
 | 
				
			||||||
 | 
						struct ceph_gcm_nonce out_gcm_nonce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct page **out_enc_pages;
 | 
				
			||||||
 | 
						int out_enc_page_cnt;
 | 
				
			||||||
 | 
						int out_enc_resid;
 | 
				
			||||||
 | 
						int out_enc_i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int con_mode;  /* CEPH_CON_MODE_* */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *conn_bufs[16];
 | 
				
			||||||
 | 
						int conn_buf_cnt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct kvec in_sign_kvecs[8];
 | 
				
			||||||
 | 
						struct kvec out_sign_kvecs[8];
 | 
				
			||||||
 | 
						int in_sign_kvec_cnt;
 | 
				
			||||||
 | 
						int out_sign_kvec_cnt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u64 client_cookie;
 | 
				
			||||||
 | 
						u64 server_cookie;
 | 
				
			||||||
 | 
						u64 global_seq;
 | 
				
			||||||
 | 
						u64 connect_seq;
 | 
				
			||||||
 | 
						u64 peer_global_seq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u8 in_buf[CEPH_PREAMBLE_SECURE_LEN];
 | 
				
			||||||
 | 
						u8 out_buf[CEPH_PREAMBLE_SECURE_LEN];
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							u8 late_status;  /* FRAME_LATE_STATUS_* */
 | 
				
			||||||
 | 
							union {
 | 
				
			||||||
 | 
								struct {
 | 
				
			||||||
 | 
									u32 front_crc;
 | 
				
			||||||
 | 
									u32 middle_crc;
 | 
				
			||||||
 | 
									u32 data_crc;
 | 
				
			||||||
 | 
								} __packed;
 | 
				
			||||||
 | 
								u8 pad[CEPH_GCM_BLOCK_LEN - 1];
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						} out_epil;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * A single connection with another host.
 | 
					 * A single connection with another host.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -346,7 +464,10 @@ struct ceph_connection {
 | 
				
			||||||
	struct delayed_work work;	    /* send|recv work */
 | 
						struct delayed_work work;	    /* send|recv work */
 | 
				
			||||||
	unsigned long       delay;          /* current delay interval */
 | 
						unsigned long       delay;          /* current delay interval */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ceph_connection_v1_info v1;
 | 
						union {
 | 
				
			||||||
 | 
							struct ceph_connection_v1_info v1;
 | 
				
			||||||
 | 
							struct ceph_connection_v2_info v2;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern struct page *ceph_zero_page;
 | 
					extern struct page *ceph_zero_page;
 | 
				
			||||||
| 
						 | 
					@ -397,6 +518,15 @@ bool ceph_con_v1_opened(struct ceph_connection *con);
 | 
				
			||||||
void ceph_con_v1_reset_session(struct ceph_connection *con);
 | 
					void ceph_con_v1_reset_session(struct ceph_connection *con);
 | 
				
			||||||
void ceph_con_v1_reset_protocol(struct ceph_connection *con);
 | 
					void ceph_con_v1_reset_protocol(struct ceph_connection *con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* messenger_v2.c */
 | 
				
			||||||
 | 
					int ceph_con_v2_try_read(struct ceph_connection *con);
 | 
				
			||||||
 | 
					int ceph_con_v2_try_write(struct ceph_connection *con);
 | 
				
			||||||
 | 
					void ceph_con_v2_revoke(struct ceph_connection *con);
 | 
				
			||||||
 | 
					void ceph_con_v2_revoke_incoming(struct ceph_connection *con);
 | 
				
			||||||
 | 
					bool ceph_con_v2_opened(struct ceph_connection *con);
 | 
				
			||||||
 | 
					void ceph_con_v2_reset_session(struct ceph_connection *con);
 | 
				
			||||||
 | 
					void ceph_con_v2_reset_protocol(struct ceph_connection *con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const char *ceph_pr_addr(const struct ceph_entity_addr *addr);
 | 
					extern const char *ceph_pr_addr(const struct ceph_entity_addr *addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,9 +14,39 @@
 | 
				
			||||||
 * constant.
 | 
					 * constant.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define CEPH_BANNER "ceph v027"
 | 
					#define CEPH_BANNER "ceph v027"
 | 
				
			||||||
 | 
					#define CEPH_BANNER_LEN 9
 | 
				
			||||||
#define CEPH_BANNER_MAX_LEN 30
 | 
					#define CEPH_BANNER_MAX_LEN 30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * messenger V2 connection banner prefix.
 | 
				
			||||||
 | 
					 * The full banner string should have the form: "ceph v2\n<le16>"
 | 
				
			||||||
 | 
					 * the 2 bytes are the length of the remaining banner.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define CEPH_BANNER_V2 "ceph v2\n"
 | 
				
			||||||
 | 
					#define CEPH_BANNER_V2_LEN 8
 | 
				
			||||||
 | 
					#define CEPH_BANNER_V2_PREFIX_LEN (CEPH_BANNER_V2_LEN + sizeof(__le16))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * messenger V2 features
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define CEPH_MSGR2_INCARNATION_1 (0ull)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFINE_MSGR2_FEATURE(bit, incarnation, name)               \
 | 
				
			||||||
 | 
						static const uint64_t CEPH_MSGR2_FEATURE_##name = (1ULL << bit); \
 | 
				
			||||||
 | 
						static const uint64_t CEPH_MSGR2_FEATUREMASK_##name =            \
 | 
				
			||||||
 | 
								(1ULL << bit | CEPH_MSGR2_INCARNATION_##incarnation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HAVE_MSGR2_FEATURE(x, name) \
 | 
				
			||||||
 | 
						(((x) & (CEPH_MSGR2_FEATUREMASK_##name)) == (CEPH_MSGR2_FEATUREMASK_##name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEFINE_MSGR2_FEATURE( 0, 1, REVISION_1)   // msgr2.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CEPH_MSGR2_SUPPORTED_FEATURES (CEPH_MSGR2_FEATURE_REVISION_1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CEPH_MSGR2_REQUIRED_FEATURES  (CEPH_MSGR2_FEATURE_REVISION_1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Rollover-safe type and comparator for 32-bit sequence numbers.
 | 
					 * Rollover-safe type and comparator for 32-bit sequence numbers.
 | 
				
			||||||
 * Comparator returns -1, 0, or 1.
 | 
					 * Comparator returns -1, 0, or 1.
 | 
				
			||||||
| 
						 | 
					@ -158,6 +188,24 @@ struct ceph_msg_header {
 | 
				
			||||||
	__le32 crc;       /* header crc32c */
 | 
						__le32 crc;       /* header crc32c */
 | 
				
			||||||
} __attribute__ ((packed));
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ceph_msg_header2 {
 | 
				
			||||||
 | 
						__le64 seq;       /* message seq# for this session */
 | 
				
			||||||
 | 
						__le64 tid;       /* transaction id */
 | 
				
			||||||
 | 
						__le16 type;      /* message type */
 | 
				
			||||||
 | 
						__le16 priority;  /* priority.  higher value == higher priority */
 | 
				
			||||||
 | 
						__le16 version;   /* version of message encoding */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__le32 data_pre_padding_len;
 | 
				
			||||||
 | 
						__le16 data_off;  /* sender: include full offset;
 | 
				
			||||||
 | 
								     receiver: mask against ~PAGE_MASK */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__le64 ack_seq;
 | 
				
			||||||
 | 
						__u8 flags;
 | 
				
			||||||
 | 
						/* oldest code we think can decode this.  unknown if zero. */
 | 
				
			||||||
 | 
						__le16 compat_version;
 | 
				
			||||||
 | 
						__le16 reserved;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CEPH_MSG_PRIO_LOW     64
 | 
					#define CEPH_MSG_PRIO_LOW     64
 | 
				
			||||||
#define CEPH_MSG_PRIO_DEFAULT 127
 | 
					#define CEPH_MSG_PRIO_DEFAULT 127
 | 
				
			||||||
#define CEPH_MSG_PRIO_HIGH    196
 | 
					#define CEPH_MSG_PRIO_HIGH    196
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,9 @@ config CEPH_LIB
 | 
				
			||||||
	select LIBCRC32C
 | 
						select LIBCRC32C
 | 
				
			||||||
	select CRYPTO_AES
 | 
						select CRYPTO_AES
 | 
				
			||||||
	select CRYPTO_CBC
 | 
						select CRYPTO_CBC
 | 
				
			||||||
 | 
						select CRYPTO_GCM
 | 
				
			||||||
 | 
						select CRYPTO_HMAC
 | 
				
			||||||
 | 
						select CRYPTO_SHA256
 | 
				
			||||||
	select CRYPTO
 | 
						select CRYPTO
 | 
				
			||||||
	select KEYS
 | 
						select KEYS
 | 
				
			||||||
	default n
 | 
						default n
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,4 +15,4 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
 | 
				
			||||||
	auth_x.o \
 | 
						auth_x.o \
 | 
				
			||||||
	ceph_strings.o ceph_hash.o \
 | 
						ceph_strings.o ceph_hash.o \
 | 
				
			||||||
	pagevec.o snapshot.o string_table.o \
 | 
						pagevec.o snapshot.o string_table.o \
 | 
				
			||||||
	messenger_v1.o
 | 
						messenger_v1.o messenger_v2.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										309
									
								
								net/ceph/auth.c
									
									
									
									
									
								
							
							
						
						
									
										309
									
								
								net/ceph/auth.c
									
									
									
									
									
								
							| 
						 | 
					@ -293,6 +293,39 @@ int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(ceph_auth_is_authenticated);
 | 
					EXPORT_SYMBOL(ceph_auth_is_authenticated);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int __ceph_auth_get_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
								       struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
								       int peer_type, bool force_new,
 | 
				
			||||||
 | 
								       int *proto, int *pref_mode, int *fallb_mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&ac->mutex);
 | 
				
			||||||
 | 
						if (force_new && auth->authorizer) {
 | 
				
			||||||
 | 
							ceph_auth_destroy_authorizer(auth->authorizer);
 | 
				
			||||||
 | 
							auth->authorizer = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!auth->authorizer)
 | 
				
			||||||
 | 
							ret = ac->ops->create_authorizer(ac, peer_type, auth);
 | 
				
			||||||
 | 
						else if (ac->ops->update_authorizer)
 | 
				
			||||||
 | 
							ret = ac->ops->update_authorizer(ac, peer_type, auth);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ret = 0;
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*proto = ac->protocol;
 | 
				
			||||||
 | 
						if (pref_mode && fallb_mode) {
 | 
				
			||||||
 | 
							*pref_mode = ac->preferred_mode;
 | 
				
			||||||
 | 
							*fallb_mode = ac->fallback_mode;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(__ceph_auth_get_authorizer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
 | 
					int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
				int peer_type,
 | 
									int peer_type,
 | 
				
			||||||
				struct ceph_auth_handshake *auth)
 | 
									struct ceph_auth_handshake *auth)
 | 
				
			||||||
| 
						 | 
					@ -369,3 +402,279 @@ void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
 | 
				
			||||||
	mutex_unlock(&ac->mutex);
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
 | 
					EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * msgr2 authentication
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool contains(const int *arr, int cnt, int val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < cnt; i++) {
 | 
				
			||||||
 | 
							if (arr[i] == val)
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int encode_con_modes(void **p, void *end, int pref_mode, int fallb_mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						WARN_ON(pref_mode == CEPH_CON_MODE_UNKNOWN);
 | 
				
			||||||
 | 
						if (fallb_mode != CEPH_CON_MODE_UNKNOWN) {
 | 
				
			||||||
 | 
							ceph_encode_32_safe(p, end, 2, e_range);
 | 
				
			||||||
 | 
							ceph_encode_32_safe(p, end, pref_mode, e_range);
 | 
				
			||||||
 | 
							ceph_encode_32_safe(p, end, fallb_mode, e_range);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ceph_encode_32_safe(p, end, 1, e_range);
 | 
				
			||||||
 | 
							ceph_encode_32_safe(p, end, pref_mode, e_range);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					e_range:
 | 
				
			||||||
 | 
						return -ERANGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Similar to ceph_auth_build_hello().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int ceph_auth_get_request(struct ceph_auth_client *ac, void *buf, int buf_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int proto = ac->key ? CEPH_AUTH_CEPHX : CEPH_AUTH_NONE;
 | 
				
			||||||
 | 
						void *end = buf + buf_len;
 | 
				
			||||||
 | 
						void *lenp;
 | 
				
			||||||
 | 
						void *p;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&ac->mutex);
 | 
				
			||||||
 | 
						if (ac->protocol == CEPH_AUTH_UNKNOWN) {
 | 
				
			||||||
 | 
							ret = init_protocol(ac, proto);
 | 
				
			||||||
 | 
							if (ret) {
 | 
				
			||||||
 | 
								pr_err("auth protocol '%s' init failed: %d\n",
 | 
				
			||||||
 | 
								       ceph_auth_proto_name(proto), ret);
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							WARN_ON(ac->protocol != proto);
 | 
				
			||||||
 | 
							ac->ops->reset(ac);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = buf;
 | 
				
			||||||
 | 
						ceph_encode_32_safe(&p, end, ac->protocol, e_range);
 | 
				
			||||||
 | 
						ret = encode_con_modes(&p, end, ac->preferred_mode, ac->fallback_mode);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lenp = p;
 | 
				
			||||||
 | 
						p += 4;  /* space for len */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ceph_encode_8_safe(&p, end, CEPH_AUTH_MODE_MON, e_range);
 | 
				
			||||||
 | 
						ret = ceph_auth_entity_name_encode(ac->name, &p, end);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ceph_encode_64_safe(&p, end, ac->global_id, e_range);
 | 
				
			||||||
 | 
						ceph_encode_32(&lenp, p - lenp - 4);
 | 
				
			||||||
 | 
						ret = p - buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					e_range:
 | 
				
			||||||
 | 
						ret = -ERANGE;
 | 
				
			||||||
 | 
						goto out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_auth_handle_reply_more(struct ceph_auth_client *ac, void *reply,
 | 
				
			||||||
 | 
									int reply_len, void *buf, int buf_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&ac->mutex);
 | 
				
			||||||
 | 
						ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len,
 | 
				
			||||||
 | 
									    NULL, NULL, NULL, NULL);
 | 
				
			||||||
 | 
						if (ret == -EAGAIN)
 | 
				
			||||||
 | 
							ret = build_request(ac, false, buf, buf_len);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							WARN_ON(ret >= 0);
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_auth_handle_reply_done(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									u64 global_id, void *reply, int reply_len,
 | 
				
			||||||
 | 
									u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									u8 *con_secret, int *con_secret_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&ac->mutex);
 | 
				
			||||||
 | 
						if (global_id && ac->global_id != global_id) {
 | 
				
			||||||
 | 
							dout("%s global_id %llu -> %llu\n", __func__, ac->global_id,
 | 
				
			||||||
 | 
							     global_id);
 | 
				
			||||||
 | 
							ac->global_id = global_id;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len,
 | 
				
			||||||
 | 
									    session_key, session_key_len,
 | 
				
			||||||
 | 
									    con_secret, con_secret_len);
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ceph_auth_handle_bad_method(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									 int used_proto, int result,
 | 
				
			||||||
 | 
									 const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									 const int *allowed_modes, int mode_cnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mutex_lock(&ac->mutex);
 | 
				
			||||||
 | 
						WARN_ON(used_proto != ac->protocol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (result == -EOPNOTSUPP) {
 | 
				
			||||||
 | 
							if (!contains(allowed_protos, proto_cnt, ac->protocol)) {
 | 
				
			||||||
 | 
								pr_err("auth protocol '%s' not allowed\n",
 | 
				
			||||||
 | 
								       ceph_auth_proto_name(ac->protocol));
 | 
				
			||||||
 | 
								goto not_allowed;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!contains(allowed_modes, mode_cnt, ac->preferred_mode) &&
 | 
				
			||||||
 | 
							    (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN ||
 | 
				
			||||||
 | 
							     !contains(allowed_modes, mode_cnt, ac->fallback_mode))) {
 | 
				
			||||||
 | 
								pr_err("preferred mode '%s' not allowed\n",
 | 
				
			||||||
 | 
								       ceph_con_mode_name(ac->preferred_mode));
 | 
				
			||||||
 | 
								if (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN)
 | 
				
			||||||
 | 
									pr_err("no fallback mode\n");
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									pr_err("fallback mode '%s' not allowed\n",
 | 
				
			||||||
 | 
									       ceph_con_mode_name(ac->fallback_mode));
 | 
				
			||||||
 | 
								goto not_allowed;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WARN_ON(result == -EOPNOTSUPP || result >= 0);
 | 
				
			||||||
 | 
						pr_err("auth protocol '%s' msgr authentication failed: %d\n",
 | 
				
			||||||
 | 
						       ceph_auth_proto_name(ac->protocol), result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					not_allowed:
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_auth_get_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
								     struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
								     int peer_type, void *buf, int *buf_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void *end = buf + *buf_len;
 | 
				
			||||||
 | 
						int pref_mode, fallb_mode;
 | 
				
			||||||
 | 
						int proto;
 | 
				
			||||||
 | 
						void *p;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = __ceph_auth_get_authorizer(ac, auth, peer_type, true, &proto,
 | 
				
			||||||
 | 
										 &pref_mode, &fallb_mode);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = buf;
 | 
				
			||||||
 | 
						ceph_encode_32_safe(&p, end, proto, e_range);
 | 
				
			||||||
 | 
						ret = encode_con_modes(&p, end, pref_mode, fallb_mode);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ceph_encode_32_safe(&p, end, auth->authorizer_buf_len, e_range);
 | 
				
			||||||
 | 
						*buf_len = p - buf;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					e_range:
 | 
				
			||||||
 | 
						return -ERANGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ceph_auth_get_authorizer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_auth_handle_svc_reply_more(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									    struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
									    void *reply, int reply_len,
 | 
				
			||||||
 | 
									    void *buf, int *buf_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void *end = buf + *buf_len;
 | 
				
			||||||
 | 
						void *p;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ceph_auth_add_authorizer_challenge(ac, auth->authorizer,
 | 
				
			||||||
 | 
											 reply, reply_len);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = buf;
 | 
				
			||||||
 | 
						ceph_encode_32_safe(&p, end, auth->authorizer_buf_len, e_range);
 | 
				
			||||||
 | 
						*buf_len = p - buf;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					e_range:
 | 
				
			||||||
 | 
						return -ERANGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ceph_auth_handle_svc_reply_more);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_auth_handle_svc_reply_done(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									    struct ceph_auth_handshake *auth,
 | 
				
			||||||
 | 
									    void *reply, int reply_len,
 | 
				
			||||||
 | 
									    u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									    u8 *con_secret, int *con_secret_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ceph_auth_verify_authorizer_reply(ac, auth->authorizer,
 | 
				
			||||||
 | 
							reply, reply_len, session_key, session_key_len,
 | 
				
			||||||
 | 
							con_secret, con_secret_len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ceph_auth_handle_svc_reply_done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ceph_auth_handle_bad_authorizer(struct ceph_auth_client *ac,
 | 
				
			||||||
 | 
									     int peer_type, int used_proto, int result,
 | 
				
			||||||
 | 
									     const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									     const int *allowed_modes, int mode_cnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mutex_lock(&ac->mutex);
 | 
				
			||||||
 | 
						WARN_ON(used_proto != ac->protocol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (result == -EOPNOTSUPP) {
 | 
				
			||||||
 | 
							if (!contains(allowed_protos, proto_cnt, ac->protocol)) {
 | 
				
			||||||
 | 
								pr_err("auth protocol '%s' not allowed by %s\n",
 | 
				
			||||||
 | 
								       ceph_auth_proto_name(ac->protocol),
 | 
				
			||||||
 | 
								       ceph_entity_type_name(peer_type));
 | 
				
			||||||
 | 
								goto not_allowed;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!contains(allowed_modes, mode_cnt, ac->preferred_mode) &&
 | 
				
			||||||
 | 
							    (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN ||
 | 
				
			||||||
 | 
							     !contains(allowed_modes, mode_cnt, ac->fallback_mode))) {
 | 
				
			||||||
 | 
								pr_err("preferred mode '%s' not allowed by %s\n",
 | 
				
			||||||
 | 
								       ceph_con_mode_name(ac->preferred_mode),
 | 
				
			||||||
 | 
								       ceph_entity_type_name(peer_type));
 | 
				
			||||||
 | 
								if (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN)
 | 
				
			||||||
 | 
									pr_err("no fallback mode\n");
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									pr_err("fallback mode '%s' not allowed by %s\n",
 | 
				
			||||||
 | 
									       ceph_con_mode_name(ac->fallback_mode),
 | 
				
			||||||
 | 
									       ceph_entity_type_name(peer_type));
 | 
				
			||||||
 | 
								goto not_allowed;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WARN_ON(result == -EOPNOTSUPP || result >= 0);
 | 
				
			||||||
 | 
						pr_err("auth protocol '%s' authorization to %s failed: %d\n",
 | 
				
			||||||
 | 
						       ceph_auth_proto_name(ac->protocol),
 | 
				
			||||||
 | 
						       ceph_entity_type_name(peer_type), result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ac->ops->invalidate_authorizer)
 | 
				
			||||||
 | 
							ac->ops->invalidate_authorizer(ac, peer_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					not_allowed:
 | 
				
			||||||
 | 
						mutex_unlock(&ac->mutex);
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ceph_auth_handle_bad_authorizer);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
// SPDX-License-Identifier: GPL-2.0
 | 
					// SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
#include <linux/ceph/ceph_debug.h>
 | 
					#include <linux/ceph/ceph_debug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/ceph/decode.h>
 | 
					#include <linux/ceph/decode.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					@ -138,3 +140,46 @@ int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
 | 
				
			||||||
	return -EINVAL;
 | 
						return -EINVAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(ceph_decode_entity_addrvec);
 | 
					EXPORT_SYMBOL(ceph_decode_entity_addrvec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int get_sockaddr_encoding_len(sa_family_t family)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct sockaddr sa;
 | 
				
			||||||
 | 
							struct sockaddr_in sin;
 | 
				
			||||||
 | 
							struct sockaddr_in6 sin6;
 | 
				
			||||||
 | 
						} u;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (family) {
 | 
				
			||||||
 | 
						case AF_INET:
 | 
				
			||||||
 | 
							return sizeof(u.sin);
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							return sizeof(u.sin6);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return sizeof(u);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ceph_entity_addr_encoding_len(const struct ceph_entity_addr *addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sa_family_t family = get_unaligned(&addr->in_addr.ss_family);
 | 
				
			||||||
 | 
						int addr_len = get_sockaddr_encoding_len(family);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1 + CEPH_ENCODING_START_BLK_LEN + 4 + 4 + 4 + addr_len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ceph_encode_entity_addr(void **p, const struct ceph_entity_addr *addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sa_family_t family = get_unaligned(&addr->in_addr.ss_family);
 | 
				
			||||||
 | 
						int addr_len = get_sockaddr_encoding_len(family);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ceph_encode_8(p, 1);  /* marker */
 | 
				
			||||||
 | 
						ceph_start_encoding(p, 1, 1, sizeof(addr->type) +
 | 
				
			||||||
 | 
									     sizeof(addr->nonce) +
 | 
				
			||||||
 | 
									     sizeof(u32) + addr_len);
 | 
				
			||||||
 | 
						ceph_encode_copy(p, &addr->type, sizeof(addr->type));
 | 
				
			||||||
 | 
						ceph_encode_copy(p, &addr->nonce, sizeof(addr->nonce));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ceph_encode_32(p, addr_len);
 | 
				
			||||||
 | 
						ceph_encode_16(p, family);
 | 
				
			||||||
 | 
						ceph_encode_copy(p, addr->in_addr.__data, addr_len - sizeof(family));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,8 +195,11 @@ EXPORT_SYMBOL(ceph_pr_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ceph_encode_my_addr(struct ceph_messenger *msgr)
 | 
					void ceph_encode_my_addr(struct ceph_messenger *msgr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	memcpy(&msgr->my_enc_addr, &msgr->inst.addr, sizeof(msgr->my_enc_addr));
 | 
						if (!ceph_msgr2(from_msgr(msgr))) {
 | 
				
			||||||
	ceph_encode_banner_addr(&msgr->my_enc_addr);
 | 
							memcpy(&msgr->my_enc_addr, &msgr->inst.addr,
 | 
				
			||||||
 | 
							       sizeof(msgr->my_enc_addr));
 | 
				
			||||||
 | 
							ceph_encode_banner_addr(&msgr->my_enc_addr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -513,7 +516,10 @@ static void ceph_con_reset_protocol(struct ceph_connection *con)
 | 
				
			||||||
		con->out_msg = NULL;
 | 
							con->out_msg = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ceph_con_v1_reset_protocol(con);
 | 
						if (ceph_msgr2(from_msgr(con->msgr)))
 | 
				
			||||||
 | 
							ceph_con_v2_reset_protocol(con);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ceph_con_v1_reset_protocol(con);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -526,6 +532,7 @@ static void ceph_msg_remove(struct ceph_msg *msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ceph_msg_put(msg);
 | 
						ceph_msg_put(msg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ceph_msg_remove_list(struct list_head *head)
 | 
					static void ceph_msg_remove_list(struct list_head *head)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	while (!list_empty(head)) {
 | 
						while (!list_empty(head)) {
 | 
				
			||||||
| 
						 | 
					@ -547,7 +554,10 @@ void ceph_con_reset_session(struct ceph_connection *con)
 | 
				
			||||||
	con->in_seq = 0;
 | 
						con->in_seq = 0;
 | 
				
			||||||
	con->in_seq_acked = 0;
 | 
						con->in_seq_acked = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ceph_con_v1_reset_session(con);
 | 
						if (ceph_msgr2(from_msgr(con->msgr)))
 | 
				
			||||||
 | 
							ceph_con_v2_reset_session(con);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ceph_con_v1_reset_session(con);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -600,6 +610,9 @@ EXPORT_SYMBOL(ceph_con_open);
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool ceph_con_opened(struct ceph_connection *con)
 | 
					bool ceph_con_opened(struct ceph_connection *con)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (ceph_msgr2(from_msgr(con->msgr)))
 | 
				
			||||||
 | 
							return ceph_con_v2_opened(con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ceph_con_v1_opened(con);
 | 
						return ceph_con_v1_opened(con);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1302,7 +1315,16 @@ int ceph_parse_ips(const char *c, const char *end,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ceph_addr_set_port(&addr[i], port);
 | 
							ceph_addr_set_port(&addr[i], port);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * We want the type to be set according to ms_mode
 | 
				
			||||||
 | 
							 * option, but options are normally parsed after mon
 | 
				
			||||||
 | 
							 * addresses.  Rather than complicating parsing, set
 | 
				
			||||||
 | 
							 * to LEGACY and override in build_initial_monmap()
 | 
				
			||||||
 | 
							 * for mon addresses and ceph_messenger_init() for
 | 
				
			||||||
 | 
							 * ip option.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
		addr[i].type = CEPH_ENTITY_ADDR_TYPE_LEGACY;
 | 
							addr[i].type = CEPH_ENTITY_ADDR_TYPE_LEGACY;
 | 
				
			||||||
 | 
							addr[i].nonce = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dout("parse_ips got %s\n", ceph_pr_addr(&addr[i]));
 | 
							dout("parse_ips got %s\n", ceph_pr_addr(&addr[i]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1410,6 +1432,13 @@ static bool con_sock_closed(struct ceph_connection *con)
 | 
				
			||||||
	CASE(PREOPEN);
 | 
						CASE(PREOPEN);
 | 
				
			||||||
	CASE(V1_BANNER);
 | 
						CASE(V1_BANNER);
 | 
				
			||||||
	CASE(V1_CONNECT_MSG);
 | 
						CASE(V1_CONNECT_MSG);
 | 
				
			||||||
 | 
						CASE(V2_BANNER_PREFIX);
 | 
				
			||||||
 | 
						CASE(V2_BANNER_PAYLOAD);
 | 
				
			||||||
 | 
						CASE(V2_HELLO);
 | 
				
			||||||
 | 
						CASE(V2_AUTH);
 | 
				
			||||||
 | 
						CASE(V2_AUTH_SIGNATURE);
 | 
				
			||||||
 | 
						CASE(V2_SESSION_CONNECT);
 | 
				
			||||||
 | 
						CASE(V2_SESSION_RECONNECT);
 | 
				
			||||||
	CASE(OPEN);
 | 
						CASE(OPEN);
 | 
				
			||||||
	CASE(STANDBY);
 | 
						CASE(STANDBY);
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -1494,7 +1523,10 @@ static void ceph_con_workfn(struct work_struct *work)
 | 
				
			||||||
			BUG_ON(con->sock);
 | 
								BUG_ON(con->sock);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = ceph_con_v1_try_read(con);
 | 
							if (ceph_msgr2(from_msgr(con->msgr)))
 | 
				
			||||||
 | 
								ret = ceph_con_v2_try_read(con);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ret = ceph_con_v1_try_read(con);
 | 
				
			||||||
		if (ret < 0) {
 | 
							if (ret < 0) {
 | 
				
			||||||
			if (ret == -EAGAIN)
 | 
								if (ret == -EAGAIN)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					@ -1504,7 +1536,10 @@ static void ceph_con_workfn(struct work_struct *work)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = ceph_con_v1_try_write(con);
 | 
							if (ceph_msgr2(from_msgr(con->msgr)))
 | 
				
			||||||
 | 
								ret = ceph_con_v2_try_write(con);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ret = ceph_con_v1_try_write(con);
 | 
				
			||||||
		if (ret < 0) {
 | 
							if (ret < 0) {
 | 
				
			||||||
			if (ret == -EAGAIN)
 | 
								if (ret == -EAGAIN)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					@ -1538,9 +1573,8 @@ static void con_fault(struct ceph_connection *con)
 | 
				
			||||||
		ceph_pr_addr(&con->peer_addr), con->error_msg);
 | 
							ceph_pr_addr(&con->peer_addr), con->error_msg);
 | 
				
			||||||
	con->error_msg = NULL;
 | 
						con->error_msg = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN_ON(con->state != CEPH_CON_S_V1_BANNER &&
 | 
						WARN_ON(con->state == CEPH_CON_S_STANDBY ||
 | 
				
			||||||
	       con->state != CEPH_CON_S_V1_CONNECT_MSG &&
 | 
							con->state == CEPH_CON_S_CLOSED);
 | 
				
			||||||
	       con->state != CEPH_CON_S_OPEN);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ceph_con_reset_protocol(con);
 | 
						ceph_con_reset_protocol(con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1596,7 +1630,11 @@ void ceph_messenger_init(struct ceph_messenger *msgr,
 | 
				
			||||||
		ceph_addr_set_port(&msgr->inst.addr, 0);
 | 
							ceph_addr_set_port(&msgr->inst.addr, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	msgr->inst.addr.type = 0;
 | 
						/*
 | 
				
			||||||
 | 
						 * Since nautilus, clients are identified using type ANY.
 | 
				
			||||||
 | 
						 * For msgr1, ceph_encode_banner_addr() munges it to NONE.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						msgr->inst.addr.type = CEPH_ENTITY_ADDR_TYPE_ANY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* generate a random non-zero nonce */
 | 
						/* generate a random non-zero nonce */
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
| 
						 | 
					@ -1706,7 +1744,10 @@ void ceph_msg_revoke(struct ceph_msg *msg)
 | 
				
			||||||
	if (con->out_msg == msg) {
 | 
						if (con->out_msg == msg) {
 | 
				
			||||||
		WARN_ON(con->state != CEPH_CON_S_OPEN);
 | 
							WARN_ON(con->state != CEPH_CON_S_OPEN);
 | 
				
			||||||
		dout("%s con %p msg %p was sending\n", __func__, con, msg);
 | 
							dout("%s con %p msg %p was sending\n", __func__, con, msg);
 | 
				
			||||||
		ceph_con_v1_revoke(con);
 | 
							if (ceph_msgr2(from_msgr(con->msgr)))
 | 
				
			||||||
 | 
								ceph_con_v2_revoke(con);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ceph_con_v1_revoke(con);
 | 
				
			||||||
		ceph_msg_put(con->out_msg);
 | 
							ceph_msg_put(con->out_msg);
 | 
				
			||||||
		con->out_msg = NULL;
 | 
							con->out_msg = NULL;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -1732,7 +1773,10 @@ void ceph_msg_revoke_incoming(struct ceph_msg *msg)
 | 
				
			||||||
	if (con->in_msg == msg) {
 | 
						if (con->in_msg == msg) {
 | 
				
			||||||
		WARN_ON(con->state != CEPH_CON_S_OPEN);
 | 
							WARN_ON(con->state != CEPH_CON_S_OPEN);
 | 
				
			||||||
		dout("%s con %p msg %p was recving\n", __func__, con, msg);
 | 
							dout("%s con %p msg %p was recving\n", __func__, con, msg);
 | 
				
			||||||
		ceph_con_v1_revoke_incoming(con);
 | 
							if (ceph_msgr2(from_msgr(con->msgr)))
 | 
				
			||||||
 | 
								ceph_con_v2_revoke_incoming(con);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ceph_con_v1_revoke_incoming(con);
 | 
				
			||||||
		ceph_msg_put(con->in_msg);
 | 
							ceph_msg_put(con->in_msg);
 | 
				
			||||||
		con->in_msg = NULL;
 | 
							con->in_msg = NULL;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										3443
									
								
								net/ceph/messenger_v2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3443
									
								
								net/ceph/messenger_v2.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -257,10 +257,16 @@ static void __open_session(struct ceph_mon_client *monc)
 | 
				
			||||||
		      &monc->monmap->mon_inst[monc->cur_mon].addr);
 | 
							      &monc->monmap->mon_inst[monc->cur_mon].addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * send an initial keepalive to ensure our timestamp is valid
 | 
						 * Queue a keepalive to ensure that in case of an early fault
 | 
				
			||||||
	 * by the time we are in an OPENED state
 | 
						 * the messenger doesn't put us into STANDBY state and instead
 | 
				
			||||||
 | 
						 * retries.  This also ensures that our timestamp is valid by
 | 
				
			||||||
 | 
						 * the time we finish hunting and delayed_work() checks it.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	ceph_con_keepalive(&monc->con);
 | 
						ceph_con_keepalive(&monc->con);
 | 
				
			||||||
 | 
						if (ceph_msgr2(monc->client)) {
 | 
				
			||||||
 | 
							monc->pending_auth = 1;
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* initiate authentication handshake */
 | 
						/* initiate authentication handshake */
 | 
				
			||||||
	ret = ceph_auth_build_hello(monc->auth,
 | 
						ret = ceph_auth_build_hello(monc->auth,
 | 
				
			||||||
| 
						 | 
					@ -543,7 +549,7 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
 | 
				
			||||||
	p = msg->front.iov_base;
 | 
						p = msg->front.iov_base;
 | 
				
			||||||
	end = p + msg->front.iov_len;
 | 
						end = p + msg->front.iov_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	monmap = ceph_monmap_decode(&p, end, false);
 | 
						monmap = ceph_monmap_decode(&p, end, ceph_msgr2(client));
 | 
				
			||||||
	if (IS_ERR(monmap)) {
 | 
						if (IS_ERR(monmap)) {
 | 
				
			||||||
		pr_err("problem decoding monmap, %d\n",
 | 
							pr_err("problem decoding monmap, %d\n",
 | 
				
			||||||
		       (int)PTR_ERR(monmap));
 | 
							       (int)PTR_ERR(monmap));
 | 
				
			||||||
| 
						 | 
					@ -1119,8 +1125,9 @@ static void delayed_work(struct work_struct *work)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int build_initial_monmap(struct ceph_mon_client *monc)
 | 
					static int build_initial_monmap(struct ceph_mon_client *monc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						__le32 my_type = ceph_msgr2(monc->client) ?
 | 
				
			||||||
 | 
							CEPH_ENTITY_ADDR_TYPE_MSGR2 : CEPH_ENTITY_ADDR_TYPE_LEGACY;
 | 
				
			||||||
	struct ceph_options *opt = monc->client->options;
 | 
						struct ceph_options *opt = monc->client->options;
 | 
				
			||||||
	struct ceph_entity_addr *mon_addr = opt->mon_addr;
 | 
					 | 
				
			||||||
	int num_mon = opt->num_mon;
 | 
						int num_mon = opt->num_mon;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1129,12 +1136,16 @@ static int build_initial_monmap(struct ceph_mon_client *monc)
 | 
				
			||||||
			       GFP_KERNEL);
 | 
								       GFP_KERNEL);
 | 
				
			||||||
	if (!monc->monmap)
 | 
						if (!monc->monmap)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < num_mon; i++) {
 | 
						for (i = 0; i < num_mon; i++) {
 | 
				
			||||||
		monc->monmap->mon_inst[i].addr = mon_addr[i];
 | 
							struct ceph_entity_inst *inst = &monc->monmap->mon_inst[i];
 | 
				
			||||||
		monc->monmap->mon_inst[i].addr.nonce = 0;
 | 
					
 | 
				
			||||||
		monc->monmap->mon_inst[i].name.type =
 | 
							memcpy(&inst->addr.in_addr, &opt->mon_addr[i].in_addr,
 | 
				
			||||||
			CEPH_ENTITY_TYPE_MON;
 | 
							       sizeof(inst->addr.in_addr));
 | 
				
			||||||
		monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
 | 
							inst->addr.type = my_type;
 | 
				
			||||||
 | 
							inst->addr.nonce = 0;
 | 
				
			||||||
 | 
							inst->name.type = CEPH_ENTITY_TYPE_MON;
 | 
				
			||||||
 | 
							inst->name.num = cpu_to_le64(i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	monc->monmap->num_mon = num_mon;
 | 
						monc->monmap->num_mon = num_mon;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -1337,6 +1348,88 @@ int ceph_monc_validate_auth(struct ceph_mon_client *monc)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(ceph_monc_validate_auth);
 | 
					EXPORT_SYMBOL(ceph_monc_validate_auth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mon_get_auth_request(struct ceph_connection *con,
 | 
				
			||||||
 | 
									void *buf, int *buf_len,
 | 
				
			||||||
 | 
									void **authorizer, int *authorizer_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mon_client *monc = con->private;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&monc->mutex);
 | 
				
			||||||
 | 
						ret = ceph_auth_get_request(monc->auth, buf, *buf_len);
 | 
				
			||||||
 | 
						mutex_unlock(&monc->mutex);
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*buf_len = ret;
 | 
				
			||||||
 | 
						*authorizer = NULL;
 | 
				
			||||||
 | 
						*authorizer_len = 0;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mon_handle_auth_reply_more(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      void *reply, int reply_len,
 | 
				
			||||||
 | 
									      void *buf, int *buf_len,
 | 
				
			||||||
 | 
									      void **authorizer, int *authorizer_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mon_client *monc = con->private;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&monc->mutex);
 | 
				
			||||||
 | 
						ret = ceph_auth_handle_reply_more(monc->auth, reply, reply_len,
 | 
				
			||||||
 | 
										  buf, *buf_len);
 | 
				
			||||||
 | 
						mutex_unlock(&monc->mutex);
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*buf_len = ret;
 | 
				
			||||||
 | 
						*authorizer = NULL;
 | 
				
			||||||
 | 
						*authorizer_len = 0;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mon_handle_auth_done(struct ceph_connection *con,
 | 
				
			||||||
 | 
									u64 global_id, void *reply, int reply_len,
 | 
				
			||||||
 | 
									u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									u8 *con_secret, int *con_secret_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mon_client *monc = con->private;
 | 
				
			||||||
 | 
						bool was_authed;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&monc->mutex);
 | 
				
			||||||
 | 
						WARN_ON(!monc->hunting);
 | 
				
			||||||
 | 
						was_authed = ceph_auth_is_authenticated(monc->auth);
 | 
				
			||||||
 | 
						ret = ceph_auth_handle_reply_done(monc->auth, global_id,
 | 
				
			||||||
 | 
										  reply, reply_len,
 | 
				
			||||||
 | 
										  session_key, session_key_len,
 | 
				
			||||||
 | 
										  con_secret, con_secret_len);
 | 
				
			||||||
 | 
						finish_auth(monc, ret, was_authed);
 | 
				
			||||||
 | 
						if (!ret)
 | 
				
			||||||
 | 
							finish_hunting(monc);
 | 
				
			||||||
 | 
						mutex_unlock(&monc->mutex);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mon_handle_auth_bad_method(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      int used_proto, int result,
 | 
				
			||||||
 | 
									      const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									      const int *allowed_modes, int mode_cnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_mon_client *monc = con->private;
 | 
				
			||||||
 | 
						bool was_authed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&monc->mutex);
 | 
				
			||||||
 | 
						WARN_ON(!monc->hunting);
 | 
				
			||||||
 | 
						was_authed = ceph_auth_is_authenticated(monc->auth);
 | 
				
			||||||
 | 
						ceph_auth_handle_bad_method(monc->auth, used_proto, result,
 | 
				
			||||||
 | 
									    allowed_protos, proto_cnt,
 | 
				
			||||||
 | 
									    allowed_modes, mode_cnt);
 | 
				
			||||||
 | 
						finish_auth(monc, -EACCES, was_authed);
 | 
				
			||||||
 | 
						mutex_unlock(&monc->mutex);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * handle incoming message
 | 
					 * handle incoming message
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1487,4 +1580,8 @@ static const struct ceph_connection_operations mon_con_ops = {
 | 
				
			||||||
	.dispatch = dispatch,
 | 
						.dispatch = dispatch,
 | 
				
			||||||
	.fault = mon_fault,
 | 
						.fault = mon_fault,
 | 
				
			||||||
	.alloc_msg = mon_alloc_msg,
 | 
						.alloc_msg = mon_alloc_msg,
 | 
				
			||||||
 | 
						.get_auth_request = mon_get_auth_request,
 | 
				
			||||||
 | 
						.handle_auth_reply_more = mon_handle_auth_reply_more,
 | 
				
			||||||
 | 
						.handle_auth_done = mon_handle_auth_done,
 | 
				
			||||||
 | 
						.handle_auth_bad_method = mon_handle_auth_bad_method,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3918,9 +3918,11 @@ static int handle_one_map(struct ceph_osd_client *osdc,
 | 
				
			||||||
	set_pool_was_full(osdc);
 | 
						set_pool_was_full(osdc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (incremental)
 | 
						if (incremental)
 | 
				
			||||||
		newmap = osdmap_apply_incremental(&p, end, false, osdc->osdmap);
 | 
							newmap = osdmap_apply_incremental(&p, end,
 | 
				
			||||||
 | 
											  ceph_msgr2(osdc->client),
 | 
				
			||||||
 | 
											  osdc->osdmap);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		newmap = ceph_osdmap_decode(&p, end, false);
 | 
							newmap = ceph_osdmap_decode(&p, end, ceph_msgr2(osdc->client));
 | 
				
			||||||
	if (IS_ERR(newmap))
 | 
						if (IS_ERR(newmap))
 | 
				
			||||||
		return PTR_ERR(newmap);
 | 
							return PTR_ERR(newmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5575,6 +5577,7 @@ static void put_osd_con(struct ceph_connection *con)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * authentication
 | 
					 * authentication
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Note: returned pointer is the address of a structure that's
 | 
					 * Note: returned pointer is the address of a structure that's
 | 
				
			||||||
 * managed separately.  Caller must *not* attempt to free it.
 | 
					 * managed separately.  Caller must *not* attempt to free it.
 | 
				
			||||||
| 
						 | 
					@ -5640,6 +5643,80 @@ static int invalidate_authorizer(struct ceph_connection *con)
 | 
				
			||||||
	return ceph_monc_validate_auth(&osdc->client->monc);
 | 
						return ceph_monc_validate_auth(&osdc->client->monc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int osd_get_auth_request(struct ceph_connection *con,
 | 
				
			||||||
 | 
									void *buf, int *buf_len,
 | 
				
			||||||
 | 
									void **authorizer, int *authorizer_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_osd *o = con->private;
 | 
				
			||||||
 | 
						struct ceph_auth_client *ac = o->o_osdc->client->monc.auth;
 | 
				
			||||||
 | 
						struct ceph_auth_handshake *auth = &o->o_auth;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ceph_auth_get_authorizer(ac, auth, CEPH_ENTITY_TYPE_OSD,
 | 
				
			||||||
 | 
									       buf, buf_len);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*authorizer = auth->authorizer_buf;
 | 
				
			||||||
 | 
						*authorizer_len = auth->authorizer_buf_len;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int osd_handle_auth_reply_more(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      void *reply, int reply_len,
 | 
				
			||||||
 | 
									      void *buf, int *buf_len,
 | 
				
			||||||
 | 
									      void **authorizer, int *authorizer_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_osd *o = con->private;
 | 
				
			||||||
 | 
						struct ceph_auth_client *ac = o->o_osdc->client->monc.auth;
 | 
				
			||||||
 | 
						struct ceph_auth_handshake *auth = &o->o_auth;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ceph_auth_handle_svc_reply_more(ac, auth, reply, reply_len,
 | 
				
			||||||
 | 
										      buf, buf_len);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*authorizer = auth->authorizer_buf;
 | 
				
			||||||
 | 
						*authorizer_len = auth->authorizer_buf_len;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int osd_handle_auth_done(struct ceph_connection *con,
 | 
				
			||||||
 | 
									u64 global_id, void *reply, int reply_len,
 | 
				
			||||||
 | 
									u8 *session_key, int *session_key_len,
 | 
				
			||||||
 | 
									u8 *con_secret, int *con_secret_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_osd *o = con->private;
 | 
				
			||||||
 | 
						struct ceph_auth_client *ac = o->o_osdc->client->monc.auth;
 | 
				
			||||||
 | 
						struct ceph_auth_handshake *auth = &o->o_auth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ceph_auth_handle_svc_reply_done(ac, auth, reply, reply_len,
 | 
				
			||||||
 | 
										       session_key, session_key_len,
 | 
				
			||||||
 | 
										       con_secret, con_secret_len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int osd_handle_auth_bad_method(struct ceph_connection *con,
 | 
				
			||||||
 | 
									      int used_proto, int result,
 | 
				
			||||||
 | 
									      const int *allowed_protos, int proto_cnt,
 | 
				
			||||||
 | 
									      const int *allowed_modes, int mode_cnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ceph_osd *o = con->private;
 | 
				
			||||||
 | 
						struct ceph_mon_client *monc = &o->o_osdc->client->monc;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ceph_auth_handle_bad_authorizer(monc->auth, CEPH_ENTITY_TYPE_OSD,
 | 
				
			||||||
 | 
										    used_proto, result,
 | 
				
			||||||
 | 
										    allowed_protos, proto_cnt,
 | 
				
			||||||
 | 
										    allowed_modes, mode_cnt)) {
 | 
				
			||||||
 | 
							ret = ceph_monc_validate_auth(monc);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return -EACCES;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void osd_reencode_message(struct ceph_msg *msg)
 | 
					static void osd_reencode_message(struct ceph_msg *msg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int type = le16_to_cpu(msg->hdr.type);
 | 
						int type = le16_to_cpu(msg->hdr.type);
 | 
				
			||||||
| 
						 | 
					@ -5677,4 +5754,8 @@ static const struct ceph_connection_operations osd_con_ops = {
 | 
				
			||||||
	.sign_message = osd_sign_message,
 | 
						.sign_message = osd_sign_message,
 | 
				
			||||||
	.check_message_signature = osd_check_message_signature,
 | 
						.check_message_signature = osd_check_message_signature,
 | 
				
			||||||
	.fault = osd_fault,
 | 
						.fault = osd_fault,
 | 
				
			||||||
 | 
						.get_auth_request = osd_get_auth_request,
 | 
				
			||||||
 | 
						.handle_auth_reply_more = osd_handle_auth_reply_more,
 | 
				
			||||||
 | 
						.handle_auth_done = osd_handle_auth_done,
 | 
				
			||||||
 | 
						.handle_auth_bad_method = osd_handle_auth_bad_method,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue