^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * midcomms.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * This is the appallingly named "mid-level" comms layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Its purpose is to take packets from the "real" comms layer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * split them up into packets and pass them to the interested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * part of the locking mechanism.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * It also takes messages from the locking layer, formats them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * into packets and sends them to the comms layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "dlm_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "lowcomms.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "lock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "midcomms.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Called from the low-level comms layer to process a buffer of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) const unsigned char *ptr = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) const struct dlm_header *hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) uint16_t msglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) while (len >= sizeof(struct dlm_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) hd = (struct dlm_header *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* no message should be more than this otherwise we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * cannot deliver this message to upper layers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) msglen = get_unaligned_le16(&hd->h_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (msglen > DEFAULT_BUFFER_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) msglen < sizeof(struct dlm_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) log_print("received invalid length header: %u from node %d, will abort message parsing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) msglen, nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* caller will take care that leftover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * will be parsed next call with more data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (msglen > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) switch (hd->h_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case DLM_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (msglen < sizeof(struct dlm_message)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) log_print("dlm msg too small: %u, will skip this message",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) msglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) goto skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) case DLM_RCOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (msglen < sizeof(struct dlm_rcom)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) log_print("dlm rcom msg too small: %u, will skip this message",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) msglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) goto skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) log_print("unsupported h_cmd received: %u, will skip this message",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) hd->h_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* for aligned memory access, we just copy current message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * to begin of the buffer which contains already parsed buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * data and should provide align access for upper layers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * because the start address of the buffer has a aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * address. This memmove can be removed when the upperlayer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * is capable of unaligned memory access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) memmove(buf, ptr, msglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dlm_receive_buffer((union dlm_packet *)buf, nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) skip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret += msglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) len -= msglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ptr += msglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)