3234 lines
112 KiB
C
3234 lines
112 KiB
C
/* ipmacsec_debug.c - MACsec Debug implementation */
|
|
|
|
/*
|
|
* Copyright (c) 2010 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute, modify, or otherwise make use
|
|
* of this software may be licensed only pursuant to the terms
|
|
* of an applicable Wind River license agreement.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01a,04Mar10,mry Created
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
/*
|
|
* Implements the MACsec debug functionality (mostly used for debugging and
|
|
* unit/dev testing, and is typically not part of a production system).
|
|
* NOTE that all code protected by #ifdef IPMACSEC_UNIT_TEST is non supported
|
|
* code and not guaranteed to work as advertised.
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_errno.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_os.h>
|
|
|
|
#include "ipmacsec_debug.h"
|
|
#include "ipmacsec_sysvar.h"
|
|
#include "ipmacsec_secy_mgmt.h"
|
|
#include "ipmacsec_h.h"
|
|
#include "ipmacsec.h"
|
|
#include "ipmacsec_netlink.h"
|
|
#include "ipmacsec_lmi.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
#include "ipmacsec_config.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
#ifdef IPMACSEC_UNIT_TEST
|
|
/* Sysvars used in Unit Testing profiles */
|
|
#define IPMACSEC_UT_SYSVAR_SCI "ipmacsec.ut.secy.sci"
|
|
#define IPMACSEC_UT_SYSVAR_RX_SCI_1 "ipmacsec.ut.secy.rx.sci.1"
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
#ifdef IPMACSEC_UNIT_TEST
|
|
|
|
/* Unit Test Keying material (Note that since this is only used for unit testing, keying material secrecy is not crucial )
|
|
* WARNING: DO NOT USE THE FOLLOWING KEYING MATERIAL AS PART OF A PRODUCTION SYSTEM. This will greatly diminish the security
|
|
* of the system.
|
|
*/
|
|
IP_STATIC Ip_u8 ipmacsec_ut_128b_keymaterial_1[16] =
|
|
{
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
|
};
|
|
|
|
IP_STATIC Ip_u8 ipmacsec_ut_128b_keymaterial_2[16] =
|
|
{
|
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
|
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
|
|
};
|
|
|
|
IP_STATIC Ip_u8 ipmacsec_ut_128b_keymaterial_3[16] =
|
|
{
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
|
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
|
|
};
|
|
|
|
IP_STATIC Ip_u8 ipmacsec_ut_128b_keymaterial_4[16] =
|
|
{
|
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
|
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
|
|
};
|
|
|
|
/* Unit Test SAK profiles */
|
|
IP_STATIC Ipmacsec_sak_profile ipmacsec_ut_sak_128b_key_1 =
|
|
{
|
|
0x0000000100008001ULL,
|
|
128/8,
|
|
ipmacsec_ut_128b_keymaterial_1
|
|
};
|
|
|
|
IP_STATIC Ipmacsec_sak_profile ipmacsec_ut_sak_128b_key_2 =
|
|
{
|
|
0x0000000100008002ULL,
|
|
128/8,
|
|
ipmacsec_ut_128b_keymaterial_2
|
|
};
|
|
|
|
IP_STATIC Ipmacsec_sak_profile ipmacsec_ut_sak_128b_key_3 =
|
|
{
|
|
0x0000000100008003ULL,
|
|
128/8,
|
|
ipmacsec_ut_128b_keymaterial_3
|
|
};
|
|
|
|
IP_STATIC Ipmacsec_sak_profile ipmacsec_ut_sak_128b_key_4 =
|
|
{
|
|
0x0000000100008004ULL,
|
|
128/8,
|
|
ipmacsec_ut_128b_keymaterial_4
|
|
};
|
|
|
|
/* Unit Test Profile #1: Use on Station A */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_1A =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_GCM_AES_128, /*cipher_suite_index*/
|
|
|
|
IP_TRUE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_STRICT, /*validateFrames*/
|
|
IP_FALSE, /*replayProtect*/
|
|
0, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_OFF /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
|
|
/* Unit Test Profile #1: Use on Station B */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_1B =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_GCM_AES_128, /*cipher_suite_index*/
|
|
|
|
IP_TRUE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_STRICT, /*validateFrames*/
|
|
IP_FALSE, /*replayProtect*/
|
|
0, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
|
|
/* Unit Test Profile #2: Use on Station A to test PN exhaustion */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_2A =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_GCM_AES_128, /*cipher_suite_index*/
|
|
|
|
IP_TRUE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_STRICT, /*validateFrames*/
|
|
IP_FALSE, /*replayProtect*/
|
|
0, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
0xfffffff0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_OFF /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
|
|
/* Unit Test Profile #2: Use on Station B. Can be used to test Replay Windows with profile 1 or exhaustion with profile 2 */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_2B =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_GCM_AES_128, /*cipher_suite_index*/
|
|
|
|
IP_TRUE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_STRICT, /*validateFrames*/
|
|
IP_TRUE, /*replayProtect*/
|
|
2, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
7, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
5, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
|
|
/* Unit Test Profile #3: Use on Station A */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_3A =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_GCM_AES_128, /*cipher_suite_index*/
|
|
|
|
IP_TRUE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_CHECK, /*validateFrames*/
|
|
IP_FALSE, /*replayProtect*/
|
|
0, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_OFF /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
|
|
/* Unit Test Profile #3: Use on Station B */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_3B =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_GCM_AES_128, /*cipher_suite_index*/
|
|
|
|
IP_FALSE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_DISABLED, /*validateFrames*/
|
|
IP_FALSE, /*replayProtect*/
|
|
0, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_OFF, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
|
|
#ifdef IPMACSEC_CRYPTO_ALLOW_NULL_CIPHER
|
|
/* NULL Cipher Unit Test Profile #1: Use on Station A */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_null_ciph_1A =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_NULL_CIPHER_128, /*cipher_suite_index*/
|
|
|
|
IP_TRUE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_STRICT, /*validateFrames*/
|
|
IP_FALSE, /*replayProtect*/
|
|
0, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_OFF /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
|
|
/* NULL Cipher Unit Test Profile #1: Use on Station A */
|
|
Ipmacsec_secy_profile ipmacsec_ut_profile_null_ciph_1B =
|
|
{
|
|
IPMACSEC_UT_SYSVAR_SCI, /*sci_sysvar*/
|
|
IPMACSEC_CIPHERSUITE_NULL_CIPHER_128, /*cipher_suite_index*/
|
|
|
|
IP_TRUE, /*protectFrames*/
|
|
IP_TRUE, /*alwaysIncludeSCI*/
|
|
IP_TRUE, /*useES*/
|
|
IP_FALSE, /*useSCB*/
|
|
|
|
IPMACSEC_SECY_VALIDATEFRAMES_STRICT, /*validateFrames*/
|
|
IP_FALSE, /*replayProtect*/
|
|
0, /*replayWindow*/
|
|
|
|
0, /*confidentialityOffset*/
|
|
|
|
0, /*pn_threshold*/
|
|
IP_TRUE, /*info_notify*/
|
|
|
|
{
|
|
IP_TRUE, /*ControlledPortEnabled*/
|
|
IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO /*adminPointToPointMAC*/
|
|
}, /*cp_profile*/
|
|
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IP_NULL, /*sci_sysvar*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00010001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_3, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_ON, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00010002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_4, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_OFF, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
}, /*tx_sc_profile*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
IPMACSEC_UT_SYSVAR_RX_SCI_1, /*sci*/
|
|
{
|
|
{
|
|
IP_TRUE, /*create*/
|
|
0, /*an*/
|
|
0x00020001, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_1, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
}, /*Ipmacsec_sa_profile[0]*/
|
|
{
|
|
IP_TRUE, /*create*/
|
|
1, /*an*/
|
|
0x00020002, /*ref*/
|
|
&ipmacsec_ut_sak_128b_key_2, /*sak_profile*/
|
|
0, /*nextPN*/
|
|
IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, /*confidentiality*/
|
|
0, /*lowestPN*/
|
|
IPMACSEC_ENABLEFLAG_IGNORE, /*enableTx*/
|
|
IPMACSEC_ENABLEFLAG_ON /*enableRx*/
|
|
} /*Ipmacsec_sa_profile[1]*/
|
|
}
|
|
} /*rx_sc_profile[0]*/
|
|
}
|
|
};
|
|
#endif
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPMACSEC_UNIT_TEST
|
|
#ifdef IPMACSEC_UNIT_TEST_INLINE_HARDCODED_CONFIG
|
|
Ip_bool ipmacsec_dummy_key_change = IP_FALSE;
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_unittest_create_dummy_key
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC Ipmacsec_secy_key *
|
|
ipmacsec_secy_unittest_create_dummy_key(Ipnet_secy *secy) {
|
|
Ip_u32 i;
|
|
Ipmacsec_secy_sak dummy_sak;
|
|
IP_STATIC Ip_u64 id = 0;
|
|
Ipmacsec_secy_key_id key_id;
|
|
|
|
dummy_sak.num_octets = 128/8;
|
|
dummy_sak.buf = ipcom_malloc(dummy_sak.num_octets);
|
|
if (!dummy_sak.buf) {
|
|
return IP_NULL;
|
|
}
|
|
for (i=0; i < dummy_sak.num_octets; i++)
|
|
ipcom_memset(dummy_sak.buf, 0xae^(1<<i), dummy_sak.num_octets);
|
|
if (ipmacsec_dummy_key_change)
|
|
dummy_sak.buf[0] = 0;
|
|
key_id.val = ++id;
|
|
return ipmacsec_secy_create_key(secy, &dummy_sak, &key_id);
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_unittest_create_all
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipmacsec_secy_unittest_create_all(Ipnet_secy *secy) {
|
|
Ip_u8 an;
|
|
Ip_u8 dummy_sci[IPMACSEC_SCI_LEN];
|
|
Ipmacsec_secy_sc *sc;
|
|
|
|
ip_assert(secy);
|
|
for (an=0; an < secy->config.maxTxKeys; an++) {
|
|
Ipmacsec_secy_sa *sa;
|
|
Ipmacsec_secy_key *dummy_key;
|
|
dummy_key = ipmacsec_secy_unittest_create_dummy_key(secy);
|
|
if (!dummy_key) {
|
|
return -1;
|
|
}
|
|
if (ipmacsec_secy_install_key(secy, dummy_key, IPMACSEC_KEYTYPE_TRANSMIT | IPMACSEC_KEYTYPE_RECEIVE) != 0) {
|
|
return -1;
|
|
}
|
|
sa = ipmacsec_secy_create_tx_sa(secy, an, (an+1)<<8, 1, IPMACSEC_CONFIDENTIALITY_UNSPECIFIED, dummy_key);
|
|
if (sa == IP_NULL) {
|
|
return -1;
|
|
}
|
|
if (ipmacsec_secy_enable_tx_sa(secy, sa, IP_TRUE) != 0) {
|
|
return -1;
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "IPMACSEC-UTEST: Successfully created SecY Tx SAs for interface %s", secy->netif->ipcom.name);
|
|
|
|
ipcom_memset(dummy_sci, 0xAE, IPMACSEC_SCI_LEN);
|
|
sc = ipmacsec_secy_create_rx_sc(secy, dummy_sci);
|
|
if (!sc) {
|
|
return -1;
|
|
}
|
|
IPCOM_LOG1(INFO, "IPMACSEC-UTEST: Successfully created SecY Rx SC for interface %s", secy->netif->ipcom.name);
|
|
|
|
for (an=0; an < secy->config.maxRxKeys; an++) {
|
|
Ipmacsec_secy_sa *sa;
|
|
Ipmacsec_secy_key *dummy_key;
|
|
dummy_key = ipmacsec_secy_unittest_create_dummy_key(secy);
|
|
if (!dummy_key) {
|
|
return -1;
|
|
}
|
|
if (ipmacsec_secy_install_key(secy, dummy_key, IPMACSEC_KEYTYPE_TRANSMIT | IPMACSEC_KEYTYPE_RECEIVE) != 0) {
|
|
return -1;
|
|
}
|
|
sa = ipmacsec_secy_create_rx_sa(secy, sc, an, (an+1)<<16, 1, 0, dummy_key);
|
|
if (sa == IP_NULL) {
|
|
return -1;
|
|
}
|
|
if (ipmacsec_secy_enable_rx_sa(secy, sa, IP_TRUE) != 0) {
|
|
return -1;
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "IPMACSEC-UTEST: Successfully created SecY Rx SAs for interface %s", secy->netif->ipcom.name);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_unittest_delete_all
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IPMACSEC_PRIVATE int
|
|
ipmacsec_secy_unittest_delete_all(Ipnet_secy *secy) {
|
|
Ipmacsec_secy_sc *sc;
|
|
Ip_u8 dummy_sci[IPMACSEC_SCI_LEN];
|
|
|
|
sc = ipmacsec_secy_lookup_rx_sc(secy, dummy_sci);
|
|
if (!sc) {
|
|
return -1;
|
|
}
|
|
if (ipmacsec_secy_delete_rx_sc(secy, sc) != 0) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_unittest_setup
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IPMACSEC_PRIVATE int
|
|
ipmacsec_secy_unittest_setup(Ipnet_secy *secy) {
|
|
if (ipmacsec_secy_unittest_create_all(secy) != 0) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-UTEST: Failed to create Tx SAs for interface %s", secy->netif->ipcom.name);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_unittest_destroy
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IPMACSEC_PRIVATE int
|
|
ipmacsec_secy_unittest_destroy(Ipnet_secy *secy) {
|
|
(void)ipmacsec_secy_unittest_delete_all(secy);
|
|
return 0;
|
|
}
|
|
#endif /* IPMACSEC_UNIT_TEST_INLINE_HARDCODED_CONFIG */
|
|
|
|
IP_STATIC Ip_bool ipmacsec_netlink_monitor_test_exit = IP_FALSE;
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_netlink_monitor_test_callback
|
|
*===========================================================================
|
|
* Description: SecY Monitor test callback routine
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int ipmacsec_netlink_monitor_test_callback(struct Ip_nlmsghdr *nlmsg, int error) {
|
|
IPCOM_LOG1(DEBUG2, "IPMACSEC-NLMON_TEST: callback invoked with error = %d", error);
|
|
if (nlmsg) {
|
|
IPCOM_LOG3(DEBUG2,"IPMACSEC-NLMON_TEST: callback received nlmsg->nlmsg_type=%d (%s), nlmsg->nlmsg_len=%u",
|
|
nlmsg->nlmsg_type, ipmacsec_netlink_type_name(nlmsg->nlmsg_type), nlmsg->nlmsg_len);
|
|
}
|
|
if (ipmacsec_netlink_monitor_test_exit) {
|
|
/* User indicated exit condition */
|
|
ipmacsec_netlink_monitor_test_exit = IP_FALSE;
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_netlink_monitor_test
|
|
*===========================================================================
|
|
* Description: Start a netlink monitor to capture all notifications
|
|
* Runs in the caller context
|
|
* Parameters: timeout- timeout value in seconds
|
|
* Returns: 0 upon success, <0 otherwise
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_netlink_monitor_test(Ip_u32 timeout) {
|
|
Ipmacsec_netlink_handle *nlhandle;
|
|
struct Ip_timeval tv;
|
|
Ip_u32 groups;
|
|
int ret = -1;
|
|
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
groups = IP_NLMSG_GROUP_MASK(IPMACSEC_NLGRP_NOTIFY) | IP_NLMSG_GROUP_MASK(IPMACSEC_NLGRP_MONITOR);
|
|
nlhandle = ipmacsec_netlink_open(groups);
|
|
if (!nlhandle) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-NLMON_TEST: ipmacsec_netlink_open() returned NULL handle");
|
|
goto error_out;
|
|
}
|
|
IPCOM_LOG1(DEBUG2, "IPMACSEC-NLMON_TEST: nlhandle = 0x%x", nlhandle);
|
|
|
|
/* Register */
|
|
ret = ipmacsec_netlink_register(nlhandle, ipmacsec_netlink_monitor_test_callback, &tv, IP_TRUE);
|
|
if (ret < 0) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMON_TEST: ipmacsec_netlink_register() returned %d", ret);
|
|
goto error_out;
|
|
}
|
|
|
|
/* Invoke the netlink loop */
|
|
ret = ipmacsec_netlink_loop(nlhandle);
|
|
IPCOM_LOG0(INFO, "IPMACSEC-NLMON_TEST: ipmacsec_netlink_loop() terminated");
|
|
|
|
error_out:
|
|
ipmacsec_netlink_close(nlhandle);
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLMON_TEST: Exiting with ret = %d", ret);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_mon_testd
|
|
*===========================================================================
|
|
* Description: MACsec SecY Uncontrolled Port reception test daemon
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC
|
|
IPCOM_PROCESS(ipmacsec_secy_mon_testd) {
|
|
char ifname[IP_IFNAMSIZ];
|
|
Ip_size_t len;
|
|
int ret;
|
|
Ip_u32 timeout;
|
|
char *sysvar;
|
|
char strval[16];
|
|
Ip_u32 pid;
|
|
|
|
IPCOM_LOG0(DEBUG2, "ipmacsec_secy_mon_testd :: Started");
|
|
|
|
ipcom_proc_init();
|
|
|
|
sysvar = "ipmacsec.secy.ut.montestd.ifname";
|
|
len = IP_IFNAMSIZ;
|
|
if (ipcom_sysvar_get(sysvar, ifname, &len) == IP_NULL) {
|
|
IPCOM_LOG1(WARNING, "ipmacsec_secy_mon_testd :: Failed to get sysvar %s", sysvar);
|
|
goto exit;
|
|
}
|
|
|
|
sysvar = "ipmacsec.secy.ut.montestd.timeout";
|
|
len = sizeof(strval);
|
|
if (ipcom_sysvar_get(sysvar, strval, &len) == IP_NULL) {
|
|
IPCOM_LOG1(WARNING, "ipmacsec_secy_ucp_testd :: Failed to get sysvar %s", sysvar);
|
|
goto exit;
|
|
}
|
|
timeout = ipcom_atoi(strval);
|
|
|
|
ret = ipmacsec_lmi_monitor_start(timeout, IP_TRUE, &pid, IP_NULL, 0);
|
|
|
|
exit:
|
|
IPCOM_LOG1(DEBUG2, "ipmacsec_secy_mon_testd :: Exiting (ret = %d)", ret);
|
|
ipcom_proc_exit();
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_monitor_test_start_daemon
|
|
*===========================================================================
|
|
* Description: Start a MACsec SecY Monitor test daemon
|
|
* Should only start one daemon at a time.
|
|
* Parameters: ifname - Interface bame
|
|
* num_expected_pkts - # of packets to expect before existing (0 ==> loop forever or until timeout)
|
|
* timeout - # of seconds before timing out (in seconds) (0 ==> no timeout)
|
|
* Returns: 0 upon successfully starting the daemon, <0 on error
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_secy_monitor_test_start_daemon(char *ifname, Ip_u32 timeout) {
|
|
Ipcom_proc_attr proc_attr;
|
|
char *sysvar;
|
|
char strval[16];
|
|
Ip_err rc;
|
|
|
|
sysvar = "ipmacsec.secy.ut.montestd.ifname";
|
|
if ((rc = ipcom_sysvar_set(sysvar, ifname, IPCOM_SYSVAR_FLAG_OVERWRITE)) != IPCOM_SUCCESS) {
|
|
IPCOM_LOG1(CRIT, "ipmacsec_secy_monitor_test_start_daemon :: Failed to set sysvar %s", sysvar);
|
|
return rc;
|
|
}
|
|
|
|
ipcom_snprintf(strval, sizeof(strval), "%d", timeout);
|
|
sysvar = "ipmacsec.secy.ut.montestd.timeout";
|
|
if ((rc = ipcom_sysvar_set(sysvar, strval, IPCOM_SYSVAR_FLAG_OVERWRITE)) != IPCOM_SUCCESS) {
|
|
IPCOM_LOG1(CRIT, "ipmacsec_secy_monitor_test_start_daemon :: Failed to set sysvar %s", sysvar);
|
|
return rc;
|
|
}
|
|
|
|
ipcom_proc_attr_init(&proc_attr);
|
|
proc_attr.stacksize = IPCOM_PROC_STACK_SMALL;
|
|
rc = ipcom_proc_acreate("secy_mon_testd", ipmacsec_secy_mon_testd, &proc_attr, IP_NULL);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_netlink_test
|
|
*===========================================================================
|
|
* Description: Execute some netlink message tests
|
|
* Parameters: none
|
|
* Returns: 0 upon success, <0 otherwise
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_netlink_test(void) {
|
|
Ipmacsec_netlink_handle *nlhandle;
|
|
struct Ip_nlmsghdr empty_request;
|
|
struct {
|
|
struct Ip_nlmsghdr nlh;
|
|
Ip_u32 command;
|
|
} request;
|
|
Ipmacsec_buffer response;
|
|
int ret = -1;
|
|
Ip_u32 num_exec_tests = 0, num_failed_tests = 0;
|
|
|
|
|
|
nlhandle = ipmacsec_netlink_open(IPMACSEC_NLGRP_NONE);
|
|
if (!nlhandle) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-NLTEST: ipmacsec_netlink_open() returned NULL handle");
|
|
goto nl_test_done;
|
|
}
|
|
|
|
/* send an uninitialized request */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLTEST: Executing test #%u", num_exec_tests);
|
|
ipcom_memset(&empty_request, 0, sizeof(empty_request));
|
|
empty_request.nlmsg_len = IP_NLMSG_LENGTH(0);
|
|
ret = ipmacsec_netlink_request(nlhandle, &empty_request, IP_NULL);
|
|
if (ret < 0) {
|
|
IPCOM_LOG0(INFO,
|
|
"IPMACSEC-NLTEST: ipmacsec_netlink_request() with INVALID request/NULL response failed (expepcted result)");
|
|
} else {
|
|
IPCOM_LOG0(ERR,
|
|
"IPMACSEC-NLTEST: ipmacsec_netlink_request() with INVALID request/NULL response succeeded (unexpepcted result)");
|
|
num_failed_tests++;
|
|
}
|
|
|
|
/* Just send an empty request */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLTEST: Executing test #%u", num_exec_tests);
|
|
ipcom_memset(&empty_request, 0, sizeof(empty_request));
|
|
empty_request.nlmsg_len = IP_NLMSG_LENGTH(0);
|
|
empty_request.nlmsg_type = IPMACSEC_NLTYPE_TEST;
|
|
ret = ipmacsec_netlink_request(nlhandle, &empty_request, IP_NULL);
|
|
if (ret < 0) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-NLTEST: ipmacsec_netlink_request() with EMPTY TEST request/NULL response failed");
|
|
num_failed_tests++;
|
|
} else {
|
|
IPCOM_LOG0(INFO, "IPMACSEC-NLTEST: ipmacsec_netlink_request() with EMPTY TEST request/NULL response succeeded");
|
|
}
|
|
|
|
/* Now send a non empty test request with a NULL response */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLTEST: Executing test #%u", num_exec_tests);
|
|
ipcom_memset(&request, 0, sizeof(request));
|
|
request.nlh.nlmsg_type = IPMACSEC_NLTYPE_TEST;
|
|
request.nlh.nlmsg_len = IP_NLMSG_LENGTH(sizeof(request.command));
|
|
request.command = 0;
|
|
ret = ipmacsec_netlink_request(nlhandle, &request.nlh, IP_NULL);
|
|
if (ret < 0) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-NLTEST: ipmacsec_netlink_request() with TEST request/NULL response failed");
|
|
num_failed_tests++;
|
|
} else {
|
|
IPCOM_LOG0(INFO, "IPMACSEC-NLTEST: ipmacsec_netlink_request() with TEST request/NULL response succeeded");
|
|
}
|
|
|
|
/* Now send a non empty test request with an expcted response */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLTEST: Executing test #%u", num_exec_tests);
|
|
IPMACSEC_BUF_INIT(&response);
|
|
IPMACSEC_BUF_ALLOC(&response, IP_NLMSG_LENGTH(0));
|
|
if (!IPMACSEC_BUF_VERIFY(&response)) {
|
|
IPCOM_LOG0(CRIT, "IPMACSEC-NLTEST: failed to alloc response");
|
|
goto nl_test_done;
|
|
}
|
|
ipcom_memset(&request, 0, sizeof(request));
|
|
request.nlh.nlmsg_type = IPMACSEC_NLTYPE_TEST;
|
|
request.nlh.nlmsg_len = IP_NLMSG_LENGTH(sizeof(request.command));
|
|
request.command = 0;
|
|
ret = ipmacsec_netlink_request(nlhandle, &request.nlh, &response);
|
|
if (ret < 0) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-NLTEST: ipmacsec_netlink_request() with TEST request/response failed");
|
|
num_failed_tests++;
|
|
goto nl_test_done;
|
|
}
|
|
if (!IPMACSEC_BUF_VERIFY(&response)) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-NLTEST: invalid response");
|
|
num_failed_tests++;
|
|
goto nl_test_done;
|
|
}
|
|
if (response.size < IP_NLMSG_LENGTH(0)) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLTEST: invalid response size %u", response.size);
|
|
num_failed_tests++;
|
|
goto nl_test_done;
|
|
}
|
|
if (response.truncated) {
|
|
IPCOM_LOG0(DEBUG2, "IPMACSEC-NLTEST: response truncated");
|
|
}
|
|
IPCOM_LOG0(INFO, "IPMACSEC-NLTEST: ipmacsec_netlink_request() with TEST request/ response succeeded");
|
|
|
|
|
|
nl_test_done:
|
|
ipmacsec_netlink_close(nlhandle);
|
|
if (num_failed_tests) {
|
|
IPCOM_LOG2(ERR, "IPMACSEC-NLTEST: COMPLETED WITH FAILURES - %u tests executed, %u failed",
|
|
num_exec_tests, num_failed_tests);
|
|
ret = -1;
|
|
} else {
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLTEST: COMPLETED SUCCESSFULLY - %u tests executed successfully", num_exec_tests);
|
|
ret = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_netlink_multi_test
|
|
*===========================================================================
|
|
* Description: Send a Mutli netlink message requests (without using an lmi handle)
|
|
* Parameters: ifname - Interface name to send to. Must be attached 1st
|
|
* otherwise this test will fail.
|
|
* Returns: 0 upon success, <0 otherwise
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_netlink_multi_test(char *ifname) {
|
|
Ipmacsec_buffer request, response;
|
|
Ip_bool en = IP_FALSE, doEnable = IP_FALSE;
|
|
int ret = -1;
|
|
Ip_u32 num_exec_tests = 0, num_failed_tests = 0;
|
|
|
|
if (!ifname) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-NLMULTI_TEST: NULL ifname. Test not executed.");
|
|
return -1;
|
|
}
|
|
|
|
/* Init and alloc buffers */
|
|
IPMACSEC_BUF_INIT(&request);
|
|
IPMACSEC_BUF_INIT(&response);
|
|
if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) {
|
|
IPCOM_LOG0(CRIT, "IPMACSEC-NLMULTI_TEST: failed to alloc request");
|
|
goto err_out;
|
|
}
|
|
if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) {
|
|
IPCOM_LOG0(CRIT, "IPMACSEC-NLMULTI_TEST: failed to alloc response");
|
|
goto err_out;
|
|
}
|
|
|
|
|
|
/* 1- Disable and check status */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLMULTI_TEST: Executing test #%u", num_exec_tests);
|
|
doEnable = IP_FALSE;
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_set_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_2;
|
|
}
|
|
ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, IP_NULL, 0);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_get_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_2;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send(IP_NULL, &request, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_send() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_2;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &en, sizeof(en));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_parse_response() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_2;
|
|
}
|
|
if (en != doEnable) {
|
|
IPCOM_LOG2(ERR, "IPMACSEC-NLMULTI_TEST: mismatched results (en=%u, doEnable=%u)", en, doEnable);
|
|
num_failed_tests++;
|
|
goto test_2;
|
|
}
|
|
|
|
test_2:
|
|
/* 2- Enable and check status */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLMULTI_TEST: Executing test #%u", num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&request);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
doEnable = IP_TRUE;
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_set_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_3;
|
|
}
|
|
ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, IP_NULL, 0);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_get_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_3;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send(IP_NULL, &request, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_send() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_3;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &en, sizeof(en));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_parse_response() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_3;
|
|
}
|
|
if (en != doEnable) {
|
|
IPCOM_LOG2(ERR, "IPMACSEC-NLMULTI_TEST: mismatched results (en=%u, doEnable=%u)", en, doEnable);
|
|
num_failed_tests++;
|
|
goto test_3;
|
|
}
|
|
|
|
test_3:
|
|
/* 3- Disable/Enable and check status */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLMULTI_TEST: Executing test #%u", num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&request);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
doEnable = IP_FALSE;
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_set_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_4;
|
|
}
|
|
doEnable = IP_TRUE;
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_set_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_4;
|
|
}
|
|
ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, IP_NULL, 0);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_get_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_4;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send(IP_NULL, &request, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_send() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_4;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &en, sizeof(en));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_parse_response() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_4;
|
|
}
|
|
if (en != doEnable) {
|
|
IPCOM_LOG2(ERR, "IPMACSEC-NLMULTI_TEST: mismatched results (en=%u, doEnable=%u)", en, doEnable);
|
|
num_failed_tests++;
|
|
goto test_4;
|
|
}
|
|
|
|
test_4:
|
|
/* 4- Disable/Enable/Disable and check status */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLMULTI_TEST: Executing test #%u", num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&request);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
doEnable = IP_FALSE;
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_set_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_5;
|
|
}
|
|
doEnable = IP_TRUE;
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_set_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_5;
|
|
}
|
|
doEnable = IP_FALSE;
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_set_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_5;
|
|
}
|
|
ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, IP_NULL, 0);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_secy_get_cmd_append() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_5;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send(IP_NULL, &request, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_send() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_5;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &en, sizeof(en));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-NLMULTI_TEST: ipmacsec_lmi_cmd_parse_response() failed (ret=%d)", ret);
|
|
num_failed_tests++;
|
|
goto test_5;
|
|
}
|
|
if (en != doEnable) {
|
|
IPCOM_LOG2(ERR, "IPMACSEC-NLMULTI_TEST: mismatched results (en=%u, doEnable=%u)", en, doEnable);
|
|
num_failed_tests++;
|
|
goto test_5;
|
|
}
|
|
|
|
test_5:
|
|
err_out:
|
|
ipmacsec_nlmsg_free(&request);
|
|
ipmacsec_nlmsg_free(&response);
|
|
if (num_failed_tests) {
|
|
IPCOM_LOG2(ERR, "IPMACSEC-NLMULTI_TEST: COMPLETED WITH FAILURES - %u tests executed, %u failed",
|
|
num_exec_tests, num_failed_tests);
|
|
ret = -1;
|
|
} else {
|
|
IPCOM_LOG1(INFO, "IPMACSEC-NLMULTI_TEST: COMPLETED SUCCESSFULLY - %u tests executed successfully", num_exec_tests);
|
|
ret = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_key_test
|
|
*===========================================================================
|
|
* Description: Test the key install/remove operations.
|
|
* Parameters: ifname - Interface name to send to. Must be attached 1st
|
|
* otherwise this test will fail.
|
|
* Returns: 0 upon success, <0 otherwise
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_key_test(char *ifname) {
|
|
Ipmacsec_secy_key_descriptor key_desc;
|
|
IPMACSEC_LMI_HANDLE lh = IP_NULL;
|
|
Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_UNSPECIFIED_ERROR;
|
|
Ip_u32 i=0, num_exec_tests = 0, num_failed_tests = 0;
|
|
Ip_u64 key_id = 0xdeadbeef;
|
|
Ip_u8 dummy_key[16];
|
|
Ipmacsec_buffer key_info;
|
|
|
|
if (!ifname) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-KEY_TEST: NULL ifname. Test not executed.");
|
|
return -1;
|
|
}
|
|
lh = ipmacsec_lmi_handle_create();
|
|
if (!lh) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-KEY_TEST: Failed to create lmi handle. Test not executed.");
|
|
return -1;
|
|
}
|
|
|
|
/* Allocate enough buffer space for key descriptors */
|
|
IPMACSEC_BUF_INIT(&key_info);
|
|
if (ipmacsec_buf_alloc(&key_info, sizeof(Ipmacsec_secy_key_descriptor)*IPMACSEC_SECY_KEYDB_SIZE) == IP_NULL) {
|
|
IPCOM_LOG0(CRIT, "IPMACSEC-KEY_TEST: failed to alloc key_info buffer");
|
|
goto err_out;
|
|
}
|
|
|
|
/* 1- Install a Key (should succeed) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = key_id;
|
|
key_desc.key_size = sizeof(dummy_key);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_TRANSMIT;
|
|
ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, dummy_key);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG4(ERR, "IPMACSEC-KEY_TEST: Failed to install key with key_id 0x%llx, keysize %u. (ret=%d, %s).",
|
|
key_desc.key_id.val, key_desc.key_size, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
} else {
|
|
IPCOM_LOG2(INFO, "IPMACSEC-KEY_TEST: Successfully installed key with key_id 0x%llx, keysize %u.",
|
|
key_desc.key_id.val, sizeof(dummy_key));
|
|
}
|
|
|
|
/* 2- Retrieve key info (should succeed) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = key_id;
|
|
IPMACSEC_BUF_WIPE(&key_info);
|
|
ret = ipmacsec_lmi_secy_get_key_info(lh, ifname, &key_desc, &key_info);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-KEY_TEST: Failed to retrieve key info for key_id 0x%llx (ret=%d, %s).",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
} else {
|
|
Ipmacsec_secy_key_descriptor *kdesc = (Ipmacsec_secy_key_descriptor *)IPMACSEC_BUF_HEAD(&key_info);
|
|
if (key_info.size < sizeof(Ipmacsec_secy_key_descriptor)) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-KEY_TEST: Invalid key descriptor for key_id 0x%llx (size = %u < %u).",
|
|
key_desc.key_id.val, key_info.size, sizeof(Ipmacsec_secy_key_descriptor));
|
|
} else if (kdesc->key_id.val != key_desc.key_id.val) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-KEY_TEST: Invalid key descriptor key_id (0x%llx != 0x%llx).",
|
|
kdesc->key_id.val, key_desc.key_id.val);
|
|
} else {
|
|
IPMACSEC_TIMEBUF(tbuf);
|
|
IPMACSEC_STRFTIME(tbuf, kdesc->created_time);
|
|
IPCOM_LOG6(INFO, "IPMACSEC-KEY_TEST: Successfully retrieved info for key: key_id 0x%llx, keysize %u, "
|
|
"transmits %s, receives %s, inUse %s, created_time %s",
|
|
kdesc->key_id.val, kdesc->key_size,
|
|
IPMACSEC_BOOL_STRING(kdesc->key_type & IPMACSEC_KEYTYPE_TRANSMIT),
|
|
IPMACSEC_BOOL_STRING(kdesc->key_type & IPMACSEC_KEYTYPE_RECEIVE),
|
|
IPMACSEC_BOOL_STRING(kdesc->inUse), tbuf);
|
|
}
|
|
}
|
|
|
|
/* 3- Try to Install the same Key again (should fail) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = key_id;
|
|
key_desc.key_size = sizeof(dummy_key);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_TRANSMIT;
|
|
ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, dummy_key);
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-KEY_TEST: Succeeded in installing key with same key_id 0x%llx. Incorrect result",
|
|
key_desc.key_id.val);
|
|
} else {
|
|
IPCOM_LOG3(INFO, "IPMACSEC-KEY_TEST: Failed to re-install key with same key_id 0x%llx (ret=%d, %s). Expected Result",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
}
|
|
|
|
/* 4- Try to remove a key with a different key id (should fail) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = 0;
|
|
ret = ipmacsec_lmi_secy_key_remove(lh, ifname, &key_desc);
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-KEY_TEST: Succeeded in removing key with differet key_id 0x%llx. Incorrect result", key_desc.key_id.val);
|
|
} else {
|
|
IPCOM_LOG3(INFO, "IPMACSEC-KEY_TEST: Failed to remove key with differet key_id 0x%llx (ret=%d, %s). Expected Result",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
}
|
|
|
|
/* 5- Try to remove the correct key now (should succeed) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = key_id;
|
|
ret = ipmacsec_lmi_secy_key_remove(lh, ifname, &key_desc);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-KEY_TEST: Failed to remove key with same key_id 0x%llx (ret=%d, %s).",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
} else {
|
|
IPCOM_LOG1(INFO, "IPMACSEC-KEY_TEST: Succeeded in removing key with same key_id 0x%llx.", key_desc.key_id.val);
|
|
}
|
|
|
|
/* 6- Try to retrieve key info (should fail) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = key_id;
|
|
IPMACSEC_BUF_WIPE(&key_info);
|
|
ret = ipmacsec_lmi_secy_get_key_info(lh, ifname, &key_desc, &key_info);
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-KEY_TEST: Successfully retrieve key info for removed key_id 0x%llx (ret=%d, %s). Incorrect result",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
} else {
|
|
IPCOM_LOG1(INFO, "IPMACSEC-KEY_TEST: Failed to retrieve key info for removed key_id 0x%llx. Expected Result",
|
|
key_desc.key_id.val);
|
|
}
|
|
|
|
/* 7- Try to remove the same key again (should fail) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = key_id;
|
|
ret = ipmacsec_lmi_secy_key_remove(lh, ifname, &key_desc);
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-KEY_TEST: Succeeded in removing key with same key_id 0x%llx. Incorrect result", key_desc.key_id.val);
|
|
} else {
|
|
IPCOM_LOG3(INFO, "IPMACSEC-KEY_TEST: Failed to remove key with same key_id 0x%llx (ret=%d, %s). Expected result",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
}
|
|
|
|
/* 8- Delete all keys (should succeed) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ret = ipmacsec_lmi_secy_key_purge(lh, ifname);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-KEY_TEST: Failed to purge keys.");
|
|
} else {
|
|
IPCOM_LOG0(INFO, "IPMACSEC-KEY_TEST: Succeeded in purging keys.");
|
|
}
|
|
|
|
/* 9- Retrieve all key info (should succeed, but return none) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&key_info);
|
|
ret = ipmacsec_lmi_secy_get_key_info(lh, ifname, IP_NULL, &key_info);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-KEY_TEST: Failed to retrieve key info list (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
} else {
|
|
if (key_info.size != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-KEY_TEST: key info returned when there should be none (key_info.size = %u).",
|
|
key_info.size);
|
|
for (i = 1; i <= IPMACSEC_SECY_KEYDB_SIZE; i++) {
|
|
Ip_u32 remlen;
|
|
Ipmacsec_secy_key_descriptor *kdesc = (Ipmacsec_secy_key_descriptor *)
|
|
ipmacsec_buf_ptr(&key_info, (i-1)*sizeof(Ipmacsec_secy_key_descriptor), &remlen);
|
|
if (!kdesc) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-KEY_TEST: kdesc NULL!");
|
|
} else {
|
|
IPMACSEC_TIMEBUF(tbuf);
|
|
IPMACSEC_STRFTIME(tbuf, kdesc->created_time);
|
|
IPCOM_LOG7(INFO, "IPMACSEC-KEY_TEST: Retrieved info for key #%u: key_id 0x%llx, keysize %u, "
|
|
"transmits %s, receives %s, inUse %s, created_time %s",
|
|
i, kdesc->key_id.val, kdesc->key_size,
|
|
IPMACSEC_BOOL_STRING(kdesc->key_type & IPMACSEC_KEYTYPE_TRANSMIT),
|
|
IPMACSEC_BOOL_STRING(kdesc->key_type & IPMACSEC_KEYTYPE_RECEIVE),
|
|
IPMACSEC_BOOL_STRING(kdesc->inUse), tbuf);
|
|
}
|
|
}
|
|
} else {
|
|
IPCOM_LOG0(INFO, "IPMACSEC-KEY_TEST: No key info retrieved. Expected result");
|
|
}
|
|
}
|
|
|
|
|
|
/* 10- Install Max keys (should succeed) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
for (i = 1; i <= IPMACSEC_SECY_KEYDB_SIZE; i++) {
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = ((Ip_u64)i << 32 | key_id);
|
|
key_desc.key_size = sizeof(dummy_key);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_TRANSMIT;
|
|
ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, dummy_key);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG5(ERR, "IPMACSEC-KEY_TEST: Failed to install key #%u with key_id 0x%llx, keysize %u. (ret=%d, %s).",
|
|
i, key_desc.key_id.val, key_desc.key_size, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
} else {
|
|
IPCOM_LOG3(INFO, "IPMACSEC-KEY_TEST: Successfully installed key #%u with key_id 0x%llx, keysize %u.",
|
|
i, key_desc.key_id.val, sizeof(dummy_key));
|
|
}
|
|
}
|
|
|
|
/* 11- Install 1 more key than mac (should fail) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = ((Ip_u64)i << 32 | key_id);
|
|
key_desc.key_size = sizeof(dummy_key);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_TRANSMIT;
|
|
ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, dummy_key);
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-KEY_TEST: Successfully installed key #%u with key_id 0x%llx, keysize %u. Incorrect result",
|
|
i, key_desc.key_id.val, sizeof(dummy_key));
|
|
} else {
|
|
IPCOM_LOG5(INFO, "IPMACSEC-KEY_TEST: Failed to install key #%u with key_id 0x%llx, keysize %u. (ret=%d, %s). Expected result",
|
|
i, key_desc.key_id.val, key_desc.key_size, ret, ipmacsec_lmi_error_name(ret));
|
|
}
|
|
|
|
/* 12- Retreive all key info (should succeed with max # of key info returned) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&key_info);
|
|
ret = ipmacsec_lmi_secy_get_key_info(lh, ifname, IP_NULL, &key_info);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-KEY_TEST: Failed to retrieve key info list (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
} else {
|
|
if (key_info.size != IPMACSEC_SECY_KEYDB_SIZE*sizeof(Ipmacsec_secy_key_descriptor)) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-KEY_TEST: Incorrect number of key info returned (%u != %u). Incorrect result",
|
|
key_info.size, IPMACSEC_SECY_KEYDB_SIZE*sizeof(Ipmacsec_secy_key_descriptor));
|
|
} else if (key_info.truncated) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-KEY_TEST: key info buffer truncated (size = %u, alloc_size = %u).",
|
|
key_info.size, key_info.alloc_size);
|
|
} else {
|
|
IPCOM_LOG0(INFO, "IPMACSEC-KEY_TEST: Complete key info retrieved successfully.");
|
|
for (i = 1; i <= IPMACSEC_SECY_KEYDB_SIZE; i++) {
|
|
Ip_u32 remlen;
|
|
Ipmacsec_secy_key_descriptor *kdesc = (Ipmacsec_secy_key_descriptor *)
|
|
ipmacsec_buf_ptr(&key_info, (i-1)*sizeof(Ipmacsec_secy_key_descriptor), &remlen);
|
|
if (!kdesc) {
|
|
IPCOM_LOG0(WARNING, "IPMACSEC-KEY_TEST: kdesc NULL!");
|
|
} else {
|
|
IPMACSEC_TIMEBUF(tbuf);
|
|
IPMACSEC_STRFTIME(tbuf, kdesc->created_time);
|
|
IPCOM_LOG7(INFO, "IPMACSEC-KEY_TEST: Successfully retrieved info for key #%u: key_id 0x%llx, keysize %u, "
|
|
"transmits %s, receives %s, inUse %s, created_time %s",
|
|
i, kdesc->key_id.val, kdesc->key_size,
|
|
IPMACSEC_BOOL_STRING(kdesc->key_type & IPMACSEC_KEYTYPE_TRANSMIT),
|
|
IPMACSEC_BOOL_STRING(kdesc->key_type & IPMACSEC_KEYTYPE_RECEIVE),
|
|
IPMACSEC_BOOL_STRING(kdesc->inUse), tbuf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 13- Delete all keys (should succeed) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
ret = ipmacsec_lmi_secy_key_purge(lh, ifname);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-KEY_TEST: Failed to purge keys.");
|
|
} else {
|
|
IPCOM_LOG0(INFO, "IPMACSEC-KEY_TEST: Succeeded in purging keys.");
|
|
}
|
|
|
|
/* 14- Retreive all key info (should succeed 0 key info returned) */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-KEY_TEST: Executing test #%u *****", num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&key_info);
|
|
ret = ipmacsec_lmi_secy_get_key_info(lh, ifname, IP_NULL, &key_info);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-KEY_TEST: Failed to retrieve key info list (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
} else {
|
|
if (key_info.size != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-KEY_TEST: key info returned when there should be none (key_info.size = %u).",
|
|
key_info.size);
|
|
} else {
|
|
IPCOM_LOG0(INFO, "IPMACSEC-KEY_TEST: No key info retrieved. Expected result");
|
|
}
|
|
}
|
|
|
|
|
|
err_out:
|
|
if (num_failed_tests) {
|
|
IPCOM_LOG2(ERR, "IPMACSEC-KEY_TEST: COMPLETED WITH FAILURES - %u tests executed, %u failed",
|
|
num_exec_tests, num_failed_tests);
|
|
ret = -1;
|
|
} else {
|
|
IPCOM_LOG1(INFO, "IPMACSEC-KEY_TEST: COMPLETED SUCCESSFULLY - %u tests executed successfully", num_exec_tests);
|
|
ret = 0;
|
|
}
|
|
(void)ipmacsec_buf_free(&key_info);
|
|
(void)ipmacsec_lmi_handle_delete(lh);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_ctrl_cmd_test
|
|
*===========================================================================
|
|
* Description: Test the SecY Control Set/Get operations.
|
|
* Set commands will fail if executed when the Secy is enabled.
|
|
* Parameters: ifname - Interface name to send to. Must be attached 1st
|
|
* otherwise this test will fail.
|
|
* Returns: 0 upon success, <0 otherwise
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_ctrl_cmd_test(char *ifname) {
|
|
Ipmacsec_lmi_command bool_cmds[] = {IPMACSEC_LMICMD_SECY_PROTECT_FRAMES,
|
|
IPMACSEC_LMICMD_SECY_ALWAYS_INC_SCI,
|
|
IPMACSEC_LMICMD_SECY_USE_ES,
|
|
IPMACSEC_LMICMD_SECY_USE_SCB,
|
|
IPMACSEC_LMICMD_SECY_REPLAY_PROTECT};
|
|
Ipmacsec_lmi_command ipu32_cmds[] = {IPMACSEC_LMICMD_SECY_REPLAY_WINDOW};
|
|
Ipmacsec_validateFrames_type validateFrames;
|
|
IPMACSEC_LMI_HANDLE lh = IP_NULL;
|
|
Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_UNSPECIFIED_ERROR;
|
|
Ip_u32 i = 0;
|
|
Ipmacsec_buffer request, response;
|
|
Ipmacsec_lmi_command cmd;
|
|
|
|
if (!ifname) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-CTRL_TEST: NULL ifname. Test not executed.");
|
|
return -1;
|
|
}
|
|
lh = ipmacsec_lmi_handle_create();
|
|
if (!lh) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-CTRL_TEST: Failed to create lmi handle. Test not executed.");
|
|
return -1;
|
|
}
|
|
|
|
IPMACSEC_BUF_INIT(&request);
|
|
if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) {
|
|
ret = IPMACSEC_LMIERR_ALLOC_FAILED;
|
|
goto err_out;
|
|
}
|
|
IPMACSEC_BUF_INIT(&response);
|
|
if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) {
|
|
ret = IPMACSEC_LMIERR_ALLOC_FAILED;
|
|
goto err_out;
|
|
}
|
|
|
|
for (i=0; i < sizeof(bool_cmds)/sizeof(bool_cmds[0]); i++) {
|
|
Ip_bool bool_val;
|
|
for (bool_val = 0; bool_val <= 1; bool_val++) {
|
|
Ip_bool val = bool_val;
|
|
cmd = bool_cmds[i];
|
|
ret = ipmacsec_lmi_cmd_send_bool(lh, ifname, cmd, &val, IPMACSEC_LMICMD_ISSET);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto set_cmd_send_err;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send_bool(lh, ifname, cmd, &val, IPMACSEC_LMICMD_ISGET);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto get_cmd_send_err;
|
|
}
|
|
if (val != bool_val) {
|
|
IPCOM_LOG3(ERR, "IPMACSEC-CTRL_TEST: cmd %s result mismatch (%s, expected %s)",
|
|
ipmacsec_lmi_cmd_name(cmd), IPMACSEC_BOOL_STRING(val), IPMACSEC_BOOL_STRING(bool_val));
|
|
goto err_out;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i=0; i < sizeof(ipu32_cmds)/sizeof(ipu32_cmds[0]); i++) {
|
|
Ip_u32 ipu32_val = 0;
|
|
cmd = ipu32_cmds[i];
|
|
for (;;) {
|
|
Ip_u32 val = ipu32_val;
|
|
ret = ipmacsec_lmi_cmd_send_u32(lh, ifname, cmd, &val, IPMACSEC_LMICMD_ISSET);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto set_cmd_send_err;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send_u32(lh, ifname, cmd, &val, IPMACSEC_LMICMD_ISGET);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto get_cmd_send_err;
|
|
}
|
|
if (val != ipu32_val) {
|
|
IPCOM_LOG3(ERR, "IPMACSEC-CTRL_TEST: cmd %s result mismatch (%u, expected %u)",
|
|
ipmacsec_lmi_cmd_name(cmd), val, ipu32_val);
|
|
goto err_out;
|
|
}
|
|
if (ipu32_val == 0xffffffffL)
|
|
break;
|
|
ipu32_val++;
|
|
if (ipu32_val == 1)
|
|
ipu32_val = 0xffffffffL;
|
|
}
|
|
}
|
|
|
|
for (validateFrames=__IPMACSEC_SECY_VALIDATEFRAMES_INVALID;
|
|
validateFrames<= __IPMACSEC_SECY_VALIDATEFRAMES_MAX; validateFrames++) {
|
|
Ipmacsec_validateFrames_type val = validateFrames;
|
|
cmd = IPMACSEC_LMICMD_SECY_VALIDATE_FRAMES;
|
|
IPMACSEC_BUF_WIPE(&request);
|
|
ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, cmd, &val, sizeof(val));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto set_cmd_append_err;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL);
|
|
if (IPMACSEC_VALIDATEFRAMES_VALID(validateFrames)) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto set_cmd_send_err;
|
|
}
|
|
} else {
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
ret = -1;
|
|
goto set_cmd_send_err;
|
|
}
|
|
ret = 0;
|
|
continue;
|
|
}
|
|
IPMACSEC_BUF_WIPE(&request);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, cmd, &val, sizeof(val));
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto get_cmd_append_err;
|
|
}
|
|
ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
goto get_cmd_send_err;
|
|
}
|
|
if (IPMACSEC_VALIDATEFRAMES_VALID(validateFrames) && (val != validateFrames)) {
|
|
IPCOM_LOG3(ERR, "IPMACSEC-CTRL_TEST: cmd %s result mismatch (%u, expected %u)",
|
|
ipmacsec_lmi_cmd_name(cmd), val, validateFrames);
|
|
goto err_out;
|
|
}
|
|
}
|
|
goto err_out;
|
|
|
|
set_cmd_append_err:
|
|
IPCOM_LOG1(ERR, "IPMACSEC-CTRL_TEST: Failed to append set cmd %s", ipmacsec_lmi_cmd_name(cmd));
|
|
goto err_out;
|
|
|
|
get_cmd_append_err:
|
|
IPCOM_LOG1(ERR, "IPMACSEC-CTRL_TEST: Failed to append get cmd %s", ipmacsec_lmi_cmd_name(cmd));
|
|
goto err_out;
|
|
|
|
set_cmd_send_err:
|
|
IPCOM_LOG1(ERR, "IPMACSEC-CTRL_TEST: Unexpected result for set cmd %s", ipmacsec_lmi_cmd_name(cmd));
|
|
goto err_out;
|
|
|
|
get_cmd_send_err:
|
|
IPCOM_LOG1(ERR, "IPMACSEC-CTRL_TEST: Unexpected result for get cmd %s", ipmacsec_lmi_cmd_name(cmd));
|
|
goto err_out;
|
|
|
|
err_out:
|
|
(void)ipmacsec_nlmsg_free(&request);
|
|
(void)ipmacsec_nlmsg_free(&response);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_sc_sa_test
|
|
*===========================================================================
|
|
* Description: Test the SecY SC/SA Create/Delete/Control operations.
|
|
* Parameters: ifname - Interface name to send to. Must be attached 1st
|
|
* otherwise this test will fail.
|
|
* Returns: 0 upon success, <0 otherwise
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_sc_sa_test(char *ifname) {
|
|
IPMACSEC_LMI_HANDLE lh = IP_NULL;
|
|
Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_UNSPECIFIED_ERROR;
|
|
Ip_u32 num_exec_tests = 0, num_failed_tests = 0;
|
|
Ipmacsec_buffer response;
|
|
Ipmacsec_secy_sc_info sc_info, *scinf = IP_NULL;
|
|
#ifdef IPMACSEC_USE_STATS
|
|
Ipmacsec_secy_sc_stats sc_stats;
|
|
#endif
|
|
Ipmacsec_secy_sa_info *sai = IP_NULL;
|
|
Ip_u8 my_sci[IPMACSEC_SCI_LEN], sci[IPMACSEC_SCI_LEN];
|
|
Ip_u16 maxTxSAs = 0, maxRxSCs =0, maxRxSAs = 0;
|
|
Ip_u8 an = 0;
|
|
Ip_u16 sc = 0;
|
|
Ip_u32 remlen = 0;
|
|
|
|
/* Verify param */
|
|
if (!ifname) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: NULL ifname. Test not executed.");
|
|
return IPMACSEC_LMIERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
/* Initialize things */
|
|
IPMACSEC_BUF_INIT(&response);
|
|
if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) {
|
|
ret = IPMACSEC_LMIERR_ALLOC_FAILED;
|
|
goto err_out;
|
|
}
|
|
|
|
|
|
IPCOM_LOG1(INFO, "IPMACSEC-SC_SA_TEST: STARTING tests on interface %s.", ifname);
|
|
/* Create an LMI handle */
|
|
lh = ipmacsec_lmi_handle_create();
|
|
if (!lh) {
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: Failed to create lmi handle. Test not executed.");
|
|
return -1;
|
|
}
|
|
|
|
/* 1st Disable the SecY to make sure everything is started from a clean slate
|
|
* This also serves as a test for the SecY existence
|
|
*/
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Disabling SecY *****", num_exec_tests);
|
|
ret = ipmacsec_lmi_secy_enable(lh, ifname, IP_FALSE);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to disable SecY (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Set the TX SCI */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Setting the TX SCI *****", num_exec_tests);
|
|
ipcom_memset(my_sci, 0x11, IPMACSEC_SCI_LEN);
|
|
ret = ipmacsec_lmi_secy_set_tx_sci(lh, ifname, my_sci);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to set the TX SCI (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Verify the TX SCI */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving the TX SCI *****", num_exec_tests);
|
|
ret = ipmacsec_lmi_secy_get_tx_sci(lh, ifname, sci);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to get the TX SCI (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
if (ipcom_memcmp(my_sci, sci, IPMACSEC_SCI_LEN) != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: TX SCI mismatch");
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Now Enable the SecY, which creates the SecY TX SC */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Enabling SecY *****", num_exec_tests);
|
|
ret = ipmacsec_lmi_secy_enable(lh, ifname, IP_TRUE);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to enable SecY (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Verify that the TX SC was created and verify some sc_info fields and stats */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Verifying TX SC status and statistics *****",
|
|
num_exec_tests);
|
|
ipcom_memset(&sc_info, 0, sizeof(sc_info));
|
|
ret = ipmacsec_lmi_secy_get_tx_sc_status(lh, ifname, &sc_info);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
if (ipcom_memcmp(my_sci, sc_info.sci, IPMACSEC_SCI_LEN) != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: TX SCI mismatch in sc_info");
|
|
goto err_out;
|
|
}
|
|
if (sc_info.dir != IPMACSEC_TX) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: TX SCI direction mismatch (%s, %u)", IPMACSEC_DIR_STRING(sc_info.dir), sc_info.dir);
|
|
goto err_out;
|
|
}
|
|
if (sc_info.status.tx.transmitting) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: TX SCI should not be transmitting");
|
|
goto err_out;
|
|
}
|
|
#ifdef IPMACSEC_USE_STATS
|
|
ret = ipmacsec_lmi_secy_get_tx_sc_stats(lh, ifname, &sc_stats);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC stats (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
#endif
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Retrieve the max # of TX SAs */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving max # of supported TX SAs *****", num_exec_tests);
|
|
ret = ipmacsec_lmi_secy_get_maxTxKeys(lh, ifname, &maxTxSAs);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve maxTxKeys (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
if (maxTxSAs != IPMACSEC_MAX_SA ) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Invalid maxTxSAs=%u (!= %u)", maxTxSAs, IPMACSEC_MAX_SA);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Create max # of TX SAs + 1, last one should fail*/
|
|
num_exec_tests++;
|
|
IPCOM_LOG2(INFO,
|
|
"***** IPMACSEC-SC_SA_TEST: Executing test #%u: Create+Get Status+Get Stats+Control %u TX SAs (Last one should fail) *****",
|
|
num_exec_tests, maxTxSAs+1);
|
|
for (an=0; an <= (Ip_u8)maxTxSAs; an++) {
|
|
Ipmacsec_secy_key_descriptor key_desc;
|
|
Ipmacsec_secy_sa_descriptor sa_desc;
|
|
Ipmacsec_secy_sa_info sa_info;
|
|
Ip_u32 ref = (an+1)<<8;
|
|
Ip_u8 dummy_key[16];
|
|
Ip_u32 nextPN=1;
|
|
Ipmacsec_confidentiality confidentiality = IPMACSEC_CONFIDENTIALITY_UNSPECIFIED;
|
|
|
|
/* Install a key */
|
|
ipcom_memset(dummy_key, 0xAE, sizeof(dummy_key));
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = (Ip_u64)(an+1);
|
|
key_desc.key_size = sizeof(dummy_key);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_TRANSMIT;
|
|
ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, dummy_key);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG4(ERR, "IPMACSEC-SC_SA_TEST: Failed to install key with key_id 0x%llx, keysize %u. (ret=%d, %s).",
|
|
key_desc.key_id.val, key_desc.key_size, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
|
|
/* Init the SA descriptor and info structures */
|
|
if (an < (Ip_u8)maxTxSAs) {
|
|
if (ipmacsec_lmi_secy_sa_descriptor_init(&sa_desc, my_sci, an, IPMACSEC_TX, ref, &key_desc.key_id) == IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA descriptor for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* For an invalid AN, we need to do it manually since ipmacsec_lmi_secy_sa_descriptor_init() does not allow it */
|
|
IPMACSEC_COPY_SCI(sa_desc.sci, my_sci);
|
|
sa_desc.an = an;
|
|
sa_desc.dir = IPMACSEC_TX;
|
|
sa_desc.ref = ref;
|
|
sa_desc.key_id.val = key_desc.key_id.val;
|
|
}
|
|
if (ipmacsec_lmi_secy_tx_sa_info_init(&sa_info, nextPN, confidentiality) == IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA info for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
nextPN++;
|
|
|
|
/* Create the SA and verify you can retrieve its info and control it */
|
|
ret = ipmacsec_lmi_secy_create_tx_sa(lh, ifname, &sa_desc, &sa_info);
|
|
if (an < (Ip_u8)maxTxSAs) {
|
|
#ifdef IPMACSEC_USE_STATS
|
|
Ipmacsec_secy_sa_stats sa_stats;
|
|
#endif
|
|
Ipmacsec_secy_sa_ctrl sa_ctrl;
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to create TX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
|
|
/* Retrieve SA status, should succeed */
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_tx_sa_status(lh, ifname, an, ref, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to get status for TX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
sai = (Ipmacsec_secy_sa_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!sai || (remlen < sizeof(Ipmacsec_secy_sa_info))) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Invalid status for TX SA with AN %u (sai=%p, remlen=%u < %u).",
|
|
(void *)sai, remlen, sizeof(Ipmacsec_secy_sa_info));
|
|
goto err_out;
|
|
}
|
|
|
|
#ifdef IPMACSEC_USE_STATS
|
|
/* Retrieve SA staistics, should succeed */
|
|
ret = ipmacsec_lmi_secy_get_tx_sa_stats(lh, ifname, &sa_stats, an, ref);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to get statistics for TX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
#endif
|
|
|
|
/* Control the SA, should succeed */
|
|
if (ipmacsec_lmi_secy_rx_sa_ctrl_init(&sa_ctrl, IPMACSEC_ENABLEFLAG_ON, 2, IPMACSEC_CONFIDENTIALITY_UNSPECIFIED)
|
|
== IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA control struct for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
ret = ipmacsec_lmi_secy_control_tx_sa(lh, ifname, &sa_desc, &sa_ctrl);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to control TX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
/* TX SC should be transmitting */
|
|
ipcom_memset(&sc_info, 0, sizeof(sc_info));
|
|
ret = ipmacsec_lmi_secy_get_tx_sc_status(lh, ifname, &sc_info);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
if (!sc_info.status.tx.transmitting) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: TX SCI should be transmitting");
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* Remove the unused key */
|
|
if (ipmacsec_lmi_secy_key_remove(lh, ifname, &key_desc) != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed in removing key with key_id 0x%llx.",
|
|
key_desc.key_id.val);
|
|
}
|
|
/* Should have failed to install 1 more SA than Max */
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success creating TX SA with AN %u", an);
|
|
goto err_out;
|
|
}
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Retrieve TX SA list. There should be exactly maxTxSAs infos */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving TX SA list *****",
|
|
num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_tx_sa_status(lh, ifname, -1, 0, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SA list (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
sai = (Ipmacsec_secy_sa_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!sai || (remlen < sizeof(Ipmacsec_secy_sa_info)*maxTxSAs)) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Invalid TX SA list (sai=%p, remlen=%u < %u).",
|
|
(void *)sai, remlen, sizeof(Ipmacsec_secy_sa_info)*maxTxSAs);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Delete # of TX SAs + 1, last one should fail*/
|
|
num_exec_tests++;
|
|
IPCOM_LOG2(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Deleting %u TX SAs (Last one should fail) *****",
|
|
num_exec_tests, maxTxSAs+1);
|
|
for (an=0; an <= (Ip_u8)maxTxSAs; an++) {
|
|
Ipmacsec_secy_key_descriptor key_desc;
|
|
Ipmacsec_secy_sa_descriptor sa_desc;
|
|
Ip_u32 ref = (an+1)<<8;
|
|
|
|
/* Init the key descriptor */
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = (Ip_u64)(an+1);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_TRANSMIT;
|
|
|
|
/* Init the SA descriptor */
|
|
if (an < (Ip_u8)maxTxSAs) {
|
|
if (ipmacsec_lmi_secy_sa_descriptor_init(&sa_desc, my_sci, an, IPMACSEC_TX, ref, &key_desc.key_id) == IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA descriptor for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* For an invalid AN, we need to do it manually since ipmacsec_lmi_secy_sa_descriptor_init() does not allow it */
|
|
IPMACSEC_COPY_SCI(sa_desc.sci, my_sci);
|
|
sa_desc.an = an;
|
|
sa_desc.dir = IPMACSEC_TX;
|
|
sa_desc.ref = ref;
|
|
sa_desc.key_id.val = key_desc.key_id.val;
|
|
}
|
|
|
|
/* Delete the SA */
|
|
ret = ipmacsec_lmi_secy_delete_tx_sa(lh, ifname, &sa_desc);
|
|
if (an < (Ip_u8)maxTxSAs) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to delete TX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
/* Remove the key */
|
|
ret = ipmacsec_lmi_secy_key_remove(lh, ifname, &key_desc);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to remove key with key_id 0x%llx. (ret=%d, %s).",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* Should have failed to delete 1 more SA than Max */
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success deleting TX SA with AN %u", an);
|
|
goto err_out;
|
|
}
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Retrieve TX SA list. There should be none */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving TX SA list *****",
|
|
num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_tx_sa_status(lh, ifname, -1, 0, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SA list (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
sai = (Ipmacsec_secy_sa_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (remlen != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Invalid TX SA list (sai=%p, remlen=%u).",
|
|
(void *)sai, remlen);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Verify the TX SC is not transmitting anymore */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving TX SA list *****",
|
|
num_exec_tests);
|
|
ipcom_memset(&sc_info, 0, sizeof(sc_info));
|
|
ret = ipmacsec_lmi_secy_get_tx_sc_status(lh, ifname, &sc_info);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
if (sc_info.status.tx.transmitting) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: TX SCI should not be transmitting");
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
|
|
/* Retrieve the max # of RX SCs */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving max # of supported RX SCs *****", num_exec_tests);
|
|
ret = ipmacsec_lmi_secy_get_maxRxSCs(lh, ifname, &maxRxSCs);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
if (maxRxSCs != IPMACSEC_MAX_RX_SC) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Invalid maxTxSAs=%u (!= %u).", maxRxSCs, IPMACSEC_MAX_RX_SC);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Create and verify maxRxSCs RX SCs + 1 (last one should fail) */
|
|
for (sc=1; sc <= maxRxSCs+1; sc++) {
|
|
Ip_u8 rx_sci[IPMACSEC_SCI_LEN];
|
|
num_exec_tests++;
|
|
if (sc < maxRxSCs+1)
|
|
IPCOM_LOG2(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Creating RX SC #%u *****", num_exec_tests, sc);
|
|
else
|
|
IPCOM_LOG2(INFO,
|
|
"***** IPMACSEC-SC_SA_TEST: Executing test #%u: Trying to create one more RX SC that suported (#%u should fail) *****",
|
|
num_exec_tests, sc);
|
|
ipcom_memset(rx_sci, (Ip_u8)sc, IPMACSEC_SCI_LEN);
|
|
ret = ipmacsec_lmi_secy_create_rx_sc(lh, ifname, rx_sci);
|
|
if (sc < maxRxSCs+1) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to create RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success in creating RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Verify that the RX SC was created and verify some sc_info fields and stats */
|
|
num_exec_tests++;
|
|
IPCOM_LOG2(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Verifying RX SC #%u status and statistics *****",
|
|
num_exec_tests, sc);
|
|
ipcom_memset(&sc_info, 0, sizeof(sc_info));
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sc_status(lh, ifname, rx_sci, &response);
|
|
if (sc < maxRxSCs+1) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
scinf = (Ipmacsec_secy_sc_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!scinf || (remlen < sizeof(Ipmacsec_secy_sc_info))) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG4(ERR, "IPMACSEC-SC_SA_TEST: Invalid RX SC status for sc #%u (scinf=%p, remlen=%u < %u).",
|
|
sc, (void *)scinf, remlen, sizeof(Ipmacsec_secy_sc_info));
|
|
goto err_out;
|
|
}
|
|
if (ipcom_memcmp(rx_sci, scinf->sci, IPMACSEC_SCI_LEN) != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: RX SCI mismatch in sc_info for sc #%u", sc);
|
|
goto err_out;
|
|
}
|
|
if (scinf->dir != IPMACSEC_RX) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: RX SCI direction mismatch for sc #%u (%s, %u)",
|
|
sc, IPMACSEC_DIR_STRING(scinf->dir), scinf->dir);
|
|
goto err_out;
|
|
}
|
|
if (scinf->status.rx.receiving) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG0(ERR, "IPMACSEC-SC_SA_TEST: RX SCI #%u should not be receiving");
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success in retrieving RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
}
|
|
#ifdef IPMACSEC_USE_STATS
|
|
ret = ipmacsec_lmi_secy_get_rx_sc_stats(lh, ifname, &sc_stats, rx_sci);
|
|
if (sc < maxRxSCs+1) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC stats (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success in retrieving stats for RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
}
|
|
#endif
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Retrieve the max # of RX SAs */
|
|
num_exec_tests++;
|
|
IPCOM_LOG2(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving max # of supported RX SAs for SC #%u *****",
|
|
num_exec_tests, sc);
|
|
ret = ipmacsec_lmi_secy_get_maxRxKeys(lh, ifname, &maxRxSAs);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve maxRxKeys (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
if (maxRxSAs != IPMACSEC_MAX_SA) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Invalid maxRxSAs=%u (!= %u)", maxRxSAs, IPMACSEC_MAX_SA);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Create max # of RX SAs + 1, last one should fail*/
|
|
num_exec_tests++;
|
|
IPCOM_LOG3(INFO,
|
|
"***** IPMACSEC-SC_SA_TEST: Executing test #%u: Create+Get Status+Get Stats+Control %u RX SAs for SC #%u (Last one should fail) *****",
|
|
num_exec_tests, maxRxSAs+1, sc);
|
|
for (an=0; (sc < maxRxSCs+1) && (an <= (Ip_u8)maxRxSAs); an++) {
|
|
Ipmacsec_secy_key_descriptor key_desc;
|
|
Ipmacsec_secy_sa_descriptor sa_desc;
|
|
Ipmacsec_secy_sa_info sa_info;
|
|
Ip_u32 ref = (an+1)<<16;
|
|
Ip_u8 dummy_key[16];
|
|
Ip_u32 nextPN=1, lowestPN = 1;
|
|
|
|
/* Install a key */
|
|
ipcom_memset(dummy_key, 0xAE, sizeof(dummy_key));
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = (Ip_u64)((sc<<8)+an+1);
|
|
key_desc.key_size = sizeof(dummy_key);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_RECEIVE;
|
|
ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, dummy_key);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG4(ERR, "IPMACSEC-SC_SA_TEST: Failed to install key with key_id 0x%llx, keysize %u. (ret=%d, %s).",
|
|
key_desc.key_id.val, key_desc.key_size, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
|
|
/* Init the SA descriptor and info structures */
|
|
if (an < (Ip_u8)maxRxSAs) {
|
|
if (ipmacsec_lmi_secy_sa_descriptor_init(&sa_desc, rx_sci, an, IPMACSEC_RX, ref, &key_desc.key_id) == IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA descriptor for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* For an invalid AN, we need to do it manually since ipmacsec_lmi_secy_sa_descriptor_init() does not allow it */
|
|
IPMACSEC_COPY_SCI(sa_desc.sci, rx_sci);
|
|
sa_desc.an = an;
|
|
sa_desc.dir = IPMACSEC_RX;
|
|
sa_desc.ref = ref;
|
|
sa_desc.key_id.val = key_desc.key_id.val;
|
|
}
|
|
if (ipmacsec_lmi_secy_rx_sa_info_init(&sa_info, nextPN, lowestPN) == IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA info for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
nextPN = ++lowestPN;
|
|
|
|
/* Create the SA and verify you can retrieve its info and control it */
|
|
ret = ipmacsec_lmi_secy_create_rx_sa(lh, ifname, &sa_desc, &sa_info);
|
|
if (an < (Ip_u8)maxRxSAs) {
|
|
#ifdef IPMACSEC_USE_STATS
|
|
Ipmacsec_secy_sa_stats sa_stats;
|
|
#endif
|
|
Ipmacsec_secy_sa_ctrl sa_ctrl;
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to create RX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
|
|
/* Retrieve SA status, should succeed */
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sa_status(lh, ifname, rx_sci, an, ref, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to get status for RX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
sai = (Ipmacsec_secy_sa_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!sai || (remlen < sizeof(Ipmacsec_secy_sa_info))) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Invalid status for RX SA with AN %u (sai=%p, remlen=%u < %u).",
|
|
(void *)sai, remlen, sizeof(Ipmacsec_secy_sa_info));
|
|
goto err_out;
|
|
}
|
|
|
|
#ifdef IPMACSEC_USE_STATS
|
|
/* Retrieve SA staistics, should succeed */
|
|
ret = ipmacsec_lmi_secy_get_rx_sa_stats(lh, ifname, &sa_stats, rx_sci, an, ref);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to get statistics for RX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
#endif
|
|
/* Control the SA, should succeed */
|
|
if (ipmacsec_lmi_secy_rx_sa_ctrl_init(&sa_ctrl, IPMACSEC_ENABLEFLAG_ON, 2, 1) == IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA control struct for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
ret = ipmacsec_lmi_secy_control_rx_sa(lh, ifname, &sa_desc, &sa_ctrl);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to control RX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
/* RX SC should be receiving */
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sc_status(lh, ifname, rx_sci, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
scinf = (Ipmacsec_secy_sc_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!scinf || (remlen < sizeof(Ipmacsec_secy_sc_info))) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Invalid RX SC list (scinf=%p, remlen=%u < %u).",
|
|
(void *)scinf, remlen, sizeof(Ipmacsec_secy_sc_info));
|
|
goto err_out;
|
|
}
|
|
if (!scinf->status.rx.receiving) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: RX SC #%u should be receiving", sc);
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* Remove the unused key */
|
|
if (ipmacsec_lmi_secy_key_remove(lh, ifname, &key_desc) != IPMACSEC_LMIERR_NONE) {
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed in removing key with key_id 0x%llx.",
|
|
key_desc.key_id.val);
|
|
}
|
|
/* Should have failed to install 1 more SA than Max */
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success creating RX SA with AN %u", an);
|
|
goto err_out;
|
|
}
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Retrieve RX SA list. There should be exactly maxRxSAs infos */
|
|
num_exec_tests++;
|
|
IPCOM_LOG2(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving RX SA for Rx SC #%u list *****",
|
|
num_exec_tests, sc);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sa_status(lh, ifname, rx_sci, -1, 0, &response);
|
|
if (sc < maxRxSCs+1) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve RX SA list for sc #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
sai = (Ipmacsec_secy_sa_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!sai || (remlen < sizeof(Ipmacsec_secy_sa_info)*maxRxSAs)) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Invalid RX SA list (sai=%p, remlen=%u < %u).",
|
|
(void *)sai, remlen, sizeof(Ipmacsec_secy_sa_info)*maxRxSAs);
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success in retrieving RX SA list for sc #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Delete # of RX SAs + 1, last one should fail*/
|
|
num_exec_tests++;
|
|
IPCOM_LOG3(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Deleting %u RX SAs for RX SC #%u (Last one should fail) *****",
|
|
num_exec_tests, maxRxSAs+1, sc);
|
|
for (an=0; (sc < maxRxSCs+1) && (an <= (Ip_u8)maxRxSAs); an++) {
|
|
Ipmacsec_secy_key_descriptor key_desc;
|
|
Ipmacsec_secy_sa_descriptor sa_desc;
|
|
Ip_u32 ref = (an+1)<<16;
|
|
|
|
/* Init the key descriptor */
|
|
ipcom_memset(&key_desc, 0, sizeof(key_desc));
|
|
key_desc.key_id.val = (Ip_u64)((sc<<8)+an+1);
|
|
key_desc.key_type |= IPMACSEC_KEYTYPE_RECEIVE;
|
|
|
|
/* Init the SA descriptor */
|
|
if (an < (Ip_u8)maxRxSAs) {
|
|
if (ipmacsec_lmi_secy_sa_descriptor_init(&sa_desc, rx_sci, an, IPMACSEC_RX, ref, &key_desc.key_id) == IP_NULL) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Failed to initialize RX SA descriptor for AN = %u.", an);
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* For an invalid AN, we need to do it manually since ipmacsec_lmi_secy_sa_descriptor_init() does not allow it */
|
|
IPMACSEC_COPY_SCI(sa_desc.sci, rx_sci);
|
|
sa_desc.an = an;
|
|
sa_desc.dir = IPMACSEC_RX;
|
|
sa_desc.ref = ref;
|
|
sa_desc.key_id.val = key_desc.key_id.val;
|
|
}
|
|
|
|
/* Delete the SA */
|
|
ret = ipmacsec_lmi_secy_delete_rx_sa(lh, ifname, &sa_desc);
|
|
if (an < (Ip_u8)maxRxSAs) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to delete RX SA with AN %u (ret=%d, %s).",
|
|
an, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
/* Remove the key */
|
|
ret = ipmacsec_lmi_secy_key_remove(lh, ifname, &key_desc);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to remove key with key_id 0x%llx. (ret=%d, %s).",
|
|
key_desc.key_id.val, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
/* Should have failed to delete 1 more SA than Max */
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success deleting RX SA with AN %u", an);
|
|
goto err_out;
|
|
}
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Retrieve RX SA list. There should be none */
|
|
if (sc < maxRxSCs+1) {
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Retrieving RX SA list *****",
|
|
num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sa_status(lh, ifname, rx_sci, -1, 0, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve RX SA list (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
sai = (Ipmacsec_secy_sa_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (remlen != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Invalid RX SA list (sai=%p, remlen=%u).",
|
|
(void *)sai, remlen);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Verify the RX SC is not receiving anymore */
|
|
num_exec_tests++;
|
|
IPCOM_LOG2(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Verifyign RX SC #%u is not receiving *****",
|
|
num_exec_tests, sc);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sc_status(lh, ifname, rx_sci, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
scinf = (Ipmacsec_secy_sc_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!scinf || (remlen < sizeof(Ipmacsec_secy_sc_info))) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Invalid RX SC list (scinf=%p, remlen=%u < %u).",
|
|
(void *)scinf, remlen, sizeof(Ipmacsec_secy_sc_info));
|
|
goto err_out;
|
|
}
|
|
if (scinf->status.rx.receiving) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: RX SC #%u should not be receiving", sc);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
}
|
|
}
|
|
|
|
/* Retrieve RX SC list. Should be maxRxSCs */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Verifying RX SC list retrieval *****",
|
|
num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sc_status(lh, ifname, IP_NULL, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC list (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
scinf = (Ipmacsec_secy_sc_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (!scinf || (remlen < sizeof(Ipmacsec_secy_sc_info)*maxRxSCs)) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Invalid RX SC list (scinf=%p, remlen=%u < %u).",
|
|
(void *)scinf, remlen, sizeof(Ipmacsec_secy_sc_info)*maxRxSCs);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
/* Delete maxRxSCs RX SCs + 1 (last one should fail) */
|
|
for (sc=1; sc <= maxRxSCs+1; sc++) {
|
|
Ip_u8 rx_sci[IPMACSEC_SCI_LEN];
|
|
num_exec_tests++;
|
|
if (sc < maxRxSCs+1)
|
|
IPCOM_LOG2(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Deleting RX SC #%u *****", num_exec_tests, sc);
|
|
else
|
|
IPCOM_LOG2(INFO,
|
|
"***** IPMACSEC-SC_SA_TEST: Executing test #%u: Trying to delete one more RX SC that suported (#%u should fail) *****",
|
|
num_exec_tests, sc);
|
|
ipcom_memset(rx_sci, (Ip_u8)sc, IPMACSEC_SCI_LEN);
|
|
ret = ipmacsec_lmi_secy_delete_rx_sc(lh, ifname, rx_sci);
|
|
if (sc < maxRxSCs+1) {
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Failed to delete RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
} else {
|
|
if (ret == IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: Unexpected success in deleting RX SC #%u (ret=%d, %s).",
|
|
sc, ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
}
|
|
|
|
/* Retrieve RX SC list. Should be none */
|
|
num_exec_tests++;
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Executing test #%u: Verifying RX SC list retrieval returns nothing *****",
|
|
num_exec_tests);
|
|
IPMACSEC_BUF_WIPE(&response);
|
|
ret = ipmacsec_lmi_secy_get_rx_sc_status(lh, ifname, IP_NULL, &response);
|
|
if (ret != IPMACSEC_LMIERR_NONE) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG2(ERR, "IPMACSEC-SC_SA_TEST: Failed to retrieve TX SC list (ret=%d, %s).",
|
|
ret, ipmacsec_lmi_error_name(ret));
|
|
goto err_out;
|
|
}
|
|
remlen = 0;
|
|
scinf = (Ipmacsec_secy_sc_info *)ipmacsec_buf_ptr(&response, 0, &remlen);
|
|
if (remlen != 0) {
|
|
num_failed_tests++;
|
|
IPCOM_LOG1(ERR, "IPMACSEC-SC_SA_TEST: Unexpected RX SC list not empty (remlen=%u).",
|
|
remlen);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "***** IPMACSEC-SC_SA_TEST: Test #%u Successfully executed *****", num_exec_tests);
|
|
|
|
|
|
err_out:
|
|
if (num_failed_tests) {
|
|
IPCOM_LOG3(ERR, "IPMACSEC-SC_SA_TEST: COMPLETED WITH FAILURES - %u tests executed, %u failed for interface %s",
|
|
num_exec_tests, num_failed_tests, ifname);
|
|
ret = -1;
|
|
} else {
|
|
IPCOM_LOG2(INFO, "IPMACSEC-SC_SA_TEST: COMPLETED SUCCESSFULLY - %u tests executed successfully for interface %s",
|
|
num_exec_tests, ifname);
|
|
ret = 0;
|
|
}
|
|
(void)ipmacsec_lmi_handle_delete(lh);
|
|
(void)ipmacsec_nlmsg_free(&response);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_counter_format_test
|
|
*===========================================================================
|
|
* Description: Test the ipmacsec_secy_counter_format() routine
|
|
* Parameters: none
|
|
* Returns: none
|
|
*
|
|
*/
|
|
IP_GLOBAL void ipmacsec_counter_format_test(void) {
|
|
Ipmacsec_secy_counter64 count;
|
|
char str[80];
|
|
|
|
for (count=1; count < 10*IPMACSEC_SECY_COUNTER_1E;) {
|
|
ipcom_printf("count %llu = %s\n", count-1, ipmacsec_secy_counter_format(str, sizeof(str), count-1));
|
|
ipcom_printf("count %llu = %s\n", count, ipmacsec_secy_counter_format(str, sizeof(str), count));
|
|
ipcom_printf("count %llu = %s\n", count+1, ipmacsec_secy_counter_format(str, sizeof(str), count+1));
|
|
ipcom_printf("count %llu = %s\n", count+count/1000, ipmacsec_secy_counter_format(str, sizeof(str), count+count/1000));
|
|
count = count*10;
|
|
}
|
|
count = 0xFFFFFFFFFFFFFFFFULL;
|
|
ipcom_printf("max count %llu = %s\n", count, ipmacsec_secy_counter_format(str, sizeof(str), count));
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_parse_sci_string_test
|
|
*===========================================================================
|
|
* Description: Test the ipmacsec_parse_sci_string() routine
|
|
* Parameters: none
|
|
* Returns: none
|
|
*
|
|
*/
|
|
IP_GLOBAL int
|
|
ipmacsec_parse_sci_string_test(void) {
|
|
Ip_u8 sci[IPMACSEC_SCI_LEN];
|
|
Ip_u8 scival[IPMACSEC_SCI_LEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
|
int ret = -1000;
|
|
|
|
ret = ipmacsec_parse_sci_string("00-11-22-33-44-55-66-77", sci);
|
|
if ((ret < 0) || (!IPMACSEC_SCI_MATCH(sci, scival))) {
|
|
return -1;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("00:11:22:33:44:55:66:77", sci);
|
|
if ((ret < 0) || (!IPMACSEC_SCI_MATCH(sci, scival))) {
|
|
return -2;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("00 11 22 33 44 55 66 77", sci);
|
|
if ((ret < 0) || (!IPMACSEC_SCI_MATCH(sci, scival))) {
|
|
return -3;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("0011223344556677", sci);
|
|
if ((ret < 0) || (!IPMACSEC_SCI_MATCH(sci, scival))) {
|
|
return -4;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("FF-FF-FF-FF-FF-FF-FF-FF", sci);
|
|
if ((ret < 0) || (!IPMACSEC_INVALID_SCI(sci))) {
|
|
return -5;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("00*11*22*33*44*55*66*77", sci);
|
|
if (ret >= 0) {
|
|
return -6;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("00-11-22-33-44-55-66-", sci);
|
|
if (ret >= 0) {
|
|
return -7;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("00-11-22-33-44-55-66*77", sci);
|
|
if (ret >= 0) {
|
|
return -8;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("00-11-22-33-44-55-66-77-", sci);
|
|
if (ret >= 0) {
|
|
return -9;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("001122334455667", sci);
|
|
if (ret >= 0) {
|
|
return -10;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("00112233445566778", sci);
|
|
if (ret >= 0) {
|
|
return -11;
|
|
}
|
|
ret = ipmacsec_parse_sci_string("X0-00-00-00-00-00-00-00", sci);
|
|
if (ret >= 0) {
|
|
return -12;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_ucp_test
|
|
*===========================================================================
|
|
* Description: Test the MACsec SecY Uncontrolled Port reception
|
|
* Parameters: ifname - Interface bame
|
|
* num_expected_pkts - # of packets to expect before existing (0 ==> loop forever or until timeout)
|
|
* timeout - # of seconds before timing out (in seconds) (0 ==> no timeout)
|
|
* Returns: # of UCP received packets upon success, <0 on error
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_secy_ucp_test(char *ifname, Ip_u32 num_expected_pkts, Ip_u32 timeout) {
|
|
Ip_fd sock = IP_INVALID_SOCKET;
|
|
struct Ip_sockaddr_ll ll;
|
|
int ret = -1;
|
|
Ip_u8 *pkt = IP_NULL;
|
|
Ip_u32 npkts = 0, nseconds = 0;
|
|
|
|
if(!ifname || ifname[0] == 0) {
|
|
IPCOM_LOG0(ERR, "ipmacsec_secy_ucp_test :: ifname not set");
|
|
goto err_out;
|
|
}
|
|
|
|
|
|
sock = ipcom_socket(IP_PF_PACKET, IP_SOCK_RAW, IPNET_ETHFRAME_MACSEC);
|
|
if (sock == IP_INVALID_SOCKET) {
|
|
IPCOM_LOG1(ERR, "ipmacsec_secy_ucp_test :: ipcom_socket() failed, errno: %d\n", ipcom_errno);
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG1(INFO, "ipmacsec_secy_ucp_test ::opened MACsec raw socket (fd = %u)\n", sock);
|
|
|
|
ipcom_memset(&ll, 0, sizeof(ll));
|
|
ll.sll_family = IP_AF_PACKET;
|
|
ll.sll_ifindex = ipcom_if_nametoindex(ifname);
|
|
if(ll.sll_ifindex == 0) {
|
|
IPCOM_LOG1(ERR, "ipmacsec_secy_ucp_test :: ipcom_if_nametoindex failed for %s", ifname);
|
|
goto err_out;
|
|
}
|
|
|
|
/* Bind raw socket to device */
|
|
if (ipcom_setsockopt(sock, IP_SOL_SOCKET, IP_SO_BINDTODEVICE,
|
|
ifname, IP_IFNAMSIZ) == IP_SOCKERR) {
|
|
IPCOM_LOG3(ERR, "ipmacsec_secy_ucp_test :: ipcom_setsockopt(bindtodevice,%s) failed : %s [%d]",
|
|
ifname, ipcom_strerror(ipcom_errno), ipcom_errno);;
|
|
goto err_out;
|
|
}
|
|
IPCOM_LOG2(INFO, "ipmacsec_secy_ucp_test :: bound sock to %s (index %u)", ifname, ll.sll_ifindex);
|
|
|
|
pkt = ipcom_malloc(1514);
|
|
if (!pkt) {
|
|
IPCOM_LOG0(ERR, "ipmacsec_secy_ucp_test :: failed to allocate packet");
|
|
goto err_out;
|
|
}
|
|
while(1) {
|
|
int rc;
|
|
Ip_fd_set rset;
|
|
struct Ip_timeval tv;
|
|
|
|
IP_FD_ZERO(&rset);
|
|
IP_FD_SET(sock, &rset);
|
|
tv.tv_sec = 1;
|
|
tv.tv_usec = 0;
|
|
IPCOM_LOG1(DEBUG2, "ipmacsec_secy_ucp_test :: blocking on socket %u", sock);
|
|
ret = ipcom_socketselect(sock + 1, &rset, IP_NULL, IP_NULL, &tv);
|
|
if (ret < 0) {
|
|
IPCOM_LOG1(ERR, "ipmacsec_secy_ucp_test :: ipcom_socketselect failed (%d)", rc);
|
|
goto err_out;
|
|
}
|
|
if (ret == 0) {
|
|
nseconds++;
|
|
}
|
|
while (ret) {
|
|
rc = ipcom_recvfrom(sock, pkt, 1514, 0, IP_NULL, IP_NULL);
|
|
if (rc <= 0) {
|
|
IPCOM_LOG1(ERR, "ipmacsec_secy_ucp_test :: ipcom_recvfrom failed (%d)", rc);
|
|
goto err_out;
|
|
}
|
|
npkts++;
|
|
ret--;
|
|
IPCOM_LOG2(DEBUG2, "ipmacsec_secy_ucp_test ::rc = %d on socket %u", rc, sock);
|
|
ipmacsec_dump_buffer("MACsec received frame: ", pkt, rc);
|
|
}
|
|
if (num_expected_pkts && (npkts >= num_expected_pkts)) {
|
|
break;
|
|
}
|
|
if (timeout && (nseconds >= timeout))
|
|
break;
|
|
}
|
|
ret = npkts;
|
|
|
|
err_out:
|
|
if(sock != IP_INVALID_SOCKET) {
|
|
ipcom_socketclose(sock);
|
|
sock = IP_INVALID_SOCKET;
|
|
}
|
|
if (pkt) {
|
|
ipcom_free(pkt);
|
|
pkt = IP_NULL;
|
|
}
|
|
IPCOM_LOG1(INFO, "ipmacsec_secy_ucp_test :: Exiting (ret = %d)", ret);
|
|
return ret;
|
|
}
|
|
|
|
/* Variable used to store # of pkts received by the MACsec SecY Uncontrolled Port reception daemon */
|
|
IP_STATIC int ucp_test_daemon_nrcv_pkts = 0;
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_ucp_testd
|
|
*===========================================================================
|
|
* Description: MACsec SecY Uncontrolled Port reception test daemon
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC
|
|
IPCOM_PROCESS(ipmacsec_secy_ucp_testd) {
|
|
char ifname[IP_IFNAMSIZ];
|
|
Ip_size_t len;
|
|
Ip_u32 num_expected_pkts;
|
|
Ip_u32 timeout;
|
|
char strval[16];
|
|
char *sysvar;
|
|
|
|
IPCOM_LOG0(DEBUG2, "ipmacsec_secy_ucp_testd :: Started");
|
|
ucp_test_daemon_nrcv_pkts = -1;
|
|
|
|
ipcom_proc_init();
|
|
|
|
sysvar = "ipmacsec.secy.ut.ucptestd.ifname";
|
|
len = IP_IFNAMSIZ;
|
|
if (ipcom_sysvar_get(sysvar, ifname, &len) == IP_NULL) {
|
|
IPCOM_LOG1(WARNING, "ipmacsec_secy_ucp_testd :: Failed to get sysvar %s", sysvar);
|
|
goto exit;
|
|
}
|
|
|
|
sysvar = "ipmacsec.secy.ut.ucptestd.npkts";
|
|
len = sizeof(strval);
|
|
if (ipcom_sysvar_get(sysvar, strval, &len) == IP_NULL) {
|
|
IPCOM_LOG1(WARNING, "ipmacsec_secy_ucp_testd :: Failed to get sysvar %s", sysvar);
|
|
goto exit;
|
|
}
|
|
num_expected_pkts = ipcom_atoi(strval);
|
|
|
|
sysvar = "ipmacsec.secy.ut.ucptestd.timeout";
|
|
len = sizeof(strval);
|
|
if (ipcom_sysvar_get(sysvar, strval, &len) == IP_NULL) {
|
|
IPCOM_LOG1(WARNING, "ipmacsec_secy_ucp_testd :: Failed to get sysvar %s", sysvar);
|
|
goto exit;
|
|
}
|
|
timeout = ipcom_atoi(strval);
|
|
|
|
ucp_test_daemon_nrcv_pkts = ipmacsec_secy_ucp_test(ifname, num_expected_pkts, timeout);
|
|
|
|
exit:
|
|
IPCOM_LOG1(DEBUG2, "ipmacsec_secy_ucp_testd :: Exiting (ucp_test_daemon_nrcv_pkts = %d)", ucp_test_daemon_nrcv_pkts);
|
|
ipcom_proc_exit();
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_ucp_test_start_daemon
|
|
*===========================================================================
|
|
* Description: Start a MACsec SecY Uncontrolled Port reception test daemon
|
|
* Should only start one daemon at a time.
|
|
* Parameters: ifname - Interface bame
|
|
* num_expected_pkts - # of packets to expect before existing (0 ==> loop forever or until timeout)
|
|
* timeout - # of seconds before timing out (in seconds) (0 ==> no timeout)
|
|
* Returns: 0 upon successfully starting the daemon, <0 on error
|
|
*
|
|
*/
|
|
IP_GLOBAL int ipmacsec_secy_ucp_test_start_daemon(char *ifname, Ip_u32 num_expected_pkts, Ip_u32 timeout) {
|
|
Ipcom_proc_attr proc_attr;
|
|
char strval[16];
|
|
char *sysvar;
|
|
Ip_err rc;
|
|
|
|
sysvar = "ipmacsec.secy.ut.ucptestd.ifname";
|
|
if ((rc = ipcom_sysvar_set(sysvar, ifname, IPCOM_SYSVAR_FLAG_OVERWRITE)) != IPCOM_SUCCESS) {
|
|
IPCOM_LOG1(CRIT, "ipmacsec_secy_ucp_testd :: Failed to set sysvar %s", sysvar);
|
|
return rc;
|
|
}
|
|
|
|
ipcom_snprintf(strval, sizeof(strval), "%d", num_expected_pkts);
|
|
sysvar = "ipmacsec.secy.ut.ucptestd.npkts";
|
|
if ((rc = ipcom_sysvar_set(sysvar, strval, IPCOM_SYSVAR_FLAG_OVERWRITE)) != IPCOM_SUCCESS) {
|
|
IPCOM_LOG1(CRIT, "ipmacsec_secy_ucp_testd :: Failed to set sysvar %s", sysvar);
|
|
return rc;
|
|
}
|
|
|
|
ipcom_snprintf(strval, sizeof(strval), "%d", timeout);
|
|
sysvar = "ipmacsec.secy.ut.ucptestd.timeout";
|
|
if ((rc = ipcom_sysvar_set(sysvar, strval, IPCOM_SYSVAR_FLAG_OVERWRITE)) != IPCOM_SUCCESS) {
|
|
IPCOM_LOG1(CRIT, "ipmacsec_secy_ucp_testd :: Failed to set sysvar %s", sysvar);
|
|
return rc;
|
|
}
|
|
|
|
ipcom_proc_attr_init(&proc_attr);
|
|
proc_attr.stacksize = IPCOM_PROC_STACK_SMALL;
|
|
rc = ipcom_proc_acreate("secy_ucp_testd", ipmacsec_secy_ucp_testd, &proc_attr, IP_NULL);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_secy_ucp_test_daemon_num_rcv_pkts
|
|
*===========================================================================
|
|
* Description: Return the # of pkts received by the MACsec SecY Uncontrolled Port reception daemon
|
|
* Parameters: None
|
|
* Returns: # of pkts rcvd
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_u32 ipmacsec_secy_ucp_test_daemon_num_rcv_pkts(void) {
|
|
return ucp_test_daemon_nrcv_pkts;
|
|
}
|
|
|
|
|
|
/* UNIT TEST CODE FOR EASILY SETTING UP SECY CONFIGURATION */
|
|
Ipmacsec_secy_profile *Ipmacsec_secy_ut_profiles[] = {
|
|
&ipmacsec_ut_profile_1A,
|
|
&ipmacsec_ut_profile_1B,
|
|
&ipmacsec_ut_profile_2A,
|
|
&ipmacsec_ut_profile_2B,
|
|
&ipmacsec_ut_profile_3A,
|
|
&ipmacsec_ut_profile_3B
|
|
};
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmacsec_lmi_secy_setup_ut_profile
|
|
*===========================================================================
|
|
* Description: Setup the specified Unit Test SecY profile
|
|
* Parameters: ifname - Interface bame
|
|
* ut_profile_index - Index of the unit test profile to setup
|
|
* Returns: IPMACSEC_LMIERR_NONE upon success,
|
|
* an Ipmacsec_lmi_error <0 upon error
|
|
*
|
|
*/
|
|
IP_GLOBAL Ipmacsec_lmi_error
|
|
ipmacsec_lmi_secy_setup_ut_profile(char *ifname, Ip_u8 ut_profile_index) {
|
|
if (ut_profile_index >= sizeof(Ipmacsec_secy_ut_profiles)/sizeof(Ipmacsec_secy_profile *)) {
|
|
return IPMACSEC_LMIERR_INVALID_PARAMETER;
|
|
}
|
|
return ipmacsec_lmi_secy_setup_profile(ifname, Ipmacsec_secy_ut_profiles[ut_profile_index]);
|
|
}
|
|
#endif
|
|
|