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

Commit ace45bec authored by David Howells's avatar David Howells
Browse files

rxrpc: Fix firewall route keepalive



Fix the firewall route keepalive part of AF_RXRPC which is currently
function incorrectly by replying to VERSION REPLY packets from the server
with VERSION REQUEST packets.

Instead, send VERSION REPLY packets to the peers of service connections to
act as keep-alives 20s after the latest packet was transmitted to that
peer.

Also, just discard VERSION REPLY packets rather than replying to them.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent c0b6edef
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -762,6 +762,7 @@ static __poll_t rxrpc_poll(struct file *file, struct socket *sock,
static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
			int kern)
			int kern)
{
{
	struct rxrpc_net *rxnet;
	struct rxrpc_sock *rx;
	struct rxrpc_sock *rx;
	struct sock *sk;
	struct sock *sk;


@@ -801,6 +802,9 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
	rwlock_init(&rx->call_lock);
	rwlock_init(&rx->call_lock);
	memset(&rx->srx, 0, sizeof(rx->srx));
	memset(&rx->srx, 0, sizeof(rx->srx));


	rxnet = rxrpc_net(sock_net(&rx->sk));
	timer_reduce(&rxnet->peer_keepalive_timer, jiffies + 1);

	_leave(" = 0 [%p]", rx);
	_leave(" = 0 [%p]", rx);
	return 0;
	return 0;
}
}
+13 −1
Original line number Original line Diff line number Diff line
@@ -97,8 +97,16 @@ struct rxrpc_net {
	struct list_head	local_endpoints;
	struct list_head	local_endpoints;
	struct mutex		local_mutex;	/* Lock for ->local_endpoints */
	struct mutex		local_mutex;	/* Lock for ->local_endpoints */


	spinlock_t		peer_hash_lock;	/* Lock for ->peer_hash */
	DECLARE_HASHTABLE	(peer_hash, 10);
	DECLARE_HASHTABLE	(peer_hash, 10);
	spinlock_t		peer_hash_lock;	/* Lock for ->peer_hash */

#define RXRPC_KEEPALIVE_TIME 20 /* NAT keepalive time in seconds */
	u8			peer_keepalive_cursor;
	ktime_t			peer_keepalive_base;
	struct hlist_head	peer_keepalive[RXRPC_KEEPALIVE_TIME + 1];
	struct hlist_head	peer_keepalive_new;
	struct timer_list	peer_keepalive_timer;
	struct work_struct	peer_keepalive_work;
};
};


/*
/*
@@ -285,6 +293,8 @@ struct rxrpc_peer {
	struct hlist_head	error_targets;	/* targets for net error distribution */
	struct hlist_head	error_targets;	/* targets for net error distribution */
	struct work_struct	error_distributor;
	struct work_struct	error_distributor;
	struct rb_root		service_conns;	/* Service connections */
	struct rb_root		service_conns;	/* Service connections */
	struct hlist_node	keepalive_link;	/* Link in net->peer_keepalive[] */
	time64_t		last_tx_at;	/* Last time packet sent here */
	seqlock_t		service_conn_lock;
	seqlock_t		service_conn_lock;
	spinlock_t		lock;		/* access lock */
	spinlock_t		lock;		/* access lock */
	unsigned int		if_mtu;		/* interface MTU for this peer */
	unsigned int		if_mtu;		/* interface MTU for this peer */
@@ -1026,6 +1036,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *, bool, rxrpc_serial_t *);
int rxrpc_send_abort_packet(struct rxrpc_call *);
int rxrpc_send_abort_packet(struct rxrpc_call *);
int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool);
int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool);
void rxrpc_reject_packets(struct rxrpc_local *);
void rxrpc_reject_packets(struct rxrpc_local *);
void rxrpc_send_keepalive(struct rxrpc_peer *);


/*
/*
 * peer_event.c
 * peer_event.c
@@ -1034,6 +1045,7 @@ void rxrpc_error_report(struct sock *);
void rxrpc_peer_error_distributor(struct work_struct *);
void rxrpc_peer_error_distributor(struct work_struct *);
void rxrpc_peer_add_rtt(struct rxrpc_call *, enum rxrpc_rtt_rx_trace,
void rxrpc_peer_add_rtt(struct rxrpc_call *, enum rxrpc_rtt_rx_trace,
			rxrpc_serial_t, rxrpc_serial_t, ktime_t, ktime_t);
			rxrpc_serial_t, rxrpc_serial_t, ktime_t, ktime_t);
void rxrpc_peer_keepalive_worker(struct work_struct *);


/*
/*
 * peer_object.c
 * peer_object.c
+3 −0
Original line number Original line Diff line number Diff line
@@ -136,6 +136,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
	}
	}


	kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len);
	kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len);
	conn->params.peer->last_tx_at = ktime_get_real();
	_leave("");
	_leave("");
	return;
	return;
}
}
@@ -239,6 +240,8 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
		return -EAGAIN;
		return -EAGAIN;
	}
	}


	conn->params.peer->last_tx_at = ktime_get_real();

	_leave(" = 0");
	_leave(" = 0");
	return 0;
	return 0;
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -1183,6 +1183,8 @@ void rxrpc_data_ready(struct sock *udp_sk)


	switch (sp->hdr.type) {
	switch (sp->hdr.type) {
	case RXRPC_PACKET_TYPE_VERSION:
	case RXRPC_PACKET_TYPE_VERSION:
		if (!(sp->hdr.flags & RXRPC_CLIENT_INITIATED))
			goto discard;
		rxrpc_post_packet_to_local(local, skb);
		rxrpc_post_packet_to_local(local, skb);
		goto out;
		goto out;


+20 −1
Original line number Original line Diff line number Diff line
@@ -32,13 +32,22 @@ static void rxrpc_service_conn_reap_timeout(struct timer_list *timer)
		rxrpc_queue_work(&rxnet->service_conn_reaper);
		rxrpc_queue_work(&rxnet->service_conn_reaper);
}
}


static void rxrpc_peer_keepalive_timeout(struct timer_list *timer)
{
	struct rxrpc_net *rxnet =
		container_of(timer, struct rxrpc_net, peer_keepalive_timer);

	if (rxnet->live)
		rxrpc_queue_work(&rxnet->peer_keepalive_work);
}

/*
/*
 * Initialise a per-network namespace record.
 * Initialise a per-network namespace record.
 */
 */
static __net_init int rxrpc_init_net(struct net *net)
static __net_init int rxrpc_init_net(struct net *net)
{
{
	struct rxrpc_net *rxnet = rxrpc_net(net);
	struct rxrpc_net *rxnet = rxrpc_net(net);
	int ret;
	int ret, i;


	rxnet->live = true;
	rxnet->live = true;
	get_random_bytes(&rxnet->epoch, sizeof(rxnet->epoch));
	get_random_bytes(&rxnet->epoch, sizeof(rxnet->epoch));
@@ -70,8 +79,16 @@ static __net_init int rxrpc_init_net(struct net *net)


	INIT_LIST_HEAD(&rxnet->local_endpoints);
	INIT_LIST_HEAD(&rxnet->local_endpoints);
	mutex_init(&rxnet->local_mutex);
	mutex_init(&rxnet->local_mutex);

	hash_init(rxnet->peer_hash);
	hash_init(rxnet->peer_hash);
	spin_lock_init(&rxnet->peer_hash_lock);
	spin_lock_init(&rxnet->peer_hash_lock);
	for (i = 0; i < ARRAY_SIZE(rxnet->peer_keepalive); i++)
		INIT_HLIST_HEAD(&rxnet->peer_keepalive[i]);
	INIT_HLIST_HEAD(&rxnet->peer_keepalive_new);
	timer_setup(&rxnet->peer_keepalive_timer,
		    rxrpc_peer_keepalive_timeout, 0);
	INIT_WORK(&rxnet->peer_keepalive_work, rxrpc_peer_keepalive_worker);
	rxnet->peer_keepalive_base = ktime_add(ktime_get_real(), NSEC_PER_SEC);


	ret = -ENOMEM;
	ret = -ENOMEM;
	rxnet->proc_net = proc_net_mkdir(net, "rxrpc", net->proc_net);
	rxnet->proc_net = proc_net_mkdir(net, "rxrpc", net->proc_net);
@@ -95,6 +112,8 @@ static __net_exit void rxrpc_exit_net(struct net *net)
	struct rxrpc_net *rxnet = rxrpc_net(net);
	struct rxrpc_net *rxnet = rxrpc_net(net);


	rxnet->live = false;
	rxnet->live = false;
	del_timer_sync(&rxnet->peer_keepalive_timer);
	cancel_work_sync(&rxnet->peer_keepalive_work);
	rxrpc_destroy_all_calls(rxnet);
	rxrpc_destroy_all_calls(rxnet);
	rxrpc_destroy_all_connections(rxnet);
	rxrpc_destroy_all_connections(rxnet);
	rxrpc_destroy_all_locals(rxnet);
	rxrpc_destroy_all_locals(rxnet);
Loading