Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b7c4f7a authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'rxrpc-rewrite-20160622-2' of...

Merge tag 'rxrpc-rewrite-20160622-2' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs



David Howells says:

====================
rxrpc: Get rid of conn bundle and transport structs

Here's the next part of the AF_RXRPC rewrite.  The primary purpose of this
set is to get rid of the rxrpc_conn_bundle and rxrpc_transport structs.
This simplifies things for future development of the connection handling.

To this end, the following significant changes are made:

 (1) The rxrpc_connection struct is given pointers to the local and peer
     endpoints, inside the rxrpc_conn_parameters struct.  Pointers to the
     transport's copy of these pointers are then redirected to the
     connection struct.

 (2) Exclusive connection handling is fixed.  Exclusive connections should
     do just one call and then be retired.  They are used in security
     negotiations and, I believe, the idea is to avoid reuse of negotiated
     security contexts.

     The current code is doing a single connection per socket and doing all
     the calls over that.  With this change it gets a new connection for
     each call made.

 (3) A new sendmsg() control message marker is added to make individual
     calls operate over exclusive connections.  This should be used in
     future in preference to the sockopt that marks a socket as "exclusive
     connection".

 (4) IDs for client connections initiated by a machine are now allocated
     from a global pool using the IDR facility and are unique across all
     client connections, no matter their destination.  The IDR facility is
     then used to look up a connection on the connection ID alone.  Other
     parameters are then verified afterwards.

     Note that the IDR facility may use a lot of memory if the IDs it holds
     are widely scattered.  Given this, in a future commit, client
     connections will be retired if they are more than a certain distance
     from the last ID allocated.

     The client epoch is advanced by 1 each time the client ID counter
     wraps.  Connections outside the current epoch will also be retired in
     a future commit.

 (5) The connection bundle concept is removed and the client connection
     tree is moved into the local endpoint.  The queue for waiting for a
     call channel is moved to the rxrpc_connection struct as there can only
     be one connection for any particular key going to any particular peer
     now.

 (6) The rxrpc_transport struct is removed and the service connection tree
     is moved into the peer struct.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e7ffd812 aa390bbe
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ struct sockaddr_rxrpc {
 */
#define RXRPC_SECURITY_KEY		1	/* [clnt] set client security key */
#define RXRPC_SECURITY_KEYRING		2	/* [srvr] set ring of server security keys */
#define RXRPC_EXCLUSIVE_CONNECTION	3	/* [clnt] use exclusive RxRPC connection */
#define RXRPC_EXCLUSIVE_CONNECTION	3	/* Deprecated; use RXRPC_EXCLUSIVE_CALL instead */
#define RXRPC_MIN_SECURITY_LEVEL	4	/* minimum security level */

/*
@@ -52,6 +52,7 @@ struct sockaddr_rxrpc {
#define RXRPC_LOCAL_ERROR	7	/* -r: local error generated [terminal] */
#define RXRPC_NEW_CALL		8	/* -r: [Service] new incoming call notification */
#define RXRPC_ACCEPT		9	/* s-: [Service] accept request */
#define RXRPC_EXCLUSIVE_CALL	10	/* s-: Call should be on exclusive connection */

/*
 * RxRPC security levels
+1 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ af-rxrpc-y := \
	call_accept.o \
	call_event.o \
	call_object.o \
	conn_client.o \
	conn_event.o \
	conn_object.o \
	input.o \
@@ -21,7 +22,6 @@ af-rxrpc-y := \
	recvmsg.o \
	security.o \
	skbuff.o \
	transport.o \
	utils.o

af-rxrpc-$(CONFIG_PROC_FS) += proc.o
+20 −67
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
	    srx->transport_len > len)
		return -EINVAL;

	if (srx->transport.family != rx->proto)
	if (srx->transport.family != rx->family)
		return -EAFNOSUPPORT;

	switch (srx->transport.family) {
@@ -224,39 +224,6 @@ static int rxrpc_listen(struct socket *sock, int backlog)
	return ret;
}

/*
 * find a transport by address
 */
struct rxrpc_transport *rxrpc_name_to_transport(struct rxrpc_sock *rx,
						struct sockaddr *addr,
						int addr_len, int flags,
						gfp_t gfp)
{
	struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *) addr;
	struct rxrpc_transport *trans;
	struct rxrpc_peer *peer;

	_enter("%p,%p,%d,%d", rx, addr, addr_len, flags);

	ASSERT(rx->local != NULL);

	if (rx->srx.transport_type != srx->transport_type)
		return ERR_PTR(-ESOCKTNOSUPPORT);
	if (rx->srx.transport.family != srx->transport.family)
		return ERR_PTR(-EAFNOSUPPORT);

	/* find a remote transport endpoint from the local one */
	peer = rxrpc_lookup_peer(rx->local, srx, gfp);
	if (IS_ERR(peer))
		return ERR_CAST(peer);

	/* find a transport */
	trans = rxrpc_get_transport(rx->local, peer, gfp);
	rxrpc_put_peer(peer);
	_leave(" = %p", trans);
	return trans;
}

/**
 * rxrpc_kernel_begin_call - Allow a kernel service to begin a call
 * @sock: The socket on which to make the call
@@ -277,39 +244,32 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
					   unsigned long user_call_ID,
					   gfp_t gfp)
{
	struct rxrpc_conn_bundle *bundle;
	struct rxrpc_transport *trans;
	struct rxrpc_conn_parameters cp;
	struct rxrpc_call *call;
	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
	int ret;

	_enter(",,%x,%lx", key_serial(key), user_call_ID);

	lock_sock(&rx->sk);
	ret = rxrpc_validate_address(rx, srx, sizeof(*srx));
	if (ret < 0)
		return ERR_PTR(ret);

	trans = rxrpc_name_to_transport(rx, (struct sockaddr *)srx,
					sizeof(*srx), 0, gfp);
	if (IS_ERR(trans)) {
		call = ERR_CAST(trans);
		trans = NULL;
		goto out_notrans;
	}
	lock_sock(&rx->sk);

	if (!key)
		key = rx->key;
	if (key && !key->payload.data[0])
		key = NULL; /* a no-security key */

	bundle = rxrpc_get_bundle(rx, trans, key, srx->srx_service, gfp);
	if (IS_ERR(bundle)) {
		call = ERR_CAST(bundle);
		goto out;
	}
	memset(&cp, 0, sizeof(cp));
	cp.local		= rx->local;
	cp.key			= key;
	cp.security_level	= 0;
	cp.exclusive		= false;
	cp.service_id		= srx->srx_service;
	call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, gfp);

	call = rxrpc_new_client_call(rx, trans, bundle, user_call_ID, gfp);
	rxrpc_put_bundle(trans, bundle);
out:
	rxrpc_put_transport(trans);
out_notrans:
	release_sock(&rx->sk);
	_leave(" = %p", call);
	return call;
@@ -487,7 +447,7 @@ static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
			ret = -EISCONN;
			if (rx->sk.sk_state != RXRPC_UNBOUND)
				goto error;
			set_bit(RXRPC_SOCK_EXCLUSIVE_CONN, &rx->flags);
			rx->exclusive = true;
			goto success;

		case RXRPC_SECURITY_KEY:
@@ -600,7 +560,7 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
	sk->sk_destruct		= rxrpc_sock_destructor;

	rx = rxrpc_sk(sk);
	rx->proto = protocol;
	rx->family = protocol;
	rx->calls = RB_ROOT;

	INIT_LIST_HEAD(&rx->listen_link);
@@ -662,16 +622,8 @@ static int rxrpc_release_sock(struct sock *sk)
	flush_workqueue(rxrpc_workqueue);
	rxrpc_purge_queue(&sk->sk_receive_queue);

	if (rx->conn) {
		rxrpc_put_connection(rx->conn);
		rx->conn = NULL;
	}

	if (rx->local) {
	rxrpc_put_local(rx->local);
	rx->local = NULL;
	}

	key_put(rx->key);
	rx->key = NULL;
	key_put(rx->securities);
@@ -836,7 +788,6 @@ static void __exit af_rxrpc_exit(void)
	proto_unregister(&rxrpc_proto);
	rxrpc_destroy_all_calls();
	rxrpc_destroy_all_connections();
	rxrpc_destroy_all_transports();

	ASSERTCMP(atomic_read(&rxrpc_n_skbs), ==, 0);

@@ -856,6 +807,8 @@ static void __exit af_rxrpc_exit(void)
	_debug("synchronise RCU");
	rcu_barrier();
	_debug("destroy locals");
	ASSERT(idr_is_empty(&rxrpc_client_conn_ids));
	idr_destroy(&rxrpc_client_conn_ids);
	rxrpc_destroy_all_locals();

	remove_proc_entry("rxrpc_conns", init_net.proc_net);
+88 −84
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ struct rxrpc_crypt {
#define rxrpc_queue_call(CALL)	rxrpc_queue_work(&(CALL)->processor)
#define rxrpc_queue_conn(CONN)	rxrpc_queue_work(&(CONN)->processor)

struct rxrpc_connection;

/*
 * sk_state for RxRPC sockets
 */
@@ -57,7 +59,6 @@ struct rxrpc_sock {
	struct sock		sk;
	rxrpc_interceptor_t	interceptor;	/* kernel service Rx interceptor function */
	struct rxrpc_local	*local;		/* local endpoint */
	struct rxrpc_connection	*conn;		/* exclusive virtual connection */
	struct list_head	listen_link;	/* link in the local endpoint's listen list */
	struct list_head	secureq;	/* calls awaiting connection security clearance */
	struct list_head	acceptq;	/* calls awaiting acceptance */
@@ -66,13 +67,13 @@ struct rxrpc_sock {
	struct rb_root		calls;		/* outstanding calls on this socket */
	unsigned long		flags;
#define RXRPC_SOCK_CONNECTED		0	/* connect_srx is set */
#define RXRPC_SOCK_EXCLUSIVE_CONN	1	/* exclusive connection for a client socket */
	rwlock_t		call_lock;	/* lock for calls */
	u32			min_sec_level;	/* minimum security level */
#define RXRPC_SECURITY_MAX	RXRPC_SECURITY_ENCRYPT
	bool			exclusive;	/* Exclusive connection for a client socket */
	sa_family_t		family;		/* Protocol family created with */
	struct sockaddr_rxrpc	srx;		/* local address */
	struct sockaddr_rxrpc	connect_srx;	/* Default client address from connect() */
	sa_family_t		proto;		/* protocol created with */
};

#define rxrpc_sk(__sk) container_of((__sk), struct rxrpc_sock, sk)
@@ -185,7 +186,8 @@ struct rxrpc_local {
	struct sk_buff_head	accept_queue;	/* incoming calls awaiting acceptance */
	struct sk_buff_head	reject_queue;	/* packets awaiting rejection */
	struct sk_buff_head	event_queue;	/* endpoint event packets awaiting processing */
	struct mutex		conn_lock;	/* Client connection creation lock */
	struct rb_root		client_conns;	/* Client connections by socket params */
	spinlock_t		client_conns_lock; /* Lock for client_conns */
	spinlock_t		lock;		/* access lock */
	rwlock_t		services_lock;	/* lock for services list */
	int			debug_id;	/* debug ID for printks */
@@ -205,6 +207,8 @@ struct rxrpc_peer {
	struct rxrpc_local	*local;
	struct hlist_head	error_targets;	/* targets for net error distribution */
	struct work_struct	error_distributor;
	struct rb_root		service_conns;	/* Service connections */
	rwlock_t		conn_lock;
	spinlock_t		lock;		/* access lock */
	unsigned int		if_mtu;		/* interface MTU for this peer */
	unsigned int		mtu;		/* network MTU for this peer */
@@ -224,66 +228,63 @@ struct rxrpc_peer {
};

/*
 * RxRPC point-to-point transport / connection manager definition
 * - handles a bundle of connections between two endpoints
 * - matched by { local, peer }
 */
struct rxrpc_transport {
	struct rxrpc_local	*local;		/* local transport endpoint */
	struct rxrpc_peer	*peer;		/* remote transport endpoint */
	struct rb_root		bundles;	/* client connection bundles on this transport */
	struct rb_root		client_conns;	/* client connections on this transport */
	struct rb_root		server_conns;	/* server connections on this transport */
	struct list_head	link;		/* link in master session list */
	unsigned long		put_time;	/* time at which to reap */
	spinlock_t		client_lock;	/* client connection allocation lock */
	rwlock_t		conn_lock;	/* lock for active/dead connections */
	atomic_t		usage;
	int			debug_id;	/* debug ID for printks */
	unsigned int		conn_idcounter;	/* connection ID counter (client) */
 * Keys for matching a connection.
 */
struct rxrpc_conn_proto {
	unsigned long		hash_key;
	struct rxrpc_local	*local;		/* Representation of local endpoint */
	u32			epoch;		/* epoch of this connection */
	u32			cid;		/* connection ID */
	u8			in_clientflag;	/* RXRPC_CLIENT_INITIATED if we are server */
	u8			addr_size;	/* Size of the address */
	sa_family_t		family;		/* Transport protocol */
	__be16			port;		/* Peer UDP/UDP6 port */
	union {					/* Peer address */
		struct in_addr	ipv4_addr;
		struct in6_addr	ipv6_addr;
		u32		raw_addr[0];
	};
};

/*
 * RxRPC client connection bundle
 * - matched by { transport, service_id, key }
 */
struct rxrpc_conn_bundle {
	struct rb_node		node;		/* node in transport's lookup tree */
	struct list_head	unused_conns;	/* unused connections in this bundle */
	struct list_head	avail_conns;	/* available connections in this bundle */
	struct list_head	busy_conns;	/* busy connections in this bundle */
	struct key		*key;		/* security for this bundle */
	wait_queue_head_t	chanwait;	/* wait for channel to become available */
	atomic_t		usage;
	int			debug_id;	/* debug ID for printks */
	unsigned short		num_conns;	/* number of connections in this bundle */
	u16			service_id;	/* Service ID for this bundle */
	u8			security_ix;	/* security type */
struct rxrpc_conn_parameters {
	struct rxrpc_local	*local;		/* Representation of local endpoint */
	struct rxrpc_peer	*peer;		/* Remote endpoint */
	struct key		*key;		/* Security details */
	bool			exclusive;	/* T if conn is exclusive */
	u16			service_id;	/* Service ID for this connection */
	u32			security_level;	/* Security level selected */
};

/*
 * RxRPC connection definition
 * - matched by { transport, service_id, conn_id, direction, key }
 * - matched by { local, peer, epoch, conn_id, direction }
 * - each connection can only handle four simultaneous calls
 */
struct rxrpc_connection {
	struct rxrpc_transport	*trans;		/* transport session */
	struct rxrpc_conn_bundle *bundle;	/* connection bundle (client) */
	struct rxrpc_conn_proto	proto;
	struct rxrpc_conn_parameters params;

	spinlock_t		channel_lock;
	struct rxrpc_call	*channels[RXRPC_MAXCALLS]; /* active calls */
	wait_queue_head_t	channel_wq;	/* queue to wait for channel to become available */

	struct work_struct	processor;	/* connection event processor */
	struct rb_node		node;		/* node in transport's lookup tree */
	union {
		struct rb_node	client_node;	/* Node in local->client_conns */
		struct rb_node	service_node;	/* Node in peer->service_conns */
	};
	struct list_head	link;		/* link in master connection list */
	struct list_head	bundle_link;	/* link in bundle */
	struct rb_root		calls;		/* calls on this connection */
	struct sk_buff_head	rx_queue;	/* received conn-level packets */
	struct rxrpc_call	*channels[RXRPC_MAXCALLS]; /* channels (active calls) */
	const struct rxrpc_security *security;	/* applied security module */
	struct key		*key;		/* security for this connection (client) */
	struct key		*server_key;	/* security for this service */
	struct crypto_skcipher	*cipher;	/* encryption handle */
	struct rxrpc_crypt	csum_iv;	/* packet checksum base */
	unsigned long		flags;
#define RXRPC_CONN_HAS_IDR	0		/* - Has a client conn ID assigned */
	unsigned long		events;
#define RXRPC_CONN_CHALLENGE	0		/* send challenge packet */
	unsigned long		put_time;	/* time at which to reap */
	unsigned long		put_time;	/* Time at which last put */
	rwlock_t		lock;		/* access lock */
	spinlock_t		state_lock;	/* state-change lock */
	atomic_t		usage;
@@ -304,17 +305,12 @@ struct rxrpc_connection {
	unsigned int		call_counter;	/* call ID counter */
	atomic_t		serial;		/* packet serial number counter */
	atomic_t		hi_serial;	/* highest serial number received */
	u8			avail_calls;	/* number of calls available */
	atomic_t		avail_chans;	/* number of channels available */
	u8			size_align;	/* data size alignment (for security) */
	u8			header_size;	/* rxrpc + security header size */
	u8			security_size;	/* security header size */
	u32			security_level;	/* security level negotiated */
	u32			security_nonce;	/* response re-use preventer */
	u32			epoch;		/* epoch of this connection */
	u32			cid;		/* connection ID */
	u16			service_id;	/* service ID for this connection */
	u8			security_ix;	/* security type */
	u8			in_clientflag;	/* RXRPC_CLIENT_INITIATED if we are server */
	u8			out_clientflag;	/* RXRPC_CLIENT_INITIATED if we are client */
};

@@ -360,6 +356,8 @@ enum rxrpc_call_event {
 * The states that a call can be in.
 */
enum rxrpc_call_state {
	RXRPC_CALL_UNINITIALISED,
	RXRPC_CALL_CLIENT_AWAIT_CONN,	/* - client waiting for connection to become available */
	RXRPC_CALL_CLIENT_SEND_REQUEST,	/* - client sending request phase */
	RXRPC_CALL_CLIENT_AWAIT_REPLY,	/* - client awaiting reply */
	RXRPC_CALL_CLIENT_RECV_REPLY,	/* - client receiving reply phase */
@@ -448,7 +446,7 @@ struct rxrpc_call {
	unsigned long		hash_key;	/* Full hash key */
	u8			in_clientflag;	/* Copy of conn->in_clientflag for hashing */
	struct rxrpc_local	*local;		/* Local endpoint. Used for hashing. */
	sa_family_t		proto;		/* Frame protocol */
	sa_family_t		family;		/* Frame protocol */
	u32			call_id;	/* call ID on connection  */
	u32			cid;		/* connection ID plus channel index */
	u32			epoch;		/* epoch of this connection */
@@ -481,10 +479,6 @@ extern u32 rxrpc_epoch;
extern atomic_t rxrpc_debug_id;
extern struct workqueue_struct *rxrpc_workqueue;

extern struct rxrpc_transport *rxrpc_name_to_transport(struct rxrpc_sock *,
						       struct sockaddr *,
						       int, int, gfp_t);

/*
 * call_accept.c
 */
@@ -512,17 +506,25 @@ struct rxrpc_call *rxrpc_find_call_hash(struct rxrpc_host_header *,
					void *, sa_family_t, const void *);
struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *, unsigned long);
struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *,
					 struct rxrpc_transport *,
					 struct rxrpc_conn_bundle *,
					 struct rxrpc_conn_parameters *,
					 struct sockaddr_rxrpc *,
					 unsigned long, gfp_t);
struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *,
				       struct rxrpc_connection *,
				       struct rxrpc_host_header *);
				       struct sk_buff *);
void rxrpc_release_call(struct rxrpc_call *);
void rxrpc_release_calls_on_socket(struct rxrpc_sock *);
void __rxrpc_put_call(struct rxrpc_call *);
void __exit rxrpc_destroy_all_calls(void);

/*
 * conn_client.c
 */
extern struct idr rxrpc_client_conn_ids;

int rxrpc_get_client_connection_id(struct rxrpc_connection *, gfp_t);
void rxrpc_put_client_connection_id(struct rxrpc_connection *);

/*
 * conn_event.c
 */
@@ -537,18 +539,32 @@ extern unsigned int rxrpc_connection_expiry;
extern struct list_head rxrpc_connections;
extern rwlock_t rxrpc_connection_lock;

struct rxrpc_conn_bundle *rxrpc_get_bundle(struct rxrpc_sock *,
					   struct rxrpc_transport *,
					   struct key *, u16, gfp_t);
void rxrpc_put_bundle(struct rxrpc_transport *, struct rxrpc_conn_bundle *);
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_transport *,
		       struct rxrpc_conn_bundle *, struct rxrpc_call *, gfp_t);
int rxrpc_connect_call(struct rxrpc_call *, struct rxrpc_conn_parameters *,
		       struct sockaddr_rxrpc *, gfp_t);
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_local *,
					       struct rxrpc_peer *,
					       struct sk_buff *);
void rxrpc_disconnect_call(struct rxrpc_call *);
void rxrpc_put_connection(struct rxrpc_connection *);
void __exit rxrpc_destroy_all_connections(void);
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *,
					       struct rxrpc_host_header *);
extern struct rxrpc_connection *
rxrpc_incoming_connection(struct rxrpc_transport *, struct rxrpc_host_header *);
struct rxrpc_connection *rxrpc_incoming_connection(struct rxrpc_local *,
						   struct rxrpc_peer *,
						   struct sk_buff *);

static inline bool rxrpc_conn_is_client(const struct rxrpc_connection *conn)
{
	return conn->out_clientflag;
}

static inline bool rxrpc_conn_is_service(const struct rxrpc_connection *conn)
{
	return conn->proto.in_clientflag;
}

static inline void rxrpc_get_connection(struct rxrpc_connection *conn)
{
	atomic_inc(&conn->usage);
}

/*
 * input.c
@@ -598,7 +614,7 @@ struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local)

static inline void rxrpc_put_local(struct rxrpc_local *local)
{
	if (atomic_dec_and_test(&local->usage))
	if (local && atomic_dec_and_test(&local->usage))
		__rxrpc_put_local(local);
}

@@ -623,7 +639,7 @@ extern const char *rxrpc_acks(u8 reason);
 */
extern unsigned int rxrpc_resend_timeout;

int rxrpc_send_packet(struct rxrpc_transport *, struct sk_buff *);
int rxrpc_send_data_packet(struct rxrpc_connection *, struct sk_buff *);
int rxrpc_do_sendmsg(struct rxrpc_sock *, struct msghdr *, size_t);

/*
@@ -655,7 +671,7 @@ struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer)
extern void __rxrpc_put_peer(struct rxrpc_peer *peer);
static inline void rxrpc_put_peer(struct rxrpc_peer *peer)
{
	if (atomic_dec_and_test(&peer->usage))
	if (peer && atomic_dec_and_test(&peer->usage))
		__rxrpc_put_peer(peer);
}

@@ -703,18 +719,6 @@ static inline int __init rxrpc_sysctl_init(void) { return 0; }
static inline void rxrpc_sysctl_exit(void) {}
#endif

/*
 * transport.c
 */
extern unsigned int rxrpc_transport_expiry;

struct rxrpc_transport *rxrpc_get_transport(struct rxrpc_local *,
					    struct rxrpc_peer *, gfp_t);
void rxrpc_put_transport(struct rxrpc_transport *);
void __exit rxrpc_destroy_all_transports(void);
struct rxrpc_transport *rxrpc_find_transport(struct rxrpc_local *,
					     struct rxrpc_peer *);

/*
 * utils.c
 */
+4 −13
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
				      struct sockaddr_rxrpc *srx)
{
	struct rxrpc_connection *conn;
	struct rxrpc_transport *trans;
	struct rxrpc_skb_priv *sp, *nsp;
	struct rxrpc_peer *peer;
	struct rxrpc_call *call;
@@ -96,29 +95,21 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
	notification->mark = RXRPC_SKB_MARK_NEW_CALL;

	peer = rxrpc_lookup_peer(local, srx, GFP_NOIO);
	if (IS_ERR(peer)) {
	if (!peer) {
		_debug("no peer");
		ret = -EBUSY;
		goto error;
	}

	trans = rxrpc_get_transport(local, peer, GFP_NOIO);
	conn = rxrpc_incoming_connection(local, peer, skb);
	rxrpc_put_peer(peer);
	if (IS_ERR(trans)) {
		_debug("no trans");
		ret = -EBUSY;
		goto error;
	}

	conn = rxrpc_incoming_connection(trans, &sp->hdr);
	rxrpc_put_transport(trans);
	if (IS_ERR(conn)) {
		_debug("no conn");
		ret = PTR_ERR(conn);
		goto error;
	}

	call = rxrpc_incoming_call(rx, conn, &sp->hdr);
	call = rxrpc_incoming_call(rx, conn, skb);
	rxrpc_put_connection(conn);
	if (IS_ERR(call)) {
		_debug("no call");
@@ -141,7 +132,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
			_debug("await conn sec");
			list_add_tail(&call->accept_link, &rx->secureq);
			call->conn->state = RXRPC_CONN_SERVER_CHALLENGING;
			atomic_inc(&call->conn->usage);
			rxrpc_get_connection(call->conn);
			set_bit(RXRPC_CONN_CHALLENGE, &call->conn->events);
			rxrpc_queue_conn(call->conn);
		} else {
Loading