blob: fde3a6afe4beaff5399ae6e711ebd0f76cf4514a [file] [log] [blame]
Thomas Gleixner2522fe42019-05-28 09:57:20 -07001// SPDX-License-Identifier: GPL-2.0-only
David Teiglande7fd4172006-01-18 09:30:29 +00002/******************************************************************************
3*******************************************************************************
4**
5** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
Fabio M. Di Nittoe7847d32008-01-30 10:56:42 -06006** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
David Teiglande7fd4172006-01-18 09:30:29 +00007**
David Teiglande7fd4172006-01-18 09:30:29 +00008**
9*******************************************************************************
10******************************************************************************/
11
12/*
13 * midcomms.c
14 *
15 * This is the appallingly named "mid-level" comms layer.
16 *
17 * Its purpose is to take packets from the "real" comms layer,
18 * split them up into packets and pass them to the interested
19 * part of the locking mechanism.
20 *
21 * It also takes messages from the locking layer, formats them
22 * into packets and sends them to the comms layer.
23 */
24
Alexander Aring4798cbb2020-09-24 10:31:26 -040025#include <asm/unaligned.h>
26
David Teiglande7fd4172006-01-18 09:30:29 +000027#include "dlm_internal.h"
28#include "lowcomms.h"
29#include "config.h"
David Teiglande7fd4172006-01-18 09:30:29 +000030#include "lock.h"
31#include "midcomms.h"
32
David Teiglande7fd4172006-01-18 09:30:29 +000033/*
34 * Called from the low-level comms layer to process a buffer of
35 * commands.
David Teiglande7fd4172006-01-18 09:30:29 +000036 */
37
Alexander Aring4798cbb2020-09-24 10:31:26 -040038int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
David Teiglande7fd4172006-01-18 09:30:29 +000039{
Alexander Aring4798cbb2020-09-24 10:31:26 -040040 const unsigned char *ptr = buf;
41 const struct dlm_header *hd;
David Teiglande7fd4172006-01-18 09:30:29 +000042 uint16_t msglen;
Alexander Aring4798cbb2020-09-24 10:31:26 -040043 int ret = 0;
David Teiglande7fd4172006-01-18 09:30:29 +000044
Alexander Aring4798cbb2020-09-24 10:31:26 -040045 while (len >= sizeof(struct dlm_header)) {
46 hd = (struct dlm_header *)ptr;
David Teiglande7fd4172006-01-18 09:30:29 +000047
Alexander Aring4798cbb2020-09-24 10:31:26 -040048 /* no message should be more than this otherwise we
49 * cannot deliver this message to upper layers
50 */
51 msglen = get_unaligned_le16(&hd->h_length);
52 if (msglen > DEFAULT_BUFFER_SIZE) {
53 log_print("received invalid length header: %u, will abort message parsing",
54 msglen);
55 return -EBADMSG;
Al Viroeef7d732008-01-25 00:58:46 -050056 }
David Teiglande7fd4172006-01-18 09:30:29 +000057
Alexander Aring4798cbb2020-09-24 10:31:26 -040058 /* caller will take care that leftover
59 * will be parsed next call with more data
60 */
David Teiglande7fd4172006-01-18 09:30:29 +000061 if (msglen > len)
62 break;
63
Alexander Aring4798cbb2020-09-24 10:31:26 -040064 switch (hd->h_cmd) {
65 case DLM_MSG:
66 if (msglen < sizeof(struct dlm_message)) {
67 log_print("dlm msg too small: %u, will skip this message",
68 msglen);
69 goto skip;
70 }
David Teiglande7fd4172006-01-18 09:30:29 +000071
Alexander Aring4798cbb2020-09-24 10:31:26 -040072 break;
73 case DLM_RCOM:
74 if (msglen < sizeof(struct dlm_rcom)) {
75 log_print("dlm rcom msg too small: %u, will skip this message",
76 msglen);
77 goto skip;
78 }
79
80 break;
81 default:
82 log_print("unsupported h_cmd received: %u, will skip this message",
83 hd->h_cmd);
84 goto skip;
David Teiglande7fd4172006-01-18 09:30:29 +000085 }
86
Alexander Aring4798cbb2020-09-24 10:31:26 -040087 /* for aligned memory access, we just copy current message
88 * to begin of the buffer which contains already parsed buffer
89 * data and should provide align access for upper layers
90 * because the start address of the buffer has a aligned
91 * address. This memmove can be removed when the upperlayer
92 * is capable of unaligned memory access.
93 */
94 memmove(buf, ptr, msglen);
95 dlm_receive_buffer((union dlm_packet *)buf, nodeid);
David Teiglande7fd4172006-01-18 09:30:29 +000096
Alexander Aring4798cbb2020-09-24 10:31:26 -040097skip:
David Teiglande7fd4172006-01-18 09:30:29 +000098 ret += msglen;
David Teiglande7fd4172006-01-18 09:30:29 +000099 len -= msglen;
Alexander Aring4798cbb2020-09-24 10:31:26 -0400100 ptr += msglen;
David Teiglande7fd4172006-01-18 09:30:29 +0000101 }
102
Alexander Aring4798cbb2020-09-24 10:31:26 -0400103 return ret;
David Teiglande7fd4172006-01-18 09:30:29 +0000104}
105