net/rxrpc/conn_event.c

Source file repositories/reference/linux-study-clean/net/rxrpc/conn_event.c

File Facts

System
Linux kernel
Corpus path
net/rxrpc/conn_event.c
Extension
.c
Size
15076 bytes
Lines
596
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (conn->state != RXRPC_CONN_ABORTED) {
			conn->abort_code = abort_code;
			conn->error	 = err;
			conn->completion = compl;
			/* Order the abort info before the state change. */
			smp_store_release(&conn->state, RXRPC_CONN_ABORTED);
			set_bit(RXRPC_CONN_DONT_REUSE, &conn->flags);
			set_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events);
			aborted = true;
		}
		spin_unlock_irq(&conn->state_lock);
	}

	return aborted;
}

/*
 * Mark a socket buffer to indicate that the connection it's on should be aborted.
 */
int rxrpc_abort_conn(struct rxrpc_connection *conn, struct sk_buff *skb,
		     s32 abort_code, int err, enum rxrpc_abort_reason why)
{

	u32 cid = conn->proto.cid, call = 0, seq = 0;

	if (skb) {
		struct rxrpc_skb_priv *sp = rxrpc_skb(skb);

		cid  = sp->hdr.cid;
		call = sp->hdr.callNumber;
		seq  = sp->hdr.seq;
	}

	if (rxrpc_set_conn_aborted(conn, abort_code, err,
				   RXRPC_CALL_LOCALLY_ABORTED)) {
		trace_rxrpc_abort(0, why, cid, call, seq, abort_code, err);
		rxrpc_poke_conn(conn, rxrpc_conn_get_poke_abort);
	}
	return -EPROTO;
}

/*
 * Mark a connection as being remotely aborted.
 */
static void rxrpc_input_conn_abort(struct rxrpc_connection *conn,
				   struct sk_buff *skb)
{
	trace_rxrpc_rx_conn_abort(conn, skb);
	rxrpc_set_conn_aborted(conn, skb->priority, -ECONNABORTED,
			       RXRPC_CALL_REMOTELY_ABORTED);
}

/*
 * Retransmit terminal ACK or ABORT of the previous call.
 */
void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
				struct sk_buff *skb,
				unsigned int channel)
{
	struct rxrpc_skb_priv *sp = skb ? rxrpc_skb(skb) : NULL;
	struct rxrpc_channel *chan;
	struct msghdr msg;
	struct kvec iov[3];
	struct {
		struct rxrpc_wire_header whdr;
		union {
			__be32 abort_code;
			struct rxrpc_ackpacket ack;
		};
	} __attribute__((packed)) pkt;
	struct rxrpc_acktrailer trailer;
	size_t len;
	int ret, ioc;
	u32 serial, max_mtu, if_mtu, call_id, padding;

	_enter("%d", conn->debug_id);

	if (sp && sp->hdr.type == RXRPC_PACKET_TYPE_ACK) {
		if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
				  &pkt.ack, sizeof(pkt.ack)) < 0)
			return;
		if (pkt.ack.reason == RXRPC_ACK_PING_RESPONSE)
			return;
	}

	chan = &conn->channels[channel];

	/* If the last call got moved on whilst we were waiting to run, just
	 * ignore this packet.
	 */

Annotation

Implementation Notes