123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // SPDX-License-Identifier: GPL-2.0-only
- /******************************************************************************
- *******************************************************************************
- **
- ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
- ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
- **
- **
- *******************************************************************************
- ******************************************************************************/
- /*
- * 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 <asm/unaligned.h>
- #include "dlm_internal.h"
- #include "lowcomms.h"
- #include "config.h"
- #include "lock.h"
- #include "midcomms.h"
- /*
- * Called from the low-level comms layer to process a buffer of
- * commands.
- */
- int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
- {
- const unsigned char *ptr = buf;
- const struct dlm_header *hd;
- uint16_t msglen;
- int ret = 0;
- while (len >= sizeof(struct dlm_header)) {
- hd = (struct dlm_header *)ptr;
- /* no message should be more than this otherwise we
- * cannot deliver this message to upper layers
- */
- msglen = get_unaligned_le16(&hd->h_length);
- 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);
- return -EBADMSG;
- }
- /* caller will take care that leftover
- * will be parsed next call with more data
- */
- if (msglen > len)
- break;
- 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;
- }
- 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;
- }
- break;
- default:
- log_print("unsupported h_cmd received: %u, will skip this message",
- hd->h_cmd);
- goto skip;
- }
- /* for aligned memory access, we just copy current message
- * to begin of the buffer which contains already parsed buffer
- * data and should provide align access for upper layers
- * because the start address of the buffer has a aligned
- * address. This memmove can be removed when the upperlayer
- * is capable of unaligned memory access.
- */
- memmove(buf, ptr, msglen);
- dlm_receive_buffer((union dlm_packet *)buf, nodeid);
- skip:
- ret += msglen;
- len -= msglen;
- ptr += msglen;
- }
- return ret;
- }
|