@ -129,6 +129,8 @@ int DecodeIEEE8021ah(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
# ifdef UNITTESTS
# ifdef UNITTESTS
# include "util-unittest-helper.h"
# include "util-unittest-helper.h"
# include "packet.h"
# include "packet.h"
# include "flow-hash.h"
# include "tmqh-packetpool.h"
/** \todo Must GRE+VLAN and Multi-Vlan packets to
/** \todo Must GRE+VLAN and Multi-Vlan packets to
* create more tests
* create more tests
@ -222,6 +224,80 @@ static int DecodeVLANtest03 (void)
FlowShutdown ( ) ;
FlowShutdown ( ) ;
PASS ;
PASS ;
}
}
/**
* \ test DecodeVLANtest04 test that the packet pool recycle path clears
* every VLAN id slot a decoder can use .
*
* DecodeVLAN ( ) fills vlan_id [ ] up to VLAN_MAX_LAYERS , so a triple tagged
* ( QinQinQ ) frame sets all of them . The slots are handed to the next
* occupant of the pool slot unless PacketReinit ( ) clears them all : the
* flow hash key ( FlowHashIp4Fill ( ) ) and the flow comparison
* ( CmpVlanIds ( ) ) fold in every slot regardless of vlan_idx , so a single
* stale slot makes the packets of one and the same stream hash into two
* different Flow objects , which splits reassembly over those two flows .
*
* \ retval 1 on success
* \ retval 0 on failure
*/
static int DecodeVLANtest04 ( void )
{
/* QinQinQ: 3 vlan header layers, ids 32, 257 and 3843. */
uint8_t raw_qinqinq [ ] = { 0x00 , 0x20 , 0x81 , 0x00 , 0x01 , 0x01 , 0x81 , 0x00 , 0x0f , 0x03 , 0x08 ,
0x00 , 0x45 , 0x00 , 0x00 , 0x34 , 0x3b , 0x36 , 0x40 , 0x00 , 0x40 , 0x06 , 0xb7 , 0xc9 , 0x83 , 0x97 ,
0x20 , 0x81 , 0x83 , 0x97 , 0x20 , 0x15 , 0x04 , 0x8a , 0x17 , 0x70 , 0x4e , 0x14 , 0xdf , 0x55 , 0x4d ,
0x3d , 0x5a , 0x61 , 0x80 , 0x10 , 0x6b , 0x50 , 0x3c , 0x4c , 0x00 , 0x00 , 0x01 , 0x01 , 0x08 , 0x0a ,
0x00 , 0x04 , 0xf0 , 0xc8 , 0x01 , 0x99 , 0xa3 , 0xf3 } ;
/* QinQ: 2 vlan header layers, ids 32 and 257, same inner packet. */
uint8_t raw_qinq [ ] = { 0x00 , 0x20 , 0x81 , 0x00 , 0x01 , 0x01 , 0x08 , 0x00 , 0x45 , 0x00 , 0x00 , 0x34 ,
0x3b , 0x36 , 0x40 , 0x00 , 0x40 , 0x06 , 0xb7 , 0xc9 , 0x83 , 0x97 , 0x20 , 0x81 , 0x83 , 0x97 , 0x20 ,
0x15 , 0x04 , 0x8a , 0x17 , 0x70 , 0x4e , 0x14 , 0xdf , 0x55 , 0x4d , 0x3d , 0x5a , 0x61 , 0x80 , 0x10 ,
0x6b , 0x50 , 0x3c , 0x4c , 0x00 , 0x00 , 0x01 , 0x01 , 0x08 , 0x0a , 0x00 , 0x04 , 0xf0 , 0xc8 , 0x01 ,
0x99 , 0xa3 , 0xf3 } ;
Packet * p = PacketPoolGetPacket ( ) ;
FAIL_IF_NULL ( p ) ;
ThreadVars tv ;
DecodeThreadVars dtv ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & dtv , 0 , sizeof ( DecodeThreadVars ) ) ;
FAIL_IF_NOT ( TM_ECODE_OK = = DecodeVLAN ( & tv , & dtv , p , raw_qinqinq , sizeof ( raw_qinqinq ) ) ) ;
FAIL_IF ( p - > vlan_idx ! = VLAN_MAX_LAYERS ) ;
for ( unsigned i = 0 ; i < VLAN_MAX_LAYERS ; i + + ) {
FAIL_IF ( p - > vlan_id [ i ] = = 0 ) ;
}
/* Hand the packet back to the pool it came from and take a packet out
* again : the very same slot is recycled . */
PacketPoolReturnPacket ( p ) ;
Packet * recycled = PacketPoolGetPacket ( ) ;
FAIL_IF_NULL ( recycled ) ;
FAIL_IF ( recycled ! = p ) ;
FAIL_IF ( recycled - > vlan_idx ! = 0 ) ;
for ( unsigned i = 0 ; i < VLAN_MAX_LAYERS ; i + + ) {
FAIL_IF ( recycled - > vlan_id [ i ] ! = 0 ) ;
}
/* And now the part that decides behaviour: decoding a double tagged
* frame into the recycled packet must key exactly like decoding it
* into a packet that never saw the QinQinQ one . */
FAIL_IF_NOT ( TM_ECODE_OK = = DecodeVLAN ( & tv , & dtv , recycled , raw_qinq , sizeof ( raw_qinq ) ) ) ;
FAIL_IF ( recycled - > vlan_idx ! = 2 ) ;
FAIL_IF ( recycled - > vlan_id [ VLAN_MAX_LAYER_IDX ] ! = 0 ) ;
const uint32_t recycled_hash = FlowGetIpPairProtoHash ( recycled ) ;
Packet * fresh = PacketGetFromAlloc ( ) ;
FAIL_IF_NULL ( fresh ) ;
FAIL_IF_NOT ( TM_ECODE_OK = = DecodeVLAN ( & tv , & dtv , fresh , raw_qinq , sizeof ( raw_qinq ) ) ) ;
const uint32_t fresh_hash = FlowGetIpPairProtoHash ( fresh ) ;
FAIL_IF ( recycled_hash ! = fresh_hash ) ;
PacketFree ( fresh ) ;
PacketPoolReturnPacket ( recycled ) ;
PASS ;
}
# endif /* UNITTESTS */
# endif /* UNITTESTS */
void DecodeVLANRegisterTests ( void )
void DecodeVLANRegisterTests ( void )
@ -230,6 +306,7 @@ void DecodeVLANRegisterTests(void)
UtRegisterTest ( " DecodeVLANtest01 " , DecodeVLANtest01 ) ;
UtRegisterTest ( " DecodeVLANtest01 " , DecodeVLANtest01 ) ;
UtRegisterTest ( " DecodeVLANtest02 " , DecodeVLANtest02 ) ;
UtRegisterTest ( " DecodeVLANtest02 " , DecodeVLANtest02 ) ;
UtRegisterTest ( " DecodeVLANtest03 " , DecodeVLANtest03 ) ;
UtRegisterTest ( " DecodeVLANtest03 " , DecodeVLANtest03 ) ;
UtRegisterTest ( " DecodeVLANtest04 " , DecodeVLANtest04 ) ;
# endif /* UNITTESTS */
# endif /* UNITTESTS */
}
}