1 // SPDX-License-Identifier: GPL-2.0-only 2 /****************************************************************************** 3 ******************************************************************************* 4 ** 5 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 6 ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. 7 ** 8 ** 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 25 #include "dlm_internal.h" 26 #include "lowcomms.h" 27 #include "config.h" 28 #include "lock.h" 29 #include "midcomms.h" 30 31 /* 32 * Called from the low-level comms layer to process a buffer of 33 * commands. 34 */ 35 36 int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len) 37 { 38 const unsigned char *ptr = buf; 39 const struct dlm_header *hd; 40 uint16_t msglen; 41 int ret = 0; 42 43 while (len >= sizeof(struct dlm_header)) { 44 hd = (struct dlm_header *)ptr; 45 46 /* no message should be more than DEFAULT_BUFFER_SIZE or 47 * less than dlm_header size. 48 * 49 * Some messages does not have a 8 byte length boundary yet 50 * which can occur in a unaligned memory access of some dlm 51 * messages. However this problem need to be fixed at the 52 * sending side, for now it seems nobody run into architecture 53 * related issues yet but it slows down some processing. 54 * Fixing this issue should be scheduled in future by doing 55 * the next major version bump. 56 */ 57 msglen = le16_to_cpu(hd->h_length); 58 if (msglen > DEFAULT_BUFFER_SIZE || 59 msglen < sizeof(struct dlm_header)) { 60 log_print("received invalid length header: %u from node %d, will abort message parsing", 61 msglen, nodeid); 62 return -EBADMSG; 63 } 64 65 /* caller will take care that leftover 66 * will be parsed next call with more data 67 */ 68 if (msglen > len) 69 break; 70 71 switch (hd->h_cmd) { 72 case DLM_MSG: 73 if (msglen < sizeof(struct dlm_message)) { 74 log_print("dlm msg too small: %u, will skip this message", 75 msglen); 76 goto skip; 77 } 78 79 break; 80 case DLM_RCOM: 81 if (msglen < sizeof(struct dlm_rcom)) { 82 log_print("dlm rcom msg too small: %u, will skip this message", 83 msglen); 84 goto skip; 85 } 86 87 break; 88 default: 89 log_print("unsupported h_cmd received: %u, will skip this message", 90 hd->h_cmd); 91 goto skip; 92 } 93 94 dlm_receive_buffer((union dlm_packet *)ptr, nodeid); 95 96 skip: 97 ret += msglen; 98 len -= msglen; 99 ptr += msglen; 100 } 101 102 return ret; 103 } 104 105