diff --git a/mesh/model.c b/mesh/model.c
index 7bbc9cca7..ed2a75215 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -862,9 +862,9 @@ static void send_msg_rcvd(struct mesh_node *node, uint8_t ele_idx,
 }
 
 bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
-			uint32_t seq, uint32_t iv_index,
-			uint16_t net_idx, uint16_t src, uint16_t dst,
-			uint8_t key_aid, const uint8_t *data, uint16_t size)
+			uint32_t iv_index, uint16_t net_idx, uint16_t src,
+			uint16_t dst, uint8_t key_aid, const uint8_t *data,
+								uint16_t size)
 {
 	uint8_t *clear_text;
 	struct mod_forward forward = {
@@ -877,7 +877,7 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
 	struct mesh_net *net = node_get_net(node);
 	uint8_t num_ele;
 	int decrypt_idx, i, ele_idx;
-	uint16_t addr, crpl;
+	uint16_t addr;
 	struct mesh_virtual *decrypt_virt = NULL;
 	bool result = false;
 	bool is_subscription;
@@ -892,12 +892,6 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
 		/* Unicast and not addressed to us */
 		return false;
 
-	/* Don't process if already in RPL */
-	crpl = node_get_crpl(node);
-
-	if (net_msg_check_replay_cache(net, src, crpl, seq, iv_index))
-		return false;
-
 	clear_text = l_malloc(size);
 	forward.data = clear_text;
 
@@ -988,10 +982,6 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
 			break;
 	}
 
-	/* If message has been handled by us, add to RPL */
-	if (result)
-		net_msg_add_replay_cache(net, src, seq, iv_index);
-
 done:
 	l_free(clear_text);
 
diff --git a/mesh/model.h b/mesh/model.h
index fe0648d04..2eec761a0 100644
--- a/mesh/model.h
+++ b/mesh/model.h
@@ -117,9 +117,9 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t dst,
 int mesh_model_publish(struct mesh_node *node, uint32_t id, uint16_t src,
 			bool segmented, uint16_t len, const void *data);
 bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
-			uint32_t seq, uint32_t iv_index, uint16_t net_idx,
-			uint16_t src, uint16_t dst, uint8_t key_aid,
-			const uint8_t *data, uint16_t size);
+			uint32_t iv_index, uint16_t net_idx, uint16_t src,
+			uint16_t dst, uint8_t key_aid, const uint8_t *data,
+								uint16_t size);
 void mesh_model_app_key_delete(struct mesh_node *node, uint16_t ele_idx,
 				struct l_queue *models, uint16_t app_idx);
 uint16_t mesh_model_opcode_set(uint32_t opcode, uint8_t *buf);
diff --git a/mesh/net.c b/mesh/net.c
index 83647d6ad..6c7311732 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -1621,6 +1621,91 @@ static void outseg_to(struct l_timeout *seg_timeout, void *user_data)
 					sar->seqZero, sar->last_nak);
 }
 
+static bool match_replay_cache(const void *a, const void *b)
+{
+	const struct mesh_rpl *rpe = a;
+	uint16_t src = L_PTR_TO_UINT(b);
+
+	return src == rpe->src;
+}
+
+static bool clean_old_iv_index(void *a, void *b)
+{
+	struct mesh_rpl *rpe = a;
+	uint32_t iv_index = L_PTR_TO_UINT(b);
+
+	if (iv_index < 2)
+		return false;
+
+	if (rpe->iv_index < iv_index - 1) {
+		l_free(rpe);
+		return true;
+	}
+
+	return false;
+}
+
+static bool msg_check_replay_cache(struct mesh_net *net, uint16_t src,
+				uint16_t crpl, uint32_t seq, uint32_t iv_index)
+{
+	struct mesh_rpl *rpe;
+
+	/* If anything missing reject this message by returning true */
+	if (!net || !net->node)
+		return true;
+
+	rpe = l_queue_find(net->replay_cache, match_replay_cache,
+						L_UINT_TO_PTR(src));
+
+	if (rpe) {
+		if (iv_index > rpe->iv_index)
+			return false;
+
+		/* Return true if (iv_index | seq) too low */
+		if (iv_index < rpe->iv_index || seq <= rpe->seq) {
+			l_debug("Ignoring replayed packet");
+			return true;
+		}
+	} else if (l_queue_length(net->replay_cache) >= crpl) {
+		/* SRC not in Replay Cache... see if there is space for it */
+
+		int ret = l_queue_foreach_remove(net->replay_cache,
+				clean_old_iv_index, L_UINT_TO_PTR(iv_index));
+
+		/* Return true if no space could be freed */
+		if (!ret) {
+			l_debug("Replay cache full");
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static void msg_add_replay_cache(struct mesh_net *net, uint16_t src,
+						uint32_t seq, uint32_t iv_index)
+{
+	struct mesh_rpl *rpe;
+
+	if (!net || !net->replay_cache)
+		return;
+
+	rpe = l_queue_remove_if(net->replay_cache, match_replay_cache,
+						L_UINT_TO_PTR(src));
+
+	if (!rpe) {
+		rpe = l_new(struct mesh_rpl, 1);
+		rpe->src = src;
+	}
+
+	rpe->seq = seq;
+	rpe->iv_index = iv_index;
+	rpl_put_entry(net->node, src, iv_index, seq);
+
+	/* Optimize so that most recent conversations stay earliest in cache */
+	l_queue_push_head(net->replay_cache, rpe);
+}
+
 static bool msg_rxed(struct mesh_net *net, bool frnd, uint32_t iv_index,
 					uint8_t ttl, uint32_t seq,
 					uint16_t net_idx,
@@ -1630,6 +1715,7 @@ static bool msg_rxed(struct mesh_net *net, bool frnd, uint32_t iv_index,
 					const uint8_t *data, uint16_t size)
 {
 	uint32_t seqAuth = seq_auth(seq, seqZero);
+	uint16_t crpl;
 
 	/* Sanity check seqAuth */
 	if (seqAuth > seq)
@@ -1671,8 +1757,19 @@ not_for_friend:
 	if (dst == PROXIES_ADDRESS && !net->proxy_enable)
 		return false;
 
-	return mesh_model_rx(net->node, szmic, seqAuth, seq, iv_index, net_idx,
-						src, dst, key_aid, data, size);
+	/* Don't process if already in RPL */
+	crpl = node_get_crpl(net->node);
+
+	if (msg_check_replay_cache(net, src, crpl, seq, iv_index))
+		return false;
+
+	if (!mesh_model_rx(net->node, szmic, seqAuth, iv_index, net_idx, src,
+						dst, key_aid, data, size))
+		return false;
+
+	/* If message has been handled by us, add to RPL */
+	msg_add_replay_cache(net, src, seq, iv_index);
+	return true;
 }
 
 static uint16_t key_id_to_net_idx(struct mesh_net *net, uint32_t key_id)
@@ -3448,89 +3545,6 @@ uint32_t mesh_net_get_instant(struct mesh_net *net)
 	return net->instant;
 }
 
-static bool match_replay_cache(const void *a, const void *b)
-{
-	const struct mesh_rpl *rpe = a;
-	uint16_t src = L_PTR_TO_UINT(b);
-
-	return src == rpe->src;
-}
-
-static bool clean_old_iv_index(void *a, void *b)
-{
-	struct mesh_rpl *rpe = a;
-	uint32_t iv_index = L_PTR_TO_UINT(b);
-
-	if (iv_index < 2)
-		return false;
-
-	if (rpe->iv_index < iv_index - 1) {
-		l_free(rpe);
-		return true;
-	}
-
-	return false;
-}
-
-bool net_msg_check_replay_cache(struct mesh_net *net, uint16_t src,
-				uint16_t crpl, uint32_t seq, uint32_t iv_index)
-{
-	struct mesh_rpl *rpe;
-
-	/* If anything missing reject this message by returning true */
-	if (!net || !net->node)
-		return true;
-
-	rpe = l_queue_find(net->replay_cache, match_replay_cache,
-						L_UINT_TO_PTR(src));
-
-	if (rpe) {
-		if (iv_index > rpe->iv_index)
-			return false;
-
-		/* Return true if (iv_index | seq) too low */
-		if (iv_index < rpe->iv_index || seq <= rpe->seq) {
-			l_debug("Ignoring replayed packet");
-			return true;
-		}
-	} else if (l_queue_length(net->replay_cache) >= crpl) {
-		/* SRC not in Replay Cache... see if there is space for it */
-
-		int ret = l_queue_foreach_remove(net->replay_cache,
-				clean_old_iv_index, L_UINT_TO_PTR(iv_index));
-
-		/* Return true if no space could be freed */
-		if (!ret)
-			return true;
-	}
-
-	return false;
-}
-
-void net_msg_add_replay_cache(struct mesh_net *net, uint16_t src, uint32_t seq,
-							uint32_t iv_index)
-{
-	struct mesh_rpl *rpe;
-
-	if (!net || !net->replay_cache)
-		return;
-
-	rpe = l_queue_remove_if(net->replay_cache, match_replay_cache,
-						L_UINT_TO_PTR(src));
-
-	if (!rpe) {
-		rpe = l_new(struct mesh_rpl, 1);
-		rpe->src = src;
-	}
-
-	rpe->seq = seq;
-	rpe->iv_index = iv_index;
-	rpl_put_entry(net->node, src, iv_index, seq);
-
-	/* Optimize so that most recent conversations stay earliest in cache */
-	l_queue_push_head(net->replay_cache, rpe);
-}
-
 static void hb_sub_timeout_func(struct l_timeout *timeout, void *user_data)
 {
 	struct mesh_net *net = user_data;
diff --git a/mesh/net.h b/mesh/net.h
index 725054ce6..7bec6d0fc 100644
--- a/mesh/net.h
+++ b/mesh/net.h
@@ -354,8 +354,4 @@ void mesh_net_set_prov(struct mesh_net *net, struct mesh_prov *prov);
 uint32_t mesh_net_get_instant(struct mesh_net *net);
 struct l_queue *mesh_net_get_friends(struct mesh_net *net);
 struct l_queue *mesh_net_get_negotiations(struct mesh_net *net);
-bool net_msg_check_replay_cache(struct mesh_net *net, uint16_t src,
-				uint16_t crpl, uint32_t seq, uint32_t iv_index);
-void net_msg_add_replay_cache(struct mesh_net *net, uint16_t src, uint32_t seq,
-							uint32_t iv_index);
 bool mesh_net_load_rpl(struct mesh_net *net);
