2019-05-28 09:57:20 -07: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 10:56:42 -06: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 .
*/
2020-09-24 10:31:26 -04:00
# include <asm/unaligned.h>
2006-01-18 09:30:29 +00:00
# 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 .
*/
2020-09-24 10:31:26 -04:00
int dlm_process_incoming_buffer ( int nodeid , unsigned char * buf , int len )
2006-01-18 09:30:29 +00:00
{
2020-09-24 10:31:26 -04: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 10:31:26 -04:00
int ret = 0 ;
2006-01-18 09:30:29 +00:00
2020-09-24 10:31:26 -04:00
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 ) {
log_print ( " received invalid length header: %u, will abort message parsing " ,
msglen ) ;
return - EBADMSG ;
2006-01-18 09:30:29 +00:00
}
2020-09-24 10:31:26 -04: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 10:31:26 -04: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 10:31:26 -04: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 10:31:26 -04: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
2020-09-24 10:31:26 -04:00
/* 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 :
2006-01-18 09:30:29 +00:00
ret + = msglen ;
len - = msglen ;
2020-09-24 10:31:26 -04:00
ptr + = msglen ;
2006-01-18 09:30:29 +00:00
}
2020-09-24 10:31:26 -04:00
return ret ;
2006-01-18 09:30:29 +00:00
}