2019-05-28 16:57:20 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2006-01-18 09:30:29 +00:00
|
|
|
/******************************************************************************
|
|
|
|
*******************************************************************************
|
|
|
|
**
|
|
|
|
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
2008-01-30 16:56:42 +00:00
|
|
|
** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
2006-01-18 09:30:29 +00:00
|
|
|
**
|
|
|
|
**
|
|
|
|
*******************************************************************************
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* midcomms.c
|
|
|
|
*
|
|
|
|
* This is the appallingly named "mid-level" comms layer.
|
|
|
|
*
|
|
|
|
* Its purpose is to take packets from the "real" comms layer,
|
|
|
|
* split them up into packets and pass them to the interested
|
|
|
|
* part of the locking mechanism.
|
|
|
|
*
|
|
|
|
* It also takes messages from the locking layer, formats them
|
|
|
|
* into packets and sends them to the comms layer.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "dlm_internal.h"
|
|
|
|
#include "lowcomms.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "lock.h"
|
|
|
|
#include "midcomms.h"
|
|
|
|
|
2021-05-21 19:08:41 +00:00
|
|
|
struct dlm_mhandle *dlm_midcomms_get_mhandle(int nodeid, int len,
|
|
|
|
gfp_t allocation, char **ppc)
|
|
|
|
{
|
2021-05-21 19:08:42 +00:00
|
|
|
return (struct dlm_mhandle *)dlm_lowcomms_new_msg(nodeid, len,
|
|
|
|
allocation, ppc,
|
|
|
|
NULL, NULL);
|
2021-05-21 19:08:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void dlm_midcomms_commit_mhandle(struct dlm_mhandle *mh)
|
|
|
|
{
|
2021-05-21 19:08:42 +00:00
|
|
|
dlm_lowcomms_commit_msg((struct dlm_msg *)mh);
|
|
|
|
dlm_lowcomms_put_msg((struct dlm_msg *)mh);
|
2021-05-21 19:08:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void dlm_midcomms_add_member(int nodeid) { }
|
|
|
|
|
|
|
|
void dlm_midcomms_remove_member(int nodeid) { }
|
|
|
|
|
|
|
|
int dlm_midcomms_start(void)
|
|
|
|
{
|
|
|
|
return dlm_lowcomms_start();
|
|
|
|
}
|
|
|
|
|
|
|
|
void dlm_midcomms_shutdown(void)
|
|
|
|
{
|
|
|
|
dlm_lowcomms_shutdown();
|
|
|
|
}
|
|
|
|
|
|
|
|
int dlm_midcomms_close(int nodeid)
|
|
|
|
{
|
|
|
|
return dlm_lowcomms_close(nodeid);
|
|
|
|
}
|
|
|
|
|
2006-01-18 09:30:29 +00:00
|
|
|
/*
|
|
|
|
* Called from the low-level comms layer to process a buffer of
|
|
|
|
* commands.
|
|
|
|
*/
|
|
|
|
|
2020-09-24 14:31:26 +00:00
|
|
|
int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
|
2006-01-18 09:30:29 +00:00
|
|
|
{
|
2020-09-24 14:31:26 +00:00
|
|
|
const unsigned char *ptr = buf;
|
|
|
|
const struct dlm_header *hd;
|
2006-01-18 09:30:29 +00:00
|
|
|
uint16_t msglen;
|
2020-09-24 14:31:26 +00:00
|
|
|
int ret = 0;
|
2006-01-18 09:30:29 +00:00
|
|
|
|
2020-09-24 14:31:26 +00:00
|
|
|
while (len >= sizeof(struct dlm_header)) {
|
|
|
|
hd = (struct dlm_header *)ptr;
|
|
|
|
|
2021-03-01 22:05:18 +00:00
|
|
|
/* no message should be more than DEFAULT_BUFFER_SIZE or
|
|
|
|
* less than dlm_header size.
|
|
|
|
*
|
|
|
|
* Some messages does not have a 8 byte length boundary yet
|
|
|
|
* which can occur in a unaligned memory access of some dlm
|
|
|
|
* messages. However this problem need to be fixed at the
|
|
|
|
* sending side, for now it seems nobody run into architecture
|
|
|
|
* related issues yet but it slows down some processing.
|
|
|
|
* Fixing this issue should be scheduled in future by doing
|
|
|
|
* the next major version bump.
|
2020-09-24 14:31:26 +00:00
|
|
|
*/
|
2021-03-01 22:05:18 +00:00
|
|
|
msglen = le16_to_cpu(hd->h_length);
|
2021-03-01 22:05:17 +00:00
|
|
|
if (msglen > DEFAULT_BUFFER_SIZE ||
|
|
|
|
msglen < sizeof(struct dlm_header)) {
|
|
|
|
log_print("received invalid length header: %u from node %d, will abort message parsing",
|
|
|
|
msglen, nodeid);
|
2020-09-24 14:31:26 +00:00
|
|
|
return -EBADMSG;
|
2006-01-18 09:30:29 +00:00
|
|
|
}
|
|
|
|
|
2020-09-24 14:31:26 +00:00
|
|
|
/* caller will take care that leftover
|
|
|
|
* will be parsed next call with more data
|
|
|
|
*/
|
2006-01-18 09:30:29 +00:00
|
|
|
if (msglen > len)
|
|
|
|
break;
|
|
|
|
|
2020-09-24 14:31:26 +00:00
|
|
|
switch (hd->h_cmd) {
|
|
|
|
case DLM_MSG:
|
|
|
|
if (msglen < sizeof(struct dlm_message)) {
|
|
|
|
log_print("dlm msg too small: %u, will skip this message",
|
|
|
|
msglen);
|
|
|
|
goto skip;
|
|
|
|
}
|
2006-01-18 09:30:29 +00:00
|
|
|
|
2020-09-24 14:31:26 +00:00
|
|
|
break;
|
|
|
|
case DLM_RCOM:
|
|
|
|
if (msglen < sizeof(struct dlm_rcom)) {
|
|
|
|
log_print("dlm rcom msg too small: %u, will skip this message",
|
|
|
|
msglen);
|
|
|
|
goto skip;
|
|
|
|
}
|
2006-01-18 09:30:29 +00:00
|
|
|
|
2020-09-24 14:31:26 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
log_print("unsupported h_cmd received: %u, will skip this message",
|
|
|
|
hd->h_cmd);
|
|
|
|
goto skip;
|
|
|
|
}
|
2006-01-18 09:30:29 +00:00
|
|
|
|
2021-03-01 22:05:18 +00:00
|
|
|
dlm_receive_buffer((union dlm_packet *)ptr, nodeid);
|
2020-09-24 14:31:26 +00:00
|
|
|
|
|
|
|
skip:
|
2006-01-18 09:30:29 +00:00
|
|
|
ret += msglen;
|
|
|
|
len -= msglen;
|
2020-09-24 14:31:26 +00:00
|
|
|
ptr += msglen;
|
2006-01-18 09:30:29 +00:00
|
|
|
}
|
|
|
|
|
2020-09-24 14:31:26 +00:00
|
|
|
return ret;
|
2006-01-18 09:30:29 +00:00
|
|
|
}
|