/* ipmacsec_lmi.c - MACsec LMI 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,15feb10,mry Created */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* * Implements MACsec Layer Management Interface (LMI), which provides the * public API for MACsec which can be used by the Key Agreement Entity (KaY), * MACsec command module, network management, or other 3rd party software. * */ /* **************************************************************************** * 2 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include "ipmacsec_debug.h" #include "ipmacsec_h.h" #include "ipmacsec_lmi.h" #include "ipmacsec_ioctl.h" #include "ipmacsec_netlink.h" #include "ipmacsec_crypto_if.h" #include "ipmacsec_sysvar.h" /* **************************************************************************** * 3 CONFIGURATION **************************************************************************** */ #include "ipmacsec_config.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER "----------------------------------------\n" #define IPMACSEC_LMI_SECY_PRINT_KEY_DELIMITER "----------------------------------------\n" #define IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER "----------------------------------------\n" #define IPMACSEC_LMI_SECY_PRINT_SA_DELIMITER "----------------------------------------\n" #define IPMACSEC_LMI_SECY_DUMP_DELIMITER "********************************************************************************\n" #define IPMACSEC_LMI_SECY_DUMP_INDENT1 " " #define IPMACSEC_LMI_SECY_DUMP_INDENT2 " " #define IPMACSEC_LMI_SECY_DUMP_INDENT3 " " #define IPMACSEC_LMI_MONITOR_OUT_PRIFIX " ^" #define IPMACSEC_LMI_MONITOR_OUT_INDENT1 "-" #define IPMACSEC_LMI_MONITOR_OUT_INDENT2 "--" #define IPMACSEC_LMI_MONITOR_OUT_INDENT3 "---" /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ IP_STATIC int ipmacsec_lmi_monitor_callback(struct Ip_nlmsghdr *nlmsg, int error); IP_STATIC int ipmacsec_lmi_secy_get_sa_status(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, int an, Ip_u32 ref, Ipmacsec_dir dir, Ipmacsec_buffer *info); #ifdef IPMACSEC_USE_STATS IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_dump_sa_stats(Ipmacsec_secy_sa_stats *sa_stats, Ipmacsec_dir dir); IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_dump_sc_stats(Ipmacsec_secy_sc_stats *sc_stats, Ipmacsec_dir dir); #endif IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_sa_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, Ip_u8 an, Ip_u32 ref, Ipmacsec_dir dir); IP_STATIC int ipmacsec_lmi_secy_print_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, int an, Ip_u32 ref, Ipmacsec_dir dir, IP_CONST char *prefix, Ip_bool display_stats); IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_rx_sc_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci); IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_tx_sc_stats(IPMACSEC_LMI_HANDLE lh, char *ifname); IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_secy_cp_get_cmd_bool(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_lmi_command cmd, Ip_bool *boolval, Ip_bool cp); /* * **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmacsec_lmi_monitor_callback *=========================================================================== * Description: Handles callbacks from the LMI monitor loop and prints out * detailed description of received notifications. * Parameters: * Returns: * */ IP_STATIC int ipmacsec_lmi_monitor_callback(struct Ip_nlmsghdr *nlmsg, int error) { Ipmacsec_nlnote_hdr *nlnote; ipcom_printf("IPMACSEC-LMI-MONITOR:\n"); if (error < 0) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Error occured (%d)\n", error); return 0; } else if (error > 0) { /* Timeout or exit */ if (nlmsg == IP_NULL) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Timeout occured (%d)\n", error); } else { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Exit signal received (%d)\n", error); } return -1; } /* error == 0 ==> must have a notification */ ip_assert(nlmsg); ip_assert(nlmsg->nlmsg_len); if (nlmsg->nlmsg_type != IPMACSEC_NLTYPE_NOTIFY) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Unexpected netlink message #%u: \n" IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT1 "type %u (%s)\n", nlmsg->nlmsg_seq, nlmsg->nlmsg_type, ipmacsec_netlink_type_name(nlmsg->nlmsg_type)); return 0; } /* Print detailed contents of notification */ nlnote = ipmacsec_nlnote_get(nlmsg); if (nlnote == IP_NULL) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Invalid notification\n"); return 0; } switch (nlnote->note) { case IPMACSEC_LMINOTE_STATUS: { Ipmacsec_secy_status status; Ipmacsec_secy_sa_descriptor sa_desc; Ipmacsec_secy_sa_info sa_info; (void)ipmacsec_nlnote_retrieve_init(nlmsg); if (ipmacsec_nlnote_retrieve_param(nlmsg, &status, sizeof(status)) < (int)sizeof(status)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Interface %s - STATUS notification #%u: \n" IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT1 "Invalid STATUS notification parameter\n", nlnote->ifname, nlmsg->nlmsg_seq); return 0; } /* Parse any additional Params */ if ((status == IPMACSEC_STATUS_SECY_PN_NEARLY_EXHAUSTED) || (status == IPMACSEC_STATUS_SECY_PN_EXHAUSTED)) { if (ipmacsec_nlnote_retrieve_param(nlmsg, &sa_desc, sizeof(sa_desc)) < (int)sizeof(sa_desc)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Interface %s - STATUS notification #%u: \n" IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT1 "Incomplete STATUS notification %s (%u) (sa descriptor missing)\n", nlnote->ifname, nlmsg->nlmsg_seq, ipmacsec_secy_status_name(status), status); return 0; } } if (status == IPMACSEC_STATUS_SECY_PN_NEARLY_EXHAUSTED) { if (ipmacsec_nlnote_retrieve_param(nlmsg, &sa_info, sizeof(sa_info)) < (int)sizeof(sa_info)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Interface %s - STATUS notification #%u: \n" IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT1 "Incomplete STATUS notification %s (%u) (sa info missing)\n", nlnote->ifname, nlmsg->nlmsg_seq, ipmacsec_secy_status_name(status), status); return 0; } } /* Print results */ ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Interface %s - STATUS Notification #%u: \n" IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT1 "%s (%d)\n", nlnote->ifname, nlmsg->nlmsg_seq, ipmacsec_secy_status_name(status), status); if ((status == IPMACSEC_STATUS_SECY_PN_NEARLY_EXHAUSTED) || (status == IPMACSEC_STATUS_SECY_PN_EXHAUSTED)) { char str[IPMACSEC_DISPLAY_BUF_LEN]; ipmacsec_lmi_strf_sa_desc(&sa_desc, IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2, str, sizeof(str)); ipcom_printf("%s", str); } if (status == IPMACSEC_STATUS_SECY_PN_NEARLY_EXHAUSTED) { char str[IPMACSEC_DISPLAY_BUF_LEN]; ipmacsec_lmi_strf_sa_info(&sa_info, sa_desc.dir, IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2, str, sizeof(str)); ipcom_printf("%s", str); } break; } case IPMACSEC_LMINOTE_INFO: { Ipmacsec_secy_info info; (void)ipmacsec_nlnote_retrieve_init(nlmsg); if (ipmacsec_nlnote_retrieve_param(nlmsg, &info, sizeof(info)) < (int)sizeof(info)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Interface %s - Invalid INFO notification parameter\n", nlnote->ifname); return 0; } ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Interface %s - INFO Notification #%u: \n" IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT1 "%s (%u)\n", nlnote->ifname, nlmsg->nlmsg_seq, ipmacsec_secy_info_name(info), info); if ((info == IPMACSEC_INFO_SECY_SC_CREATED) || (info == IPMACSEC_INFO_SECY_SC_STATUS_CHANGED)) { Ipmacsec_secy_sc_info sc_info; char str[IPMACSEC_DISPLAY_BUF_LEN]; if (ipmacsec_nlnote_retrieve_param(nlmsg, &sc_info, sizeof(sc_info)) < (int)sizeof(sc_info)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "Incomplete notification (sc info missing)\n"); return 0; } ipmacsec_lmi_strf_sc_info(&sc_info, IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2, str, sizeof(str)); ipcom_printf("%s", str); return 0; } if (info == IPMACSEC_INFO_SECY_SC_DELETED) { Ip_u8 sci[IPMACSEC_SCI_LEN]; if (ipmacsec_nlnote_retrieve_param(nlmsg, sci, sizeof(sci)) < (int)sizeof(sci)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "Incomplete notification (sci missing)\n"); return 0; } ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "sci: " IPMACSEC_SCI_STRING "\n", IPMACSEC_SCI_OCTETS(sci)); return 0; } if ((info == IPMACSEC_INFO_SECY_SA_CREATED) || (info == IPMACSEC_INFO_SECY_SA_STATUS_CHANGED) || (info == IPMACSEC_INFO_SECY_SA_DELETED)) { Ipmacsec_secy_sa_descriptor sa_desc; Ipmacsec_secy_sa_info sa_info; Ipmacsec_secy_sa_ctrl sa_ctrl; char str[IPMACSEC_DISPLAY_BUF_LEN]; if (ipmacsec_nlnote_retrieve_param(nlmsg, &sa_desc, sizeof(sa_desc)) < (int)sizeof(sa_desc)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "Incomplete notification (sa descriptor missing)\n"); return 0; } ipmacsec_lmi_strf_sa_desc(&sa_desc, IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2, str, sizeof(str)); ipcom_printf("%s", str); if ((info == IPMACSEC_INFO_SECY_SA_CREATED) || (info == IPMACSEC_INFO_SECY_SA_STATUS_CHANGED)) { if (ipmacsec_nlnote_retrieve_param(nlmsg, &sa_info, sizeof(sa_info)) < (int)sizeof(sa_info)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "Incomplete notification (sa info missing)\n"); return 0; } ipmacsec_lmi_strf_sa_info(&sa_info, sa_desc.dir, IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2, str, sizeof(str)); ipcom_printf("%s", str); } if ((info == IPMACSEC_INFO_SECY_SA_STATUS_CHANGED)) { if (ipmacsec_nlnote_retrieve_param(nlmsg, &sa_ctrl, sizeof(sa_ctrl)) < (int)sizeof(sa_ctrl)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "Incomplete notification (sa ctrl missing)\n"); return 0; } ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "SA Control:\n"); ipmacsec_lmi_strf_sa_ctrl(&sa_ctrl, sa_desc.dir, IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT3, str, sizeof(str)); ipcom_printf("%s", str); } } if ((info == IPMACSEC_INFO_SECY_KEY_INSTALLED) || (info == IPMACSEC_INFO_SECY_KEY_REMOVED)) { Ipmacsec_secy_key_descriptor key_desc; char str[IPMACSEC_DISPLAY_BUF_LEN]; if (ipmacsec_nlnote_retrieve_param(nlmsg, &key_desc, sizeof(key_desc)) < (int)sizeof(key_desc)) { ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2 "Incomplete notification (key descriptor missing)\n"); return 0; } ipmacsec_lmi_strf_key_desc(&key_desc, IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT2, str, sizeof(str)); ipcom_printf("%s", str); } break; } default: ipcom_printf(IPMACSEC_LMI_MONITOR_OUT_PRIFIX "Interface %s - Unexpected notification #%u: \n" IPMACSEC_LMI_MONITOR_OUT_PRIFIX IPMACSEC_LMI_MONITOR_OUT_INDENT1 "%u (%s)\n", nlnote->ifname, nlmsg->nlmsg_seq, nlnote->note, ipmacsec_lmi_note_name(nlnote->note)); break; } return 0; } /* *=========================================================================== * ipmacsec_lmi_secy_get_sa_status *=========================================================================== * Description: Retrieves SA Status info for a single SA or all SAs (if an < 0). * Parameters: * Returns: * */ IP_STATIC int ipmacsec_lmi_secy_get_sa_status(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, int an, Ip_u32 ref, Ipmacsec_dir dir, Ipmacsec_buffer *info) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_command cmd = __IPMACSEC_LMICMD_NONE; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !info || (an >= IPMACSEC_MAX_SA)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if ((dir == IPMACSEC_RX) && !sci) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } 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; } if (an < 0) { cmd = ((dir == IPMACSEC_RX) ? IPMACSEC_LMICMD_SECY_RX_SA_LIST : IPMACSEC_LMICMD_SECY_TX_SA_LIST); ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, cmd, (sci ? sci : IP_NULL), (sci ? IPMACSEC_SCI_LEN : 0)); } else { Ipmacsec_secy_sa_descriptor sa_desc; cmd = ((dir == IPMACSEC_RX) ? IPMACSEC_LMICMD_SECY_RX_SA_STATUS : IPMACSEC_LMICMD_SECY_TX_SA_STATUS); ipcom_memset(&sa_desc, 0, sizeof(sa_desc)); if (sci) IPMACSEC_COPY_SCI(sa_desc.sci, sci); sa_desc.dir = dir; sa_desc.an = (Ip_u8)an; sa_desc.ref = ref; ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, cmd, &sa_desc, sizeof(sa_desc)); } if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } if (an < 0) { ret = ipmacsec_lmi_cmd_parse_response_pbuf(&response, ifname, cmd, info); } else { struct { Ipmacsec_secy_sa_descriptor sa_desc; Ipmacsec_secy_sa_info sa_info; Ipmacsec_secy_sa_ctrl sa_ctrl; } param; ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, cmd, ¶m, sizeof(param)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } (void)ipmacsec_buf_append(info, (Ip_u8 *)¶m, sizeof(param)); ret = IPMACSEC_LMIERR_NONE; /* Even if we fail to append, we still succeed since we got info back and * caller may not have supplied enough buffer space (intentionally or not) */ } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } #ifdef IPMACSEC_USE_STATS /* *=========================================================================== * ipmacsec_lmi_secy_dump_sa_stats *=========================================================================== * Description: Dumps (to stdout) the specified SA Statistics * Parameters: * Returns: * */ IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_dump_sa_stats(Ipmacsec_secy_sa_stats *sa_stats, Ipmacsec_dir dir) { ip_assert(sa_stats); if (dir == IPMACSEC_TX) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Generartion stats:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "-----------------\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "OutPktsProtected: %llu, ", sa_stats->tx.OutPktsProtected); ipcom_printf( "OutPktsEncrypted: %llu", sa_stats->tx.OutPktsEncrypted); ipcom_printf("\n"); } if (dir == IPMACSEC_RX) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Verification stats:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "------------------\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsOK: %llu, ", sa_stats->rx.InPktsOK); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsInvalid: %llu, ", sa_stats->rx.InPktsInvalid); ipcom_printf( "InPktsNotValid: %llu, ", sa_stats->rx.InPktsNotValid); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsNotUsingSA: %llu, ", sa_stats->rx.InPktsNotUsingSA); ipcom_printf( "InPktsUnusedSA: %llu", sa_stats->rx.InPktsUnusedSA); ipcom_printf("\n"); } return IPMACSEC_LMIERR_NONE; } /* *=========================================================================== * ipmacsec_lmi_secy_dump_sc_stats *=========================================================================== * Description: Dumps (to stdout) the specified SC Statistics * Parameters: * Returns: * */ IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_dump_sc_stats(Ipmacsec_secy_sc_stats *sc_stats, Ipmacsec_dir dir) { ip_assert(sc_stats); (void)ipmacsec_lmi_secy_dump_sa_stats(&sc_stats->aggr, dir); if (dir == IPMACSEC_RX) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsUnchecked: %llu, ", sc_stats->in.InPktsUnchecked); ipcom_printf( "InPktsDelayed: %llu, ", sc_stats->in.InPktsDelayed); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsLate: %llu", sc_stats->in.InPktsLate); ipcom_printf("\n"); } return IPMACSEC_LMIERR_NONE; } #endif /* *=========================================================================== * ipmacsec_lmi_secy_print_sa_stats *=========================================================================== * Description: Dumps (to stdout) the specified SA Statistics * Parameters: * Returns: * */ IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_sa_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, Ip_u8 an, Ip_u32 ref, Ipmacsec_dir dir) { #ifdef IPMACSEC_USE_STATS Ipmacsec_secy_sa_stats sa_stats; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; ipcom_memset(&sa_stats, 0, sizeof(sa_stats)); /* retrieve stats */ if (dir == IPMACSEC_TX) { ret = ipmacsec_lmi_secy_get_tx_sa_stats(lh, ifname, &sa_stats, an, ref); } else { ip_assert(sci); ret = ipmacsec_lmi_secy_get_rx_sa_stats(lh, ifname, &sa_stats, sci, an, ref); } if (ret != IPMACSEC_LMIERR_NONE) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "*** Failed to retrieve stats ***\n"); goto err_out; } (void)ipmacsec_lmi_secy_dump_sa_stats(&sa_stats, dir); err_out: ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); return IPMACSEC_LMIERR_NONE; #else IPCOM_UNUSED_ARG(lh); IPCOM_UNUSED_ARG(ifname); IPCOM_UNUSED_ARG(sci); IPCOM_UNUSED_ARG(an); IPCOM_UNUSED_ARG(ref); IPCOM_UNUSED_ARG(dir); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "*** SECY Statistics Gathering Disabled ***\n"); return IPMACSEC_LMIERR_NOT_SUPPORTED; #endif } /* *=========================================================================== * ipmacsec_lmi_secy_print_sa *=========================================================================== * Description: Dumps (to stdout) the specified SA's (or if an < 0, all SAs') * status info and Statistics * Parameters: * Returns: * */ IP_STATIC int ipmacsec_lmi_secy_print_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, int an, Ip_u32 ref, Ipmacsec_dir dir, IP_CONST char *prefix, Ip_bool display_stats) { Ipmacsec_buffer info; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; char str[IPMACSEC_DISPLAY_BUF_LEN]; IP_CONST char *pref = (prefix ? prefix : ""); Ip_u32 saNum = 0, remlen = 0, offset = 0; /* Allocate enough buffer space for key descriptors */ IPMACSEC_BUF_INIT(&info); if (ipmacsec_nlmsg_alloc(&info) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (dir == IPMACSEC_TX) { ret = ipmacsec_lmi_secy_get_tx_sa_status(lh, ifname, an, ref, &info); } else { ret = ipmacsec_lmi_secy_get_rx_sa_status(lh, ifname, sci, an, ref, &info); } if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } for (saNum=0,offset=0;;saNum++) { struct sa_status_param { Ipmacsec_secy_sa_descriptor sa_desc; Ipmacsec_secy_sa_info sa_info; Ipmacsec_secy_sa_ctrl sa_ctrl; } *param; param = (struct sa_status_param *)ipmacsec_buf_ptr(&info, offset, &remlen); offset+=(Ip_u32)sizeof(struct sa_status_param); if (!param || (remlen < (int)sizeof(struct sa_status_param))) break; ipmacsec_lmi_strf_sa_desc(¶m->sa_desc, pref, str, sizeof(str)); ipcom_printf("%s", str); ipmacsec_lmi_strf_sa_info(¶m->sa_info, dir, pref, str, sizeof(str)); ipcom_printf("%s", str); ipcom_printf("%sSA Control:\n" "%s----------\n", pref, pref); ipmacsec_lmi_strf_sa_ctrl(¶m->sa_ctrl, dir, pref, str, sizeof(str)); ipcom_printf("%s", str); if (display_stats) { ipcom_printf("\n"); (void)ipmacsec_lmi_secy_print_sa_stats(lh, ifname, sci, param->sa_desc.an, param->sa_desc.ref, dir); } ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SA_DELIMITER, pref); } err_out: if (saNum==0) { ipcom_printf("%s*** No %s SAs found ***\n", pref, IPMACSEC_DIR_STRING(dir)); ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SA_DELIMITER, pref); } ipmacsec_nlmsg_free(&info); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_print_rx_sc_stats *=========================================================================== * Description: Dumps (to stdout) the specified RX SC's Statistics * Parameters: * Returns: * */ IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_rx_sc_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci) { #ifdef IPMACSEC_USE_STATS Ipmacsec_secy_sc_stats sc_stats; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; ipcom_memset(&sc_stats, 0, sizeof(sc_stats)); /* retrieve stats */ ret = ipmacsec_lmi_secy_get_rx_sc_stats(lh, ifname, &sc_stats, sci); if (ret != IPMACSEC_LMIERR_NONE) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "*** Failed to retrieve stats ***\n"); goto err_out; } (void)ipmacsec_lmi_secy_dump_sc_stats(&sc_stats, IPMACSEC_RX); err_out: ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); return IPMACSEC_LMIERR_NONE; #else IPCOM_UNUSED_ARG(lh); IPCOM_UNUSED_ARG(ifname); IPCOM_UNUSED_ARG(sci); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "*** SECY Statistics Gathering Disabled ***\n"); return IPMACSEC_LMIERR_NOT_SUPPORTED; #endif } /* *=========================================================================== * ipmacsec_lmi_secy_print_tx_sc_stats *=========================================================================== * Description: Dumps (to stdout) the TX SC's Statistics * Parameters: * Returns: * */ IP_STATIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_tx_sc_stats(IPMACSEC_LMI_HANDLE lh, char *ifname) { #ifdef IPMACSEC_USE_STATS Ipmacsec_secy_sc_stats sc_stats; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; ipcom_memset(&sc_stats, 0, sizeof(sc_stats)); /* retrieve stats */ ret = ipmacsec_lmi_secy_get_tx_sc_stats(lh, ifname, &sc_stats); if (ret != IPMACSEC_LMIERR_NONE) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "*** Failed to retrieve stats ***\n"); goto err_out; } (void)ipmacsec_lmi_secy_dump_sc_stats(&sc_stats, IPMACSEC_TX); err_out: ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); return IPMACSEC_LMIERR_NONE; #else IPCOM_UNUSED_ARG(lh); IPCOM_UNUSED_ARG(ifname); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "*** SECY Statistics Gathering Disabled ***\n"); return IPMACSEC_LMIERR_NOT_SUPPORTED; #endif } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmacsec_lmi_secy_cp_get_cmd_bool *=========================================================================== * Description: Retrieve a SecY Controlled or Uncontrolled port boolean * control value. * Parameters: * Returns: * */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_secy_cp_get_cmd_bool(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_lmi_command cmd, Ip_bool *boolval, Ip_bool cp) { Ipmacsec_buffer request, response; Ip_bool val = cp; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !boolval) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } /* Verify it is a command that takes bool params */ if ((cmd != IPMACSEC_LMICMD_PORT_MAC_ENABLED) && (cmd != IPMACSEC_LMICMD_PORT_MAC_OPER) && (cmd != IPMACSEC_LMICMD_PORT_OPER_PTP_MAC)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } *boolval = IP_FALSE; ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, cmd, &val, sizeof(val)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, cmd, &val, sizeof(val)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } *boolval = val; err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_parse_sci_string *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL int ipmacsec_parse_sci_string(IP_CONST char *sci_string, Ip_u8 *sci) { Ip_u8 sci_val[IPMACSEC_SCI_LEN]; Ip_u8 i, separator = IP_NULL; Ip_u32 len, off; if (!sci_string || !sci) { return -1; } IPMACSEC_INVALIDATE_SCI(sci); len = (Ip_u32)ipcom_strlen(sci_string); for (i = 0, off=0; i < IPMACSEC_SCI_LEN; i++) { IP_STATIC Ip_u8 octetlo, octethi; IP_STATIC Ip_u8 char1=IP_NULL, char2=IP_NULL, char3=IP_NULL; char1 = sci_string[off]; char2 = sci_string[++off]; char3 = sci_string[++off]; if (off > len) return -2; if (!ipcom_isxdigit(char1) || !isxdigit(char2)) { return -3; } octethi = (Ip_u8)(ipcom_isdigit(char1) ? (char1-'0') : (ipcom_toupper(char1)-'A'+0xa)); octetlo = (Ip_u8)(ipcom_isdigit(char2) ? (char2-'0') : (ipcom_toupper(char2)-'A'+0xa)); sci_val[i] = (Ip_u8)((octethi << 4) | octetlo); if (i==0) { if (ipcom_isxdigit(char3)) separator = IP_NULL; else if (char3 == '-') separator = '-'; else if (char3 == ':') separator = ':'; else if (char3 == ' ') separator = ' '; else return -4; } else if (i == IPMACSEC_SCI_LEN-1) { if (char3 != '\0') return -5; continue; } else if ((separator != IP_NULL) && (char3 != separator)) { return -6; } if (separator != IP_NULL) off++; } IPMACSEC_COPY_SCI(sci, sci_val); return 0; } /* *=========================================================================== * ipmacsec_secy_counter_format *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_secy_counter_format(char *buf, int len, Ipmacsec_secy_counter64 count) { Ipmacsec_secy_counter64 remainder; ip_assert(buf); ip_assert(len); if (count < IPMACSEC_SECY_COUNTER_1K) { snprintf(buf, len, "%llu", count); } else if (count >= IPMACSEC_SECY_COUNTER_1E) { remainder = count%IPMACSEC_SECY_COUNTER_1E; if (remainder==0) snprintf(buf, len, "%lluE", count/IPMACSEC_SECY_COUNTER_1E); else snprintf(buf, len, "%llu.%0.3lluE", count/IPMACSEC_SECY_COUNTER_1E, (remainder/IPMACSEC_SECY_COUNTER_1P)); } else if (count >= IPMACSEC_SECY_COUNTER_1P) { remainder = count%IPMACSEC_SECY_COUNTER_1P; if (remainder==0) snprintf(buf, len, "%lluP", count/IPMACSEC_SECY_COUNTER_1P); else snprintf(buf, len, "%llu.%0.3lluP", count/(IPMACSEC_SECY_COUNTER_1P), (remainder/IPMACSEC_SECY_COUNTER_1T)); } else if (count >= IPMACSEC_SECY_COUNTER_1T) { remainder = count%IPMACSEC_SECY_COUNTER_1T; if (remainder==0) snprintf(buf, len, "%lluT", count/IPMACSEC_SECY_COUNTER_1T); else snprintf(buf, len, "%llu.%0.3lluT", count/IPMACSEC_SECY_COUNTER_1T, (remainder/IPMACSEC_SECY_COUNTER_1G)); } else if (count >= IPMACSEC_SECY_COUNTER_1G) { remainder = count%IPMACSEC_SECY_COUNTER_1G; if (remainder==0) snprintf(buf, len, "%lluG", count/IPMACSEC_SECY_COUNTER_1G); else snprintf(buf, len, "%llu.%0.3lluG", count/IPMACSEC_SECY_COUNTER_1G, (remainder/IPMACSEC_SECY_COUNTER_1M)); } else if (count >= IPMACSEC_SECY_COUNTER_1M) { remainder = count%IPMACSEC_SECY_COUNTER_1M; if (remainder==0) snprintf(buf, len, "%lluM", count/IPMACSEC_SECY_COUNTER_1M); else snprintf(buf, len, "%llu.%0.3lluM", count/IPMACSEC_SECY_COUNTER_1M, (remainder/IPMACSEC_SECY_COUNTER_1K)); } else { remainder = count%IPMACSEC_SECY_COUNTER_1K; if (remainder==0) snprintf(buf, len, "%lluk", count/IPMACSEC_SECY_COUNTER_1K); else snprintf(buf, len, "%llu.%0.3lluk", count/IPMACSEC_SECY_COUNTER_1K, remainder); } buf[len-1] = '\0'; /* Null terminate just in case not enough storage was supplied. */ return buf; } /* *=========================================================================== * ipmacsec_lmi_error_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_lmi_error_name(Ipmacsec_lmi_error error) { IP_CONST char *name = "INVALID LMI ERROR"; switch (error) { case IPMACSEC_LMIERR_NONE: name = "IPMACSEC_LMIERR_NONE"; break; case IPMACSEC_LMIERR_UNSPECIFIED_ERROR: name = "IPMACSEC_LMIERR_UNSPECIFIED_ERROR"; break; case IPMACSEC_LMIERR_ALLOC_FAILED: name = "IPMACSEC_LMIERR_ALLOC_FAILED"; break; case IPMACSEC_LMIERR_NETLINK_MSG_ERROR: name = "IPMACSEC_LMIERR_NETLINK_MSG_ERROR"; break; case IPMACSEC_LMIERR_NETLINK_PARAM_ERROR: name = "IPMACSEC_LMIERR_NETLINK_PARAM_ERROR"; break; case IPMACSEC_LMIERR_NETLINK_OPEN_ERROR: name = "IPMACSEC_LMIERR_NETLINK_OPEN_ERROR"; break; case IPMACSEC_LMIERR_NETLINK_REG_ERROR: name = "IPMACSEC_LMIERR_NETLINK_REG_ERROR"; break; case IPMACSEC_LMIERR_NETLINK_REQUEST_ERROR: name = "IPMACSEC_LMIERR_NETLINK_REQUEST_ERROR"; break; case IPMACSEC_LMIERR_NETLINK_RESPONSE_ERROR: name = "IPMACSEC_LMIERR_NETLINK_RESPONSE_ERROR"; break; case IPMACSEC_LMIERR_NETLINK_LOOP_ERROR: name = "IPMACSEC_LMIERR_NETLINK_LOOP_ERROR"; break; case IPMACSEC_LMIERR_INVALID_REQUEST: name = "IPMACSEC_LMIERR_INVALID_REQUEST"; break; case IPMACSEC_LMIERR_INVALID_PID: name = "IPMACSEC_LMIERR_INVALID_PID"; break; case IPMACSEC_LMIERR_INVALID_PARAMETER: name = "IPMACSEC_LMIERR_INVALID_PARAMETER"; break; case IPMACSEC_LMIERR_SECY_DOESNOT_EXIST: name = "IPMACSEC_LMIERR_SECY_DOESNOT_EXIST"; break; case IPMACSEC_LMIERR_CIPHER_SUITE_NOT_SUPPORTED: name = "IPMACSEC_LMIERR_CIPHER_SUITE_NOT_SUPPORTED"; break; case IPMACSEC_LMIERR_NOT_SUPPORTED: name = "IPMACSEC_LMIERR_NOT_SUPPORTED"; break; case IPMACSEC_LMIERR_HANDLE_CREATE_FAILED: name = "IPMACSEC_LMIERR_HANDLE_CREATE_FAILED"; break; case IPMACSEC_LMIERR_INVALID_PROFILE: name = "IPMACSEC_LMIERR_INVALID_PROFILE"; break; case IPMACSEC_LMIERR_CMD_NOT_FOUND: name = "IPMACSEC_LMIERR_CMD_NOT_FOUND"; break; case IPMACSEC_LMIERR_INVALID_CMD_SYNTAX: name = "IPMACSEC_LMIERR_INVALID_CMD_SYNTAX"; break; case IPMACSEC_LMIERR_SECY_CMD_ERROR: name = "IPMACSEC_LMIERR_SECY_CMD_ERROR"; break; } return name; } /* *=========================================================================== * ipmacsec_lmi_cmd_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_lmi_cmd_name(Ipmacsec_lmi_command cmd) { char *name = "INVALID IPMACSEC COMMAND"; if (!IPMACSEC_LMICMD_IS_VALID(cmd)) { return name; } switch(cmd) { case IPMACSEC_LMICMD_SECY_EXISTS: name = "IPMACSEC_LMICMD_SECY_EXISTS"; break; case IPMACSEC_LMICMD_SECY_ENABLED: name = "IPMACSEC_LMICMD_SECY_ENABLED"; break; case IPMACSEC_LMICMD_SECY_PROTECT_FRAMES: name = "IPMACSEC_LMICMD_SECY_PROTECT_FRAMES"; break; case IPMACSEC_LMICMD_SECY_ALWAYS_INC_SCI: name = "IPMACSEC_LMICMD_SECY_ALWAYS_INC_SCI"; break; case IPMACSEC_LMICMD_SECY_USE_ES: name = "IPMACSEC_LMICMD_SECY_USE_ES"; break; case IPMACSEC_LMICMD_SECY_USE_SCB: name = "IPMACSEC_LMICMD_SECY_USE_SCB"; break; case IPMACSEC_LMICMD_SECY_VALIDATE_FRAMES: name = "IPMACSEC_LMICMD_SECY_VALIDATE_FRAMES"; break; case IPMACSEC_LMICMD_SECY_REPLAY_PROTECT: name = "IPMACSEC_LMICMD_SECY_REPLAY_PROTECT"; break; case IPMACSEC_LMICMD_SECY_REPLAY_WINDOW: name = "IPMACSEC_LMICMD_SECY_REPLAY_WINDOW"; break; case IPMACSEC_LMICMD_SECY_TX_SCI: name = "IPMACSEC_LMICMD_SECY_TX_SCI"; break; case IPMACSEC_LMICMD_SECY_MAX_RX_SC: name = "IPMACSEC_LMICMD_SECY_MAX_RX_SC"; break; case IPMACSEC_LMICMD_SECY_MAX_RX_KEYS: name = "IPMACSEC_LMICMD_SECY_MAX_RX_KEYS"; break; case IPMACSEC_LMICMD_SECY_MAX_TX_KEYS: name = "IPMACSEC_LMICMD_SECY_MAX_TX_KEYS"; break; case IPMACSEC_LMICMD_SECY_PN_THRESHOLD: name = "IPMACSEC_LMICMD_SECY_PN_THRESHOLD"; break; case IPMACSEC_LMICMD_SECY_INFO_NOTIFY: name = "IPMACSEC_LMICMD_SECY_INFO_NOTIFY"; break; case IPMACSEC_LMICMD_SECY_CONFIDENTIALITY_OFFSET: name = "IPMACSEC_LMICMD_SECY_CONFIDENTIALITY_OFFSET"; break; case IPMACSEC_LMICMD_SECY_CURRENT_CIPHER_SUITE: name = "IPMACSEC_LMICMD_SECY_CURRENT_CIPHER_SUITE"; break; case IPMACSEC_LMICMD_SECY_CIPHER_SUITE_LIST: name = "IPMACSEC_LMICMD_SECY_CIPHER_SUITE_LIST"; break; case IPMACSEC_LMICMD_SECY_CIPHER_SUITE_INFO: name = "IPMACSEC_LMICMD_SECY_CIPHER_SUITE_INFO"; break; case IPMACSEC_LMICMD_SECY_NUM_RX_SC_ACTIVE: name = "IPMACSEC_LMICMD_SECY_NUM_RX_SC_ACTIVE"; break; case IPMACSEC_LMICMD_SECY_NUM_RX_SC_CREATED: name = "IPMACSEC_LMICMD_SECY_NUM_RX_SC_CREATED"; break; case IPMACSEC_LMICMD_SECY_KEY_INSTALL: name = "IPMACSEC_LMICMD_SECY_KEY_INSTALL"; break; case IPMACSEC_LMICMD_SECY_KEY_REMOVE: name = "IPMACSEC_LMICMD_SECY_KEY_REMOVE"; break; case IPMACSEC_LMICMD_SECY_KEY_PURGE: name = "IPMACSEC_LMICMD_SECY_KEY_PURGE"; break; case IPMACSEC_LMICMD_SECY_KEY_INFO: name = "IPMACSEC_LMICMD_SECY_KEY_INFO"; break; case IPMACSEC_LMICMD_SECY_KEY_LIST: name = "IPMACSEC_LMICMD_SECY_KEY_LIST"; break; case IPMACSEC_LMICMD_SECY_RX_SC_CREATE: name = "IPMACSEC_LMICMD_SECY_RX_SC_CREATE"; break; case IPMACSEC_LMICMD_SECY_RX_SC_DELETE: name = "IPMACSEC_LMICMD_SECY_RX_SC_DELETE"; break; case IPMACSEC_LMICMD_SECY_RX_SC_STATUS: name = "IPMACSEC_LMICMD_SECY_RX_SC_STATUS"; break; case IPMACSEC_LMICMD_SECY_RX_SC_LIST: name = "IPMACSEC_LMICMD_SECY_RX_SC_LIST"; break; case IPMACSEC_LMICMD_SECY_TX_SC_CREATE: name = "IPMACSEC_LMICMD_SECY_TX_SC_CREATE"; break; case IPMACSEC_LMICMD_SECY_TX_SC_DELETE: name = "IPMACSEC_LMICMD_SECY_TX_SC_DELETE"; break; case IPMACSEC_LMICMD_SECY_TX_SC_STATUS: name = "IPMACSEC_LMICMD_SECY_TX_SC_STATUS"; break; case IPMACSEC_LMICMD_SECY_RX_SA_CREATE: name = "IPMACSEC_LMICMD_SECY_RX_SA_CREATE"; break; case IPMACSEC_LMICMD_SECY_RX_SA_DELETE: name = "IPMACSEC_LMICMD_SECY_RX_SA_DELETE"; break; case IPMACSEC_LMICMD_SECY_RX_SA_CONTROL: name = "IPMACSEC_LMICMD_SECY_RX_SA_CONTROL"; break; case IPMACSEC_LMICMD_SECY_RX_SA_STATUS: name = "IPMACSEC_LMICMD_SECY_RX_SA_STATUS"; break; case IPMACSEC_LMICMD_SECY_RX_SA_LIST: name = "IPMACSEC_LMICMD_SECY_RX_SA_LIST"; break; case IPMACSEC_LMICMD_SECY_TX_SA_CREATE: name = "IPMACSEC_LMICMD_SECY_TX_SA_CREATE"; break; case IPMACSEC_LMICMD_SECY_TX_SA_DELETE: name = "IPMACSEC_LMICMD_SECY_TX_SA_DELETE"; break; case IPMACSEC_LMICMD_SECY_TX_SA_CONTROL: name = "IPMACSEC_LMICMD_SECY_TX_SA_CONTROL"; break; case IPMACSEC_LMICMD_SECY_TX_SA_STATUS: name = "IPMACSEC_LMICMD_SECY_TX_SA_STATUS"; break; case IPMACSEC_LMICMD_SECY_TX_SA_LIST: name = "IPMACSEC_LMICMD_SECY_TX_SA_LIST"; break; case IPMACSEC_LMICMD_SECY_STATS: name = "IPMACSEC_LMICMD_SECY_STATS"; break; case IPMACSEC_LMICMD_SECY_RX_SC_STATS: name = "IPMACSEC_LMICMD_SECY_RX_SC_STATS"; break; case IPMACSEC_LMICMD_SECY_TX_SC_STATS: name = "IPMACSEC_LMICMD_SECY_TX_SC_STATS"; break; case IPMACSEC_LMICMD_SECY_RX_SA_STATS: name = "IPMACSEC_LMICMD_SECY_RX_SA_STATS"; break; case IPMACSEC_LMICMD_SECY_TX_SA_STATS: name = "IPMACSEC_LMICMD_SECY_TX_SA_STATS"; break; case IPMACSEC_LMICMD_CONTROLLED_PORT_ENABLED: name = "IPMACSEC_LMICMD_CONTROLLED_PORT_ENABLED"; break; case IPMACSEC_LMICMD_PORT_MAC_ENABLED: name = "IPMACSEC_LMICMD_PORT_MAC_ENABLED"; break; case IPMACSEC_LMICMD_PORT_MAC_OPER: name = "IPMACSEC_LMICMD_PORT_MAC_OPER"; break; case IPMACSEC_LMICMD_PORT_OPER_PTP_MAC: name = "IPMACSEC_LMICMD_PORT_OPER_PTP_MAC"; break; case IPMACSEC_LMICMD_PORT_ADMIN_PTP_MAC: name = "IPMACSEC_LMICMD_PORT_ADMIN_PTP_MAC"; break; case IPMACSEC_LMICMD_PORT_STATISTICS: name = "IPMACSEC_LMICMD_PORT_STATISTICS"; break; case IPMACSEC_LMICMD_SECY_RESET_STATISTICS: name = "IPMACSEC_LMICMD_SECY_RESET_STATISTICS"; break; #if 0 case __IPMACSEC_LMICMD_NONE: case __IPMACSEC_LMICMD_MAX: break; #endif } return name; } /* *=========================================================================== * ipmacsec_lmi_note_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_lmi_note_name(Ipmacsec_lmi_note notification) { char *name = "INVALID IPMACSEC NOTIFICATION"; if (!IPMACSEC_LMINOTE_IS_VALID(notification)) { return name; } switch(notification) { case IPMACSEC_LMINOTE_STATUS: name = "IPMACSEC_LMINOTE_STATUS"; break; case IPMACSEC_LMINOTE_INFO: name = "IPMACSEC_LMINOTE_INFO"; break; #if 0 case __IPMACSEC_LMINOTE_NONE: case __IPMACSEC_LMINOTE_MAX: break; #endif } return name; } /* *=========================================================================== * ipmacsec_secy_status_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_secy_status_name(Ipmacsec_secy_status status) { char *name = "INVALID IPMACSEC STATUS"; if (!IPMACSEC_SECY_STATUS_IS_VALID(status)) { return name; } switch(status) { case IPMACSEC_STATUS_SECY_CP_ENABLED_ON: name = "IPMACSEC_STATUS_SECY_CP_ENABLED_ON"; break; case IPMACSEC_STATUS_SECY_CP_ENABLED_OFF: name = "IPMACSEC_STATUS_SECY_CP_ENABLED_OFF"; break; case IPMACSEC_STATUS_SECY_CP_MAC_ENABLED_ON: name = "IPMACSEC_STATUS_SECY_CP_MAC_ENABLED_ON"; break; case IPMACSEC_STATUS_SECY_CP_MAC_ENABLED_OFF: name = "IPMACSEC_STATUS_SECY_CP_MAC_ENABLED_OFF"; break; case IPMACSEC_STATUS_SECY_CP_MAC_OPER_ON: name = "IPMACSEC_STATUS_SECY_CP_MAC_OPER_ON"; break; case IPMACSEC_STATUS_SECY_CP_MAC_OPER_OFF: name = "IPMACSEC_STATUS_SECY_CP_MAC_OPER_OFF"; break; case IPMACSEC_STATUS_SECY_CP_OPER_PTP_MAC_ON: name = "IPMACSEC_STATUS_SECY_CP_OPER_PTP_MAC_ON"; break; case IPMACSEC_STATUS_SECY_CP_OPER_PTP_MAC_OFF: name = "IPMACSEC_STATUS_SECY_CP_OPER_PTP_MAC_OFF"; break; case IPMACSEC_STATUS_SECY_PN_NEARLY_EXHAUSTED: name = "IPMACSEC_STATUS_SECY_PN_NEARLY_EXHAUSTED"; break; case IPMACSEC_STATUS_SECY_PN_EXHAUSTED: name = "IPMACSEC_STATUS_SECY_PN_EXHAUSTED"; break; #if 0 case __IPMACSEC_STATUS_NONE: case __IPMACSEC_STATUS_MAX: break; #endif } return name; } /* *=========================================================================== * ipmacsec_secy_info_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_secy_info_name(Ipmacsec_secy_info info) { char *name = "INVALID IPMACSEC INFO"; if (!IPMACSEC_SECY_INFO_IS_VALID(info)) { return name; } switch(info) { case IPMACSEC_INFO_SECY_ENABLED: name = "IPMACSEC_INFO_SECY_ENABLED"; break; case IPMACSEC_INFO_SECY_DISABLED: name = "IPMACSEC_INFO_SECY_DISABLED"; break; case IPMACSEC_INFO_SECY_SC_CREATED: name = "IPMACSEC_INFO_SECY_SC_CREATED"; break; case IPMACSEC_INFO_SECY_SC_DELETED: name = "IPMACSEC_INFO_SECY_SC_DELETED"; break; case IPMACSEC_INFO_SECY_SC_STATUS_CHANGED: name = "IPMACSEC_INFO_SECY_SC_STATUS_CHANGED"; break; case IPMACSEC_INFO_SECY_SA_CREATED: name = "IPMACSEC_INFO_SECY_SA_CREATED"; break; case IPMACSEC_INFO_SECY_SA_DELETED: name = "IPMACSEC_INFO_SECY_SA_DELETED"; break; case IPMACSEC_INFO_SECY_SA_STATUS_CHANGED: name = "IPMACSEC_INFO_SECY_SA_STATUS_CHANGED"; break; case IPMACSEC_INFO_SECY_KEY_INSTALLED: name = "IPMACSEC_INFO_SECY_KEY_INSTALLED"; break; case IPMACSEC_INFO_SECY_KEY_REMOVED: name = "IPMACSEC_INFO_SECY_KEY_REMOVED"; break; #if 0 case __IPMACSEC_INFO_NONE: case __IPMACSEC_INFO_MAX: break; #endif } return name; } /* *=========================================================================== * ipmacsec_lmi_enable_flag_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_lmi_enable_flag_name(Ipmacsec_enable_flag enable_flag) { char *name = "INVALID ENABLE FLAG"; if (!IPMACSEC_ENABLE_FLAG_VALID(enable_flag)) { return name; } switch(enable_flag) { case IPMACSEC_ENABLEFLAG_IGNORE: name = "Ignore"; break; case IPMACSEC_ENABLEFLAG_ON: name = "On"; break; case IPMACSEC_ENABLEFLAG_OFF: name = "Off"; break; } return name; } /* *=========================================================================== * ipmacsec_lmi_confidentiality_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_lmi_confidentiality_name(Ipmacsec_confidentiality confidentiality) { char *name = "INVALID IPMACSEC CONFIDENTIALITY"; if (!IPMACSEC_CONFIDENTIALITY_VALID(confidentiality)) { return name; } switch(confidentiality) { case IPMACSEC_CONFIDENTIALITY_UNSPECIFIED: name = "Unspecified"; break; case IPMACSEC_CONFIDENTIALITY_ON: name = "On"; break; case IPMACSEC_CONFIDENTIALITY_OFF: name = "Off"; break; #if 0 case IPMACSEC_CONFIDENTIALITY_INVALID: break; #endif } return name; } /* *=========================================================================== * ipmacsec_secy_validateFrames_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_secy_validateFrames_name(Ipmacsec_validateFrames_type validateFrames) { char *name = "INVALID VALUE"; if (!IPMACSEC_SECY_INFO_IS_VALID(validateFrames)) { return name; } switch(validateFrames) { case IPMACSEC_SECY_VALIDATEFRAMES_DISABLED: name = IPMACSEC_SYSVARVAL_SECY_VALIDATEFRAMES_DISABLED; break; case IPMACSEC_SECY_VALIDATEFRAMES_CHECK: name = IPMACSEC_SYSVARVAL_SECY_VALIDATEFRAMES_CHECK; break; case IPMACSEC_SECY_VALIDATEFRAMES_STRICT: name = IPMACSEC_SYSVARVAL_SECY_VALIDATEFRAMES_STRICT; break; #if 0 case __IPMACSEC_SECY_VALIDATEFRAMES_INVALID: case __IPMACSEC_SECY_VALIDATEFRAMES_MAX: break; #endif } return name; } /* *=========================================================================== * ipmacsec_secy_cp_adminPointToPointMAC_name *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL IP_CONST char * ipmacsec_secy_cp_adminPointToPointMAC_name(Ip_portif_admin_ptp_mac_val admin_p2p_mac) { char *name = "UNKNOWN VALUE"; switch (admin_p2p_mac) { case IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO: name = "AUTO"; break; case IP_PORTIF_ADMIN_PTP_MAC_FORCE_TRUE: name = "TRUE"; break; case IP_PORTIF_ADMIN_PTP_MAC_FORCE_FALSE: name = "FALSE"; break; } return name; } /* *=========================================================================== * ipmacsec_lmi_strf_sc_info *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL void ipmacsec_lmi_strf_sc_info(Ipmacsec_secy_sc_info *sc_info, IP_CONST char *prefix, char *str, Ip_u32 strln) { IP_CONST char *pref = (prefix ? prefix : ""); if (sc_info && str && strln) { IPMACSEC_TIMEBUF(createdTime); IPMACSEC_TIMEBUF(startedTime); IPMACSEC_TIMEBUF(stoppedTime); IPMACSEC_STRFTIME(createdTime, sc_info->createdTime); IPMACSEC_STRFTIME(startedTime, sc_info->startedTime); IPMACSEC_STRFTIME(stoppedTime, sc_info->stoppedTime); if (sc_info->dir == IPMACSEC_TX) { ipcom_snprintf(str, strln, "%ssci: " IPMACSEC_SCI_STRING ", dir: %s, transmitting: %s\n" "%sencipheringSA: %u, encodingSA: %u\n" "%screatedTime: %s\n" "%sstartedTime: %s\n" "%sstoppedTime: %s\n", pref, IPMACSEC_SCI_OCTETS(sc_info->sci), IPMACSEC_DIR_STRING(sc_info->dir), IPMACSEC_BOOL_STRING(sc_info->status.tx.transmitting), pref, sc_info->status.tx.encipheringSA, sc_info->status.tx.encodingSA, pref, createdTime, pref, startedTime, pref, stoppedTime); } else if (sc_info->dir == IPMACSEC_RX) { ipcom_snprintf(str, strln, "%ssci: " IPMACSEC_SCI_STRING ", dir: %s, receiving: %s\n" "%screatedTime: %s\n" "%sstartedTime: %s\n" "%sstoppedTime: %s\n", pref, IPMACSEC_SCI_OCTETS(sc_info->sci), IPMACSEC_DIR_STRING(sc_info->dir), IPMACSEC_BOOL_STRING(sc_info->status.rx.receiving), pref, createdTime, pref, startedTime, pref, stoppedTime); } else { ipcom_snprintf(str, strln, "Corrupt SC info (SC dir = %u)\n", sc_info->dir); } str[strln-1] = '\0'; /* NULL terminate just in case of truncation */ } } /* *=========================================================================== * ipmacsec_lmi_strf_sa_desc *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL void ipmacsec_lmi_strf_sa_desc(Ipmacsec_secy_sa_descriptor *sa_desc, IP_CONST char *prefix, char *str, Ip_u32 strln) { IP_CONST char *pref = (prefix ? prefix : ""); if (sa_desc && str && strln) { ipcom_snprintf(str, strln, "%ssci: " IPMACSEC_SCI_STRING ", an: %u, dir: %s\n" "%skey_id: 0x%llx, ref: 0x%x" "\n", pref, IPMACSEC_SCI_OCTETS(sa_desc->sci), sa_desc->an, IPMACSEC_DIR_STRING(sa_desc->dir), pref, sa_desc->key_id.val, sa_desc->ref); str[strln-1] = '\0'; /* NULL terminate just in case of truncation */ } } /* *=========================================================================== * ipmacsec_lmi_strf_sa_info *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL void ipmacsec_lmi_strf_sa_info(Ipmacsec_secy_sa_info *sa_info, Ipmacsec_dir sa_dir, IP_CONST char *prefix, char *str, Ip_u32 strln) { IP_CONST char *pref = (prefix ? prefix : ""); if (sa_info && str && strln) { IPMACSEC_TIMEBUF(createdTime); IPMACSEC_TIMEBUF(startedTime); IPMACSEC_TIMEBUF(stoppedTime); IPMACSEC_STRFTIME(createdTime, sa_info->createdTime); IPMACSEC_STRFTIME(startedTime, sa_info->startedTime); IPMACSEC_STRFTIME(stoppedTime, sa_info->stoppedTime); if (sa_dir == IPMACSEC_TX) { ipcom_snprintf(str, strln, "%sinUse: %s, confidentiality: %s, nextPN: %u\n" "%screatedTime: %s\n" "%sstartedTime: %s\n" "%sstoppedTime: %s\n", pref, IPMACSEC_BOOL_STRING(sa_info->inUse), ipmacsec_lmi_confidentiality_name(sa_info->config.tx.confidentiality), sa_info->config.tx.nextPN, pref, createdTime, pref, startedTime, pref, stoppedTime); } else if (sa_dir == IPMACSEC_RX) { ipcom_snprintf(str, strln, "%sinUse: %s, lowestPN: %u, nextPN: %u\n" "%screatedTime: %s\n" "%sstartedTime: %s\n" "%sstoppedTime: %s\n", pref, IPMACSEC_BOOL_STRING(sa_info->inUse), sa_info->config.rx.lowestPN, sa_info->config.rx.nextPN, pref, createdTime, pref, startedTime, pref, stoppedTime); } else { ipcom_snprintf(str, strln, "Corrupt SA info (SA dir = %u)\n", sa_dir); } str[strln-1] = '\0'; /* NULL terminate just in case of truncation */ } } /* *=========================================================================== * ipmacsec_lmi_strf_sa_ctrl *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL void ipmacsec_lmi_strf_sa_ctrl(Ipmacsec_secy_sa_ctrl *sa_ctrl, Ipmacsec_dir sa_dir, IP_CONST char *prefix, char *str, Ip_u32 strln) { IP_CONST char *pref = (prefix ? prefix : ""); if (sa_ctrl && str && strln) { if (sa_dir == IPMACSEC_TX) { ipcom_snprintf(str, strln, "%senableTx: %s\n", pref, ipmacsec_lmi_enable_flag_name(sa_ctrl->tx.enableTx)); } else if (sa_dir == IPMACSEC_RX) { ipcom_snprintf(str, strln, "%senableRx: %s, updtNextPN: %u, updtLowestPN: %u\n", pref, ipmacsec_lmi_enable_flag_name(sa_ctrl->rx.enableRx), sa_ctrl->rx.updtNextPN, sa_ctrl->rx.updtLowestPN); } else { ipcom_snprintf(str, strln, "Corrupt SA ctrl (SA dir = %u)\n", sa_dir); } str[strln-1] = '\0'; /* NULL terminate just in case of truncation */ } } /* *=========================================================================== * ipmacsec_lmi_strf_key_desc *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL void ipmacsec_lmi_strf_key_desc(Ipmacsec_secy_key_descriptor *key_desc, IP_CONST char *prefix, char *str, Ip_u32 strln) { IP_CONST char *pref = (prefix ? prefix : ""); if (key_desc && str && strln) { IPMACSEC_TIMEBUF(createdTime); IPMACSEC_STRFTIME(createdTime, key_desc->created_time); ipcom_snprintf(str, strln, "%skey_id: 0x%llx, type: %s%s%s, size: %u, inUse: %s\n" "%screatedTime: %s\n", pref, key_desc->key_id.val, ((key_desc->key_type & IPMACSEC_KEYTYPE_TRANSMIT) ? "TX " : ""), ((key_desc->key_type & IPMACSEC_KEYTYPE_RECEIVE) ? "RX" : ""), ((key_desc->key_type == 0) ? "NOT SET" : ""), key_desc->key_size, IPMACSEC_BOOL_STRING(key_desc->inUse), pref, createdTime); str[strln-1] = '\0'; /* NULL terminate just in case of truncation */ } } /* *=========================================================================== * ipmacsec_lmi_secy_set_cmd_append *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_secy_set_cmd_append(Ipmacsec_buffer *buf, struct Ip_nlmsghdr **nlreq, char *ifname, Ipmacsec_lmi_command cmd, void *param, Ip_u32 param_size) { struct Ip_nlmsghdr *nlmsg = IP_NULL; ip_assert(buf); ip_assert(ifname); if (nlreq) *nlreq = IP_NULL; nlmsg = ipmacsec_nlcmd_add(buf, IPMACSEC_NLTYPE_SECY_COMMAND, cmd, ifname, 0, 0); if (nlmsg == IP_NULL) { return IPMACSEC_LMIERR_NETLINK_MSG_ERROR; } if (ipmacsec_nlcmd_add_param(buf, nlmsg, param, param_size) < (int)param_size) { return IPMACSEC_LMIERR_NETLINK_PARAM_ERROR; } if (nlreq) *nlreq = nlmsg; return IPMACSEC_LMIERR_NONE; } /* *=========================================================================== * ipmacsec_lmi_secy_get_cmd_append *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_secy_get_cmd_append(Ipmacsec_buffer *buf, struct Ip_nlmsghdr **nlreq, char *ifname, Ipmacsec_lmi_command cmd, void *param, Ip_u32 param_size) { struct Ip_nlmsghdr *nlmsg = IP_NULL; ip_assert(buf); ip_assert(ifname); if (nlreq) *nlreq = IP_NULL; nlmsg = ipmacsec_nlcmd_add(buf, IPMACSEC_NLTYPE_SECY_COMMAND, cmd, ifname, 1, 0); if (nlmsg == IP_NULL) { return IPMACSEC_LMIERR_NETLINK_MSG_ERROR; } if (ipmacsec_nlcmd_add_param(buf, nlmsg, param, param_size) < (int)param_size) { return IPMACSEC_LMIERR_NETLINK_PARAM_ERROR; } if (nlreq) *nlreq = nlmsg; return IPMACSEC_LMIERR_NONE; } /* *=========================================================================== * ipmacsec_lmi_cmd_parse_response *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_cmd_parse_response(Ipmacsec_buffer *buf, char *ifname, Ipmacsec_lmi_command cmd, void *param, Ip_u32 param_size) { struct Ip_nlmsghdr *nlmsg = IP_NULL; Ip_u32 offset = 0, remlen = 0; ip_assert(buf); ip_assert(ifname); offset = 0; nlmsg = (struct Ip_nlmsghdr *)ipmacsec_buf_ptr(buf, offset, &remlen); while (nlmsg) { Ipmacsec_nlcmd_hdr *nlcmd = IP_NULL; /* Skip non command responses */ if ((remlen >= IPMACSEC_NLCMD_LENGTH(0)) && (nlmsg->nlmsg_type == IPMACSEC_NLTYPE_SECY_COMMAND)) nlcmd = ipmacsec_nlcmd_get(nlmsg); if (nlcmd && nlcmd->reply && (nlcmd->command == cmd) && (ipcom_strcmp(nlcmd->ifname, ifname) ==0) ) { (void)ipmacsec_nlcmd_retrieve_init(nlmsg); if (ipmacsec_nlcmd_retrieve_param(nlmsg, param, param_size) >= (int)param_size) { return IPMACSEC_LMIERR_NONE; } } /* Parse next command (if any) */ offset += nlmsg->nlmsg_len; nlmsg = (struct Ip_nlmsghdr *)ipmacsec_buf_ptr(buf, offset, &remlen); } return IPMACSEC_LMIERR_NETLINK_RESPONSE_ERROR; } /* *=========================================================================== * ipmacsec_lmi_cmd_parse_response_pbuf *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_cmd_parse_response_pbuf(Ipmacsec_buffer *buf, char *ifname, Ipmacsec_lmi_command cmd, Ipmacsec_buffer *pbuf) { struct Ip_nlmsghdr *nlmsg = IP_NULL; Ip_u32 offset = 0, remlen = 0; ip_assert(buf); ip_assert(ifname); offset = 0; nlmsg = (struct Ip_nlmsghdr *)ipmacsec_buf_ptr(buf, offset, &remlen); while (nlmsg) { Ipmacsec_nlcmd_hdr *nlcmd = IP_NULL; /* Skip non command responses */ if ((remlen >= IPMACSEC_NLCMD_LENGTH(0)) && (nlmsg->nlmsg_type == IPMACSEC_NLTYPE_SECY_COMMAND)) nlcmd = ipmacsec_nlcmd_get(nlmsg); if (nlcmd && nlcmd->reply && (nlcmd->command == cmd) && (ipcom_strcmp(nlcmd->ifname, ifname) ==0) ) { Ip_u16 plen = (Ip_u16)ipmacsec_nlcmd_retrieve_init(nlmsg); /* Safe because we already checked nlcmd */ Ip_u16 addlen = (Ip_u16)IP_MIN(plen, IPMACSEC_BUF_REM(pbuf)); (void)ipmacsec_nlcmd_retrieve_param(nlmsg, IPMACSEC_BUF_TAIL(pbuf), addlen); IPMACSEC_BUF_APPEND(pbuf, IP_NULL, addlen); return IPMACSEC_LMIERR_NONE; } /* Parse next command (if any) */ offset += nlmsg->nlmsg_len; nlmsg = (struct Ip_nlmsghdr *)ipmacsec_buf_ptr(buf, offset, &remlen); } return IPMACSEC_LMIERR_NETLINK_RESPONSE_ERROR; } /* *=========================================================================== * ipmacsec_lmi_cmd_send *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_cmd_send(Ipmacsec_netlink_handle *nlh, Ipmacsec_buffer *request, Ipmacsec_buffer *response) { struct Ip_nlmsghdr *nlmsg = IP_NULL; Ipmacsec_netlink_handle *nlhandle = nlh; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ip_u32 offset = 0, remlen = 0; ip_assert(request); if (!nlhandle) nlhandle = ipmacsec_netlink_open(IPMACSEC_NLGRP_NONE); if (!nlhandle) { ret = IPMACSEC_LMIERR_NETLINK_OPEN_ERROR; goto err_out; } offset = 0; nlmsg = (struct Ip_nlmsghdr *)ipmacsec_buf_ptr(request, offset, &remlen); while (nlmsg) { if ((nlmsg->nlmsg_len < IPMACSEC_NLCMD_LENGTH(0)) || (remlen < nlmsg->nlmsg_len)) { ret = IPMACSEC_LMIERR_INVALID_REQUEST; goto err_out; } ret = ipmacsec_netlink_request(nlhandle, nlmsg, response); if (ret < 0) { ret = IPMACSEC_LMIERR_NETLINK_REQUEST_ERROR; goto err_out; } offset += nlmsg->nlmsg_len; nlmsg = (struct Ip_nlmsghdr *)ipmacsec_buf_ptr(request, offset, &remlen); } if (offset) /* We have sent at least 1 cmd */ ret = 0; err_out: /* Do not close caller's handle */ if (!nlh) ipmacsec_netlink_close(nlhandle); return ret; } /* *=========================================================================== * ipmacsec_lmi_cmd_send_bool *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_cmd_send_bool(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_lmi_command cmd, Ip_bool *param, Ip_bool isGet) { Ipmacsec_buffer request, response; Ip_bool val; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !param) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } /* Verify it is a command that takes bool params */ if ((cmd != IPMACSEC_LMICMD_SECY_PROTECT_FRAMES) && (cmd != IPMACSEC_LMICMD_SECY_ALWAYS_INC_SCI) && (cmd != IPMACSEC_LMICMD_SECY_USE_ES) && (cmd != IPMACSEC_LMICMD_SECY_USE_SCB) && (cmd != IPMACSEC_LMICMD_SECY_REPLAY_PROTECT) && (cmd != IPMACSEC_LMICMD_CONTROLLED_PORT_ENABLED)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (isGet) { if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } *param = IP_FALSE; ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, cmd, IP_NULL, 0); } else { val = *param; ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, cmd, &val, sizeof(val)); } if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, (isGet ? &response : IP_NULL)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } if (isGet) { ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, cmd, &val, sizeof(val)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } *param = val; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_cmd_send_u16 *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_cmd_send_u16(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_lmi_command cmd, Ip_u16 *param, Ip_bool isGet) { Ipmacsec_buffer request, response; Ip_u16 val; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !param) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } /* Verify it is a command that takes Ip_u16 params */ if ((cmd != IPMACSEC_LMICMD_SECY_MAX_RX_SC) && (cmd != IPMACSEC_LMICMD_SECY_MAX_RX_KEYS) && (cmd != IPMACSEC_LMICMD_SECY_MAX_TX_KEYS) && (cmd != IPMACSEC_LMICMD_SECY_NUM_RX_SC_ACTIVE) && (cmd != IPMACSEC_LMICMD_SECY_NUM_RX_SC_CREATED) && (cmd != IPMACSEC_LMICMD_SECY_CONFIDENTIALITY_OFFSET)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (isGet) { if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } *param = IP_FALSE; ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, cmd, IP_NULL, 0); } else { val = *param; ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, cmd, &val, sizeof(val)); } if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, (isGet ? &response : IP_NULL)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } if (isGet) { ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, cmd, &val, sizeof(val)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } *param = val; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_cmd_send_u32 *=========================================================================== * Description: see "ipmacsec_lmi.h" * Parameters: * Returns: * */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_cmd_send_u32(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_lmi_command cmd, Ip_u32 *param, Ip_bool isGet) { Ipmacsec_buffer request, response; Ip_u32 val; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !param) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } /* Verify it is a command that takes Ip_u16 params */ if ((cmd != IPMACSEC_LMICMD_SECY_VALIDATE_FRAMES) && (cmd != IPMACSEC_LMICMD_SECY_REPLAY_WINDOW) && (cmd != IPMACSEC_LMICMD_SECY_PN_THRESHOLD) && (cmd != IPMACSEC_LMICMD_SECY_CURRENT_CIPHER_SUITE) && (cmd != IPMACSEC_LMICMD_PORT_ADMIN_PTP_MAC)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (isGet) { if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } *param = IP_FALSE; ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, cmd, IP_NULL, 0); } else { val = *param; ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, cmd, &val, sizeof(val)); } if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, (isGet ? &response : IP_NULL)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } if (isGet) { ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, cmd, &val, sizeof(val)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } *param = val; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmacsec_lmi_protocol_version *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_protocol_version(void) { return IPMACSEC_VERSION_NUMBER; } /* *=========================================================================== * ipmacsec_lmi_handle_create *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC IPMACSEC_LMI_HANDLE ipmacsec_lmi_handle_create(void) { return (IPMACSEC_LMI_HANDLE)ipmacsec_netlink_open(IPMACSEC_NLGRP_NONE); } /* *=========================================================================== * ipmacsec_lmi_handle_delete *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_handle_delete(IPMACSEC_LMI_HANDLE lh) { return (ipmacsec_netlink_close(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh))); } /* *=========================================================================== * ipmacsec_lmi_secy_exists *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ip_bool ipmacsec_lmi_secy_exists(IPMACSEC_LMI_HANDLE lh, char *ifname) { Ipmacsec_buffer request; Ip_bool ret = IP_FALSE; if (!ifname) { return ret; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { goto err_out; } if (ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_EXISTS, IP_NULL, 0) != IPMACSEC_LMIERR_NONE) { goto err_out; } if (ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL) == IPMACSEC_LMIERR_NONE) { ret = IP_TRUE; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_enable *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_enable(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool enable) { #ifdef IPMACSEC_USE_IOCTL return ipmacsec_send_ioctl(ifname, (enable ? IPMACSEC_LMICMD_SECY_ENABLE : IPMACSEC_LMICMD_SECY_DISABLE), 0, 0); #else Ipmacsec_buffer request; Ip_bool doEnable = enable; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &doEnable, sizeof(doEnable)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); err_out: ipmacsec_nlmsg_free(&request); return ret; #endif } /* *=========================================================================== * ipmacsec_lmi_secy_is_enabled *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_is_enabled(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *enabled) { Ipmacsec_buffer request, response; Ip_bool en = IP_FALSE; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !enabled) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_ENABLED, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_ENABLED, &en, sizeof(en)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } *enabled = en; err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_set_protectFrames *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_protectFrames(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool protectFrames) { Ip_bool val = protectFrames; return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_PROTECT_FRAMES, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_protectFrames *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_protectFrames(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *protectFrames) { return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_PROTECT_FRAMES, protectFrames, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_alwaysIncludeSCI *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_alwaysIncludeSCI(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool alwaysIncludeSCI) { Ip_bool val = alwaysIncludeSCI; return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_ALWAYS_INC_SCI, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_alwaysIncludeSCI *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_alwaysIncludeSCI(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *alwaysIncludeSCI) { return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_ALWAYS_INC_SCI, alwaysIncludeSCI, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_useES *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_useES(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool useES) { Ip_bool val = useES; return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_USE_ES, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_useES *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_useES(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *useES) { return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_USE_ES, useES, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_useSCB *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_useSCB(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool useSCB) { Ip_bool val = useSCB; return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_USE_SCB, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_useSCB *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_useSCB(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *useSCB) { return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_USE_SCB, useSCB, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_validateFrames *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_validateFrames(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_validateFrames_type validateFrames) { Ip_u32 val = (Ip_u32)validateFrames; if (!IPMACSEC_VALIDATEFRAMES_VALID(validateFrames)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_SECY_VALIDATE_FRAMES, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_validateFrames *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_validateFrames(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_validateFrames_type *validateFrames) { return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_SECY_VALIDATE_FRAMES, (Ip_u32 *)validateFrames, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_replayProtect *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_replayProtect(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool replayProtect) { Ip_bool val = replayProtect; return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_REPLAY_PROTECT, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_replayProtect *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_replayProtect(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *replayProtect) { return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_SECY_REPLAY_PROTECT, replayProtect, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_replayWindow *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_replayWindow(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u32 replayWindow) { Ip_u32 val = replayWindow; return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_SECY_REPLAY_WINDOW, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_replayWindow *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_replayWindow(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u32 *replayWindow) { return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_SECY_REPLAY_WINDOW, replayWindow, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_key_install *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_key_install(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_key_descriptor *key_desc, Ip_u8 *key) { Ipmacsec_buffer request; struct Ip_nlmsghdr *nlreq; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !key_desc || !key || !key_desc->key_size) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, &nlreq, ifname, IPMACSEC_LMICMD_SECY_KEY_INSTALL, key_desc, sizeof(Ipmacsec_secy_key_descriptor)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } if (ipmacsec_nlcmd_add_param(&request, nlreq, key, key_desc->key_size) < (int)key_desc->key_size) { ret = IPMACSEC_LMIERR_NETLINK_PARAM_ERROR; goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); err_out: IPMACSEC_BUF_WIPE(&request); /* for security reasons, we wipe out the temp keying material storage */ ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_key_remove *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_key_remove(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_key_descriptor *key_desc) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !key_desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_KEY_REMOVE, key_desc, sizeof(Ipmacsec_secy_key_descriptor)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_key_purge *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_key_purge(IPMACSEC_LMI_HANDLE lh, char *ifname) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_KEY_PURGE,IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_key_info *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_key_info(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_key_descriptor *key_desc, Ipmacsec_buffer *info) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !info) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } 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; } if (key_desc) { ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_KEY_INFO, key_desc, sizeof(Ipmacsec_secy_key_descriptor)); } else { ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_KEY_LIST, IP_NULL, 0); } if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } if (key_desc) { Ipmacsec_secy_key_descriptor kdesc; ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_KEY_INFO, &kdesc, sizeof(kdesc)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } (void)ipmacsec_buf_append(info, (Ip_u8 *)&kdesc, sizeof(kdesc)); ret = IPMACSEC_LMIERR_NONE; /* Even if we fail to append, we still succeed since we got info back and * caller may not have supplied enough buffer space (intentionally or not) */ } else { ret = ipmacsec_lmi_cmd_parse_response_pbuf(&response, ifname, IPMACSEC_LMICMD_SECY_KEY_LIST, info); } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_sa_descriptor_init *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_secy_sa_descriptor * ipmacsec_lmi_secy_sa_descriptor_init(Ipmacsec_secy_sa_descriptor *sa_desc, Ip_u8 *sci, Ip_u8 an, Ipmacsec_dir dir, Ipmacsec_secy_sa_ref ref, Ipmacsec_secy_key_id *key_id) { if (!sa_desc || ((dir == IPMACSEC_RX) && !sci) || IPMACSEC_INVALID_AN(an)) { return IP_NULL; } if (sci) IPMACSEC_COPY_SCI(sa_desc->sci, sci); else IPMACSEC_INVALIDATE_SCI(sa_desc->sci); sa_desc->an = an; sa_desc->dir = dir; sa_desc->ref = ref; if (key_id) sa_desc->key_id.val = key_id->val; else sa_desc->key_id.val = 0; return sa_desc; } /* *=========================================================================== * ipmacsec_lmi_secy_rx_sa_info_init *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_secy_sa_info * ipmacsec_lmi_secy_rx_sa_info_init(Ipmacsec_secy_sa_info *sa_info, Ip_u32 nextPN, Ip_u32 lowestPN) { if (!sa_info) { return IP_NULL; } ipcom_memset(sa_info, 0, sizeof(Ipmacsec_secy_sa_info)); sa_info->config.rx.nextPN = nextPN; sa_info->config.rx.lowestPN = lowestPN; return sa_info; } /* *=========================================================================== * ipmacsec_lmi_secy_tx_sa_info_init *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_secy_sa_info * ipmacsec_lmi_secy_tx_sa_info_init(Ipmacsec_secy_sa_info *sa_info, Ip_u32 nextPN, Ipmacsec_confidentiality confidentiality) { if (!sa_info) { return IP_NULL; } ipcom_memset(sa_info, 0, sizeof(Ipmacsec_secy_sa_info)); sa_info->config.tx.nextPN = nextPN; sa_info->config.tx.confidentiality = confidentiality; return sa_info; } /* *=========================================================================== * ipmacsec_lmi_secy_rx_sa_ctrl_init *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_secy_sa_ctrl * ipmacsec_lmi_secy_rx_sa_ctrl_init(Ipmacsec_secy_sa_ctrl *sa_ctrl, Ipmacsec_enable_flag enableRx, Ip_u32 updtNextPN, Ip_u32 updtLowestPN) { if (!sa_ctrl || !IPMACSEC_ENABLE_FLAG_VALID(enableRx)) { return IP_NULL; } ipcom_memset(sa_ctrl, 0, sizeof(Ipmacsec_secy_sa_ctrl)); sa_ctrl->rx.enableRx = enableRx; sa_ctrl->rx.updtNextPN = updtNextPN; sa_ctrl->rx.updtLowestPN = updtLowestPN; return sa_ctrl; } /* *=========================================================================== * ipmacsec_lmi_secy_tx_sa_ctrl_init *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_secy_sa_ctrl * ipmacsec_lmi_secy_tx_sa_ctrl_init(Ipmacsec_secy_sa_ctrl *sa_ctrl, Ipmacsec_enable_flag enableTx) { if (!sa_ctrl || !IPMACSEC_ENABLE_FLAG_VALID(enableTx)) { return IP_NULL; } ipcom_memset(sa_ctrl, 0, sizeof(Ipmacsec_secy_sa_ctrl)); sa_ctrl->tx.enableTx = enableTx; return sa_ctrl; } /* *=========================================================================== * ipmacsec_lmi_secy_create_rx_sc *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_create_rx_sc(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sci) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RX_SC_CREATE, sci, IPMACSEC_SCI_LEN); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_delete_rx_sc *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_delete_rx_sc(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sci) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RX_SC_DELETE, sci, IPMACSEC_SCI_LEN); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_rx_sc_status *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_rx_sc_status(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, Ipmacsec_buffer *info) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !info) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } 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; } if (sci) { ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RX_SC_STATUS, sci, IPMACSEC_SCI_LEN); } else { ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RX_SC_LIST, IP_NULL, 0); } if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } if (sci) { Ipmacsec_secy_sc_info sc_info; ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_RX_SC_STATUS, &sc_info, sizeof(sc_info)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } (void)ipmacsec_buf_append(info, (Ip_u8 *)&sc_info, sizeof(sc_info)); ret = IPMACSEC_LMIERR_NONE; /* Even if we fail to append, we still succeed since we got info back and * caller may not have supplied enough buffer space (intentionally or not) */ } else { ret = ipmacsec_lmi_cmd_parse_response_pbuf(&response, ifname, IPMACSEC_LMICMD_SECY_RX_SC_LIST, info); } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_create_tx_sc *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_create_tx_sc(IPMACSEC_LMI_HANDLE lh, char *ifname) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SC_CREATE, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_delete_tx_sc *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_delete_tx_sc(IPMACSEC_LMI_HANDLE lh, char *ifname) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SC_DELETE, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_tx_sc_status *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_tx_sc_status(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sc_info *sc_info) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sc_info) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } 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; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SC_STATUS, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_TX_SC_STATUS, sc_info, sizeof(Ipmacsec_secy_sc_info)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_create_rx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_create_rx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_descriptor *sa_desc, Ipmacsec_secy_sa_info *sa_info) { struct Ip_nlmsghdr *nlreq = IP_NULL; Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ipmacsec_secy_sa_info default_sa_info, *sai = IP_NULL; if (!ifname || !sa_desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (IPMACSEC_INVALID_SCI(sa_desc->sci) || IPMACSEC_INVALID_AN(sa_desc->an)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (!sa_info) { ipcom_memset(&default_sa_info, 0, sizeof(default_sa_info)); sai = &default_sa_info; } else { sai = sa_info; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, &nlreq, ifname, IPMACSEC_LMICMD_SECY_RX_SA_CREATE, sa_desc, sizeof(Ipmacsec_secy_sa_descriptor)); if (ipmacsec_nlcmd_add_param(&request, nlreq, sai, sizeof(Ipmacsec_secy_sa_info)) < (int)sizeof(Ipmacsec_secy_sa_info)) { ret = IPMACSEC_LMIERR_NETLINK_PARAM_ERROR; goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_delete_rx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_delete_rx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_descriptor *sa_desc) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sa_desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (IPMACSEC_INVALID_SCI(sa_desc->sci) || IPMACSEC_INVALID_AN(sa_desc->an)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RX_SA_DELETE, sa_desc, sizeof(Ipmacsec_secy_sa_descriptor)); ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_control_rx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_control_rx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_descriptor *sa_desc, Ipmacsec_secy_sa_ctrl *sa_ctrl) { struct Ip_nlmsghdr *nlreq = IP_NULL; Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sa_desc || !sa_ctrl) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (IPMACSEC_INVALID_SCI(sa_desc->sci) || IPMACSEC_INVALID_AN(sa_desc->an)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (!IPMACSEC_ENABLE_FLAG_VALID(sa_ctrl->rx.enableRx)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, &nlreq, ifname, IPMACSEC_LMICMD_SECY_RX_SA_CONTROL, sa_desc, sizeof(Ipmacsec_secy_sa_descriptor)); if (ipmacsec_nlcmd_add_param(&request, nlreq, sa_ctrl, sizeof(Ipmacsec_secy_sa_ctrl)) < (int)sizeof(Ipmacsec_secy_sa_ctrl)) { ret = IPMACSEC_LMIERR_NETLINK_PARAM_ERROR; goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_rx_sa_status *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_rx_sa_status(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, int an, Ip_u32 ref, Ipmacsec_buffer *info) { return ipmacsec_lmi_secy_get_sa_status(lh, ifname, sci, an, ref, IPMACSEC_RX, info); } /* *=========================================================================== * ipmacsec_lmi_secy_create_tx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_create_tx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_descriptor *sa_desc, Ipmacsec_secy_sa_info *sa_info) { struct Ip_nlmsghdr *nlreq = IP_NULL; Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ipmacsec_secy_sa_info default_sa_info, *sai = IP_NULL; if (!ifname || !sa_desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } /* TX SCI is not required for this operation */ if (IPMACSEC_INVALID_AN(sa_desc->an)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (!sa_info) { ipcom_memset(&default_sa_info, 0, sizeof(default_sa_info)); sai = &default_sa_info; } else { if (!IPMACSEC_CONFIDENTIALITY_VALID(sa_info->config.tx.confidentiality)) return IPMACSEC_LMIERR_INVALID_PARAMETER; sai = sa_info; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, &nlreq, ifname, IPMACSEC_LMICMD_SECY_TX_SA_CREATE, sa_desc, sizeof(Ipmacsec_secy_sa_descriptor)); if (ipmacsec_nlcmd_add_param(&request, nlreq, sai, sizeof(Ipmacsec_secy_sa_info)) < (int)sizeof(Ipmacsec_secy_sa_info)) { ret = IPMACSEC_LMIERR_NETLINK_PARAM_ERROR; goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_delete_tx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_delete_tx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_descriptor *sa_desc) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sa_desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } /* TX SCI is not required for this operation */ if (IPMACSEC_INVALID_AN(sa_desc->an)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SA_DELETE, sa_desc, sizeof(Ipmacsec_secy_sa_descriptor)); ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_control_tx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_control_tx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_descriptor *sa_desc, Ipmacsec_secy_sa_ctrl *sa_ctrl) { struct Ip_nlmsghdr *nlreq = IP_NULL; Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sa_desc || !sa_ctrl) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } /* TX SCI is not required for this operation */ if (IPMACSEC_INVALID_AN(sa_desc->an)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (!IPMACSEC_ENABLE_FLAG_VALID(sa_ctrl->tx.enableTx)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, &nlreq, ifname, IPMACSEC_LMICMD_SECY_TX_SA_CONTROL, sa_desc, sizeof(Ipmacsec_secy_sa_descriptor)); if (ipmacsec_nlcmd_add_param(&request, nlreq, sa_ctrl, sizeof(Ipmacsec_secy_sa_ctrl)) < (int)sizeof(Ipmacsec_secy_sa_ctrl)) { ret = IPMACSEC_LMIERR_NETLINK_PARAM_ERROR; goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_enable_tx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_enable_tx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 an, Ip_u32 ref, Ip_bool enable) { Ipmacsec_secy_sa_descriptor sa_desc; Ipmacsec_secy_sa_ctrl sa_ctrl; if (!ifname || IPMACSEC_INVALID_AN(an)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (ipmacsec_lmi_secy_sa_descriptor_init(&sa_desc, IP_NULL, an, IPMACSEC_TX, ref, IP_NULL) == IP_NULL) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (ipmacsec_lmi_secy_tx_sa_ctrl_init(&sa_ctrl, (enable ? IPMACSEC_ENABLEFLAG_ON : IPMACSEC_ENABLEFLAG_OFF))== IP_NULL) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } return ipmacsec_lmi_secy_control_tx_sa(lh, ifname, &sa_desc, &sa_ctrl); } /* *=========================================================================== * ipmacsec_lmi_secy_get_tx_sa_status *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_tx_sa_status(IPMACSEC_LMI_HANDLE lh, char *ifname, int an, Ip_u32 ref, Ipmacsec_buffer *info) { return ipmacsec_lmi_secy_get_sa_status(lh, ifname, IP_NULL, an, ref, IPMACSEC_TX, info); } /* *=========================================================================== * ipmacsec_lmi_secy_set_tx_sci *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_tx_sci(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sci) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SCI, sci, IPMACSEC_SCI_LEN); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_tx_sci *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_tx_sci(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sci) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } 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; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SCI, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_TX_SCI, sci, IPMACSEC_SCI_LEN); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_set_confidentialityOffset *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_confidentialityOffset(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u16 confidentialityOffset) { Ip_u16 val = confidentialityOffset; if (!IPMACSEC_SECY_VERIFY_CONFIDENTIALITY_OFFSET(confidentialityOffset)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } return ipmacsec_lmi_cmd_send_u16(lh, ifname, IPMACSEC_LMICMD_SECY_CONFIDENTIALITY_OFFSET, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_confidentialityOffset *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_confidentialityOffset(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u16 *confidentialityOffset) { return ipmacsec_lmi_cmd_send_u16(lh, ifname, IPMACSEC_LMICMD_SECY_CONFIDENTIALITY_OFFSET, confidentialityOffset, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_cipher_suite_id_resolve *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_cipher_suite_id_resolve(IP_CONST Ipmacsec_cipher_suite_index cipher_suite_index, Ip_u8 *cipher_suite_id) { if (!IPMACSEC_SECY_VERIFY_CIPHER_SUITE_INDEX(cipher_suite_index) || !cipher_suite_id) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (ipmacsec_crypto_cipher_suite_id_resolve(cipher_suite_index, cipher_suite_id) != 0) { return IPMACSEC_LMIERR_CIPHER_SUITE_NOT_SUPPORTED; } return IPMACSEC_LMIERR_NONE; } /* *=========================================================================== * ipmacsec_lmi_cipher_suite_index_resolve *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_cipher_suite_index_resolve(IP_CONST Ip_u8 *cipher_suite_id, Ipmacsec_cipher_suite_index *cipher_suite_index) { if (!cipher_suite_id || !cipher_suite_index) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (ipmacsec_crypto_cipher_suite_index_resolve(cipher_suite_id, cipher_suite_index) != 0) { return IPMACSEC_LMIERR_CIPHER_SUITE_NOT_SUPPORTED; } return IPMACSEC_LMIERR_NONE; } /* *=========================================================================== * ipmacsec_lmi_cipher_suite_name *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC IP_CONST char * ipmacsec_lmi_cipher_suite_name(IP_CONST Ipmacsec_cipher_suite_index cipher_suite_index) { return ipmacsec_crypto_cipher_suite_name(cipher_suite_index); } /* *=========================================================================== * ipmacsec_lmi_secy_set_cipher_suite *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_cipher_suite(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_cipher_suite_index cipher_suite_index) { Ip_u32 val = (Ip_u32)cipher_suite_index; if (!IPMACSEC_SECY_VERIFY_CIPHER_SUITE_INDEX(cipher_suite_index)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_SECY_CURRENT_CIPHER_SUITE, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_cipher_suite *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_cipher_suite(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_ciphersuite_descriptor *cipher_suite_desc) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !cipher_suite_desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } ipcom_memset(cipher_suite_desc,0, sizeof(Ipmacsec_ciphersuite_descriptor)); 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; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_CURRENT_CIPHER_SUITE, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_CURRENT_CIPHER_SUITE, cipher_suite_desc, sizeof(Ipmacsec_ciphersuite_descriptor)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_cipher_suite_info *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_cipher_suite_info(IPMACSEC_LMI_HANDLE lh, char *ifname, IP_CONST Ipmacsec_cipher_suite_index cipher_suite_index, Ipmacsec_ciphersuite_descriptor *cipher_suite_desc) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ip_u32 val = (Ip_u32)cipher_suite_index; if (!IPMACSEC_SECY_VERIFY_CIPHER_SUITE_INDEX(cipher_suite_index)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } if (!ifname || !cipher_suite_desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } ipcom_memset(cipher_suite_desc,0, sizeof(Ipmacsec_ciphersuite_descriptor)); 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; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_CIPHER_SUITE_INFO, &val, sizeof(val)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_CIPHER_SUITE_INFO, cipher_suite_desc, sizeof(Ipmacsec_ciphersuite_descriptor)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_cipher_suite_info_list *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_cipher_suite_info_list(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_buffer *desc) { Ipmacsec_buffer request; Ipmacsec_buffer response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !desc || !IPMACSEC_BUF_VERIFY(desc)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_WIPE(desc); 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; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_CIPHER_SUITE_LIST, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response_pbuf(&response, ifname, IPMACSEC_LMICMD_SECY_CIPHER_SUITE_LIST, desc); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_maxRxSCs *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_maxRxSCs(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u16 *maxRxSCs) { return ipmacsec_lmi_cmd_send_u16(lh, ifname, IPMACSEC_LMICMD_SECY_MAX_RX_SC, maxRxSCs, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_maxRxKeys *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_maxRxKeys(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u16 *maxRxKeys) { return ipmacsec_lmi_cmd_send_u16(lh, ifname, IPMACSEC_LMICMD_SECY_MAX_RX_KEYS, maxRxKeys, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_maxTxKeys *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_maxTxKeys(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u16 *maxTxKeys) { return ipmacsec_lmi_cmd_send_u16(lh, ifname, IPMACSEC_LMICMD_SECY_MAX_TX_KEYS, maxTxKeys, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_pn_threshold *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_pn_threshold(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u32 threshold) { Ip_u32 val = threshold; return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_SECY_PN_THRESHOLD, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_pn_threshold *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_pn_threshold(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u32 *threshold) { return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_SECY_PN_THRESHOLD, threshold, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_set_info_notification *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_info_notification(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool on) { Ipmacsec_buffer request; Ip_bool turnOn = on; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_INFO_NOTIFY, &turnOn, sizeof(turnOn)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_info_notification *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_info_notification(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *on) { Ipmacsec_buffer request, response; Ip_bool onStatus = IP_FALSE; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !on) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_INFO_NOTIFY, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_INFO_NOTIFY, &onStatus, sizeof(onStatus)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } *on = onStatus; err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_numActiveRxSCs *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_numActiveRxSCs(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u16 *numActiveRxSCs) { return ipmacsec_lmi_cmd_send_u16(lh, ifname, IPMACSEC_LMICMD_SECY_NUM_RX_SC_ACTIVE, numActiveRxSCs, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_numCreatedRxSCs *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_numCreatedRxSCs(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u16 *numCreatedRxSCs) { return ipmacsec_lmi_cmd_send_u16(lh, ifname, IPMACSEC_LMICMD_SECY_NUM_RX_SC_CREATED, numCreatedRxSCs, IPMACSEC_LMICMD_ISGET); } #ifdef IPMACSEC_USE_STATS /* *=========================================================================== * ipmacsec_lmi_secy_get_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_stats *secy_stats) { Ipmacsec_buffer request, response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !secy_stats) { ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_STATS, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_STATS, secy_stats, sizeof(Ipmacsec_secy_stats)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } #endif /* *=========================================================================== * ipmacsec_lmi_secy_reset_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_reset_stats(IPMACSEC_LMI_HANDLE lh, char *ifname) { Ipmacsec_buffer request; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname) { ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPMACSEC_BUF_INIT(&request); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_set_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RESET_STATISTICS, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, IP_NULL); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_set_ControlledPortEnabled *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_ControlledPortEnabled(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool cp_enabled) { Ip_bool val = cp_enabled; return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_CONTROLLED_PORT_ENABLED, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_ControlledPortEnabled *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_ControlledPortEnabled(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *cp_enabled) { return ipmacsec_lmi_cmd_send_bool(lh, ifname, IPMACSEC_LMICMD_CONTROLLED_PORT_ENABLED, cp_enabled, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_MAC_Enabled *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_MAC_Enabled(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *mac_enabled, Ip_bool cp) { return ipmacsec_lmi_secy_cp_get_cmd_bool(lh, ifname, IPMACSEC_LMICMD_PORT_MAC_ENABLED, mac_enabled, cp); } /* *=========================================================================== * ipmacsec_lmi_secy_get_MAC_Operational *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_MAC_Operational(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *mac_oper, Ip_bool cp) { return ipmacsec_lmi_secy_cp_get_cmd_bool(lh, ifname, IPMACSEC_LMICMD_PORT_MAC_OPER, mac_oper, cp); } /* *=========================================================================== * ipmacsec_lmi_secy_get_operPointToPointMAC *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_operPointToPointMAC(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool *oper_ptp_mac, Ip_bool cp) { return ipmacsec_lmi_secy_cp_get_cmd_bool(lh, ifname, IPMACSEC_LMICMD_PORT_OPER_PTP_MAC, oper_ptp_mac, cp); } /* *=========================================================================== * ipmacsec_lmi_secy_set_adminPointToPointMAC *=========================================================================== * Description: * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_set_adminPointToPointMAC(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_portif_admin_ptp_mac_val admin_ptp_mac) { Ip_u32 val =admin_ptp_mac ; if ((admin_ptp_mac != IP_PORTIF_ADMIN_PTP_MAC_FORCE_AUTO) && (admin_ptp_mac != IP_PORTIF_ADMIN_PTP_MAC_FORCE_TRUE) && (admin_ptp_mac != IP_PORTIF_ADMIN_PTP_MAC_FORCE_FALSE)) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_PORT_ADMIN_PTP_MAC, &val, IPMACSEC_LMICMD_ISSET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_adminPointToPointMAC *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_adminPointToPointMAC(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_portif_admin_ptp_mac_val *admin_ptp_mac) { return ipmacsec_lmi_cmd_send_u32(lh, ifname, IPMACSEC_LMICMD_PORT_ADMIN_PTP_MAC, (Ip_u32 *)admin_ptp_mac, IPMACSEC_LMICMD_ISGET); } /* *=========================================================================== * ipmacsec_lmi_secy_get_port_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_port_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipnet_portif_stats *port_stats, Ip_bool cp) { Ipmacsec_buffer request, response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ip_bool isCP = cp; if (!ifname || !port_stats) { ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_PORT_STATISTICS, &isCP, sizeof(isCP)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_PORT_STATISTICS, port_stats, sizeof(Ipnet_portif_stats)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } #ifdef IPMACSEC_USE_STATS /* *=========================================================================== * ipmacsec_lmi_secy_get_rx_sc_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_rx_sc_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sc_stats *sc_stats, Ip_u8 *sci) { Ipmacsec_buffer request, response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sc_stats || !sci) { ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RX_SC_STATS, sci, IPMACSEC_SCI_LEN); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_RX_SC_STATS, sc_stats, sizeof(Ipmacsec_secy_sc_stats)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_tx_sc_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_tx_sc_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sc_stats *sc_stats) { Ipmacsec_buffer request, response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; if (!ifname || !sc_stats) { ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SC_STATS, IP_NULL, 0); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_TX_SC_STATS, sc_stats, sizeof(Ipmacsec_secy_sc_stats)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_rx_sa_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_rx_sa_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_stats *sa_stats, Ip_u8 *sci, Ip_u8 an, Ip_u32 ref) { Ipmacsec_buffer request, response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ipmacsec_secy_sa_descriptor sa_desc; if (!ifname || !sa_stats || !sci || (an >= IPMACSEC_MAX_SA)) { ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ipcom_memset(&sa_desc, 0, sizeof(sa_desc)); IPMACSEC_COPY_SCI(sa_desc.sci, sci); sa_desc.dir = IPMACSEC_RX; sa_desc.an = an; sa_desc.ref = ref; ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_RX_SA_STATS, &sa_desc, sizeof(sa_desc)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_RX_SA_STATS, sa_stats, sizeof(Ipmacsec_secy_sa_stats)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_get_tx_sa_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_get_tx_sa_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_sa_stats *sa_stats, Ip_u8 an, Ip_u32 ref) { Ipmacsec_buffer request, response; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ipmacsec_secy_sa_descriptor sa_desc; if (!ifname || !sa_stats || (an >= IPMACSEC_MAX_SA)) { ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPMACSEC_BUF_INIT(&request); IPMACSEC_BUF_INIT(&response); if (ipmacsec_nlmsg_alloc(&request) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (ipmacsec_nlmsg_alloc(&response) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ipcom_memset(&sa_desc, 0, sizeof(sa_desc)); sa_desc.dir = IPMACSEC_TX; sa_desc.an = an; sa_desc.ref = ref; ret = ipmacsec_lmi_secy_get_cmd_append(&request, IP_NULL, ifname, IPMACSEC_LMICMD_SECY_TX_SA_STATS, &sa_desc, sizeof(sa_desc)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_send(IPMACSEC_LMI_TO_NETLINK_HANDLE(lh), &request, &response); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } ret = ipmacsec_lmi_cmd_parse_response(&response, ifname, IPMACSEC_LMICMD_SECY_TX_SA_STATS, sa_stats, sizeof(Ipmacsec_secy_sa_stats)); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } err_out: ipmacsec_nlmsg_free(&request); ipmacsec_nlmsg_free(&response); return ret; } #endif /* *=========================================================================== * ipmacsec_lmi_secy_print_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_stats(IPMACSEC_LMI_HANDLE lh, char *ifname) { #ifdef IPMACSEC_USE_STATS Ipmacsec_secy_stats secy_stats; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; ipcom_memset(&secy_stats, 0, sizeof(secy_stats)); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Statistics:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "===============\n"); /* retrieve secy_stats */ ret = ipmacsec_lmi_secy_get_stats(lh, ifname, &secy_stats); if (ret != IPMACSEC_LMIERR_NONE) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "*** Failed to retrieve stats ***\n"); goto err_out; } ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Validation:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "----------\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsUntagged: %llu, ", secy_stats.InPktsUntagged); ipcom_printf( "InPktsNoTag: %llu, ", secy_stats.InPktsNoTag); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsBadTag: %llu, ", secy_stats.InPktsBadTag); ipcom_printf( "InPktsUnknownSCI: %llu, ", secy_stats.InPktsUnknownSCI); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InPktsNoSCI: %llu, ", secy_stats.InPktsNoSCI); ipcom_printf( "InPktsOverrun: %llu, ", secy_stats.InPktsOverrun); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "InOctetsValidated: %llu, ", secy_stats.InOctetsValidated); ipcom_printf( "InOctetsDecrypted: %llu", secy_stats.InOctetsDecrypted); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Generation:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "----------\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "OutPktsUntagged: %llu, ", secy_stats.OutPktsUntagged); ipcom_printf( "OutPktsTooLong: %llu, ", secy_stats.OutPktsTooLong); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "OutOctetsProtected: %llu, ", secy_stats.OutOctetsProtected); ipcom_printf( "OutOctetsEncrypted: %llu", secy_stats.OutOctetsEncrypted); ipcom_printf("\n"); err_out: ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); return IPMACSEC_LMIERR_NONE; #else IPCOM_UNUSED_ARG(lh); IPCOM_UNUSED_ARG(ifname); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "*** SECY Statistics Gathering Disabled ***\n"); return IPMACSEC_LMIERR_NOT_SUPPORTED; #endif } /* *=========================================================================== * ipmacsec_lmi_secy_print_port_stats *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_print_port_stats(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_bool cp) { #ifdef IPMACSEC_USE_STATS Ipnet_portif_stats port_stats; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; ipcom_memset(&port_stats, 0, sizeof(port_stats)); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY %s Port Statistics:\n", (cp ? "Controlled" : "Uncontrolled")); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "================================\n"); /* retrieve port_stats */ ret = ipmacsec_lmi_secy_get_port_stats(lh, ifname, &port_stats, cp); if (ret != IPMACSEC_LMIERR_NONE) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "*** Failed to retrieve stats ***\n"); goto err_out; } ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "ifInOctets: %llu, ", port_stats.ifInOctets); ipcom_printf( "ifInUcastPkts: %llu, ", port_stats.ifInUcastPkts); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "ifInMulticastPkts: %llu, ", port_stats.ifInMulticastPkts); ipcom_printf( "ifInBroadcastPkts: %llu, ", port_stats.ifInBroadcastPkts); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "ifInDiscards: %llu, ", port_stats.ifInDiscards); ipcom_printf( "ifInErrors: %llu, ", port_stats.ifInErrors); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "ifOutOctets: %llu, ", port_stats.ifOutOctets); ipcom_printf( "ifOutUcastPkts: %llu", port_stats.ifOutUcastPkts); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "ifOutMulticastPkts: %llu, ", port_stats.ifOutMulticastPkts); ipcom_printf( "ifOutBroadcastPkts: %llu, ", port_stats.ifOutBroadcastPkts); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "ifOutErrors: %llu", port_stats.ifOutErrors); ipcom_printf("\n"); err_out: ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); return IPMACSEC_LMIERR_NONE; #else IPCOM_UNUSED_ARG(lh); IPCOM_UNUSED_ARG(ifname); IPCOM_UNUSED_ARG(cp); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "*** SECY Statistics Gathering Disabled ***\n"); return IPMACSEC_LMIERR_NOT_SUPPORTED; #endif } /* *=========================================================================== * ipmacsec_lmi_secy_print_key_info *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_secy_print_key_info(IPMACSEC_LMI_HANDLE lh, char *ifname, Ipmacsec_secy_key_id *key_id, IP_CONST char *prefix) { Ipmacsec_buffer key_info; Ipmacsec_secy_key_descriptor key_desc; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; char str[IPMACSEC_DISPLAY_BUF_LEN]; IP_CONST char *pref = (prefix ? prefix : ""); Ip_u32 keyNum = 0, remlen = 0; /* Allocate enough buffer space for key descriptors */ IPMACSEC_BUF_INIT(&key_info); if (ipmacsec_nlmsg_alloc(&key_info) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } if (key_id) { ipcom_memset(&key_desc, 0, sizeof(key_desc)); key_desc.key_id.val = key_id->val; } ret = ipmacsec_lmi_secy_get_key_info(lh, ifname, (key_id ? &key_desc : IP_NULL), &key_info); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } for (keyNum = 0;;keyNum++) { Ipmacsec_secy_key_descriptor *kdesc = (Ipmacsec_secy_key_descriptor *) ipmacsec_buf_ptr(&key_info, (Ip_u32)(keyNum*sizeof(Ipmacsec_secy_key_descriptor)), &remlen); if (!kdesc) { if (keyNum==0) ipcom_printf("%s*** No Keys Installed ***\n", pref); break; } ipmacsec_lmi_strf_key_desc(kdesc, pref, str, sizeof(str)); ipcom_printf("%s", str); ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_KEY_DELIMITER, pref); } err_out: ipmacsec_nlmsg_free(&key_info); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_print_rx_sc *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_secy_print_rx_sc(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, IP_CONST char *prefix, Ip_bool display_stats) { Ipmacsec_buffer info; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; char str[IPMACSEC_DISPLAY_BUF_LEN]; IP_CONST char *pref = (prefix ? prefix : ""); Ip_u32 scNum = 0, remlen = 0; /* Allocate enough buffer space for key descriptors */ IPMACSEC_BUF_INIT(&info); if (ipmacsec_nlmsg_alloc(&info) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_rx_sc_status(lh, ifname, sci, &info); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } for (scNum = 0;;scNum++) { Ipmacsec_secy_sc_info *sc_info = (Ipmacsec_secy_sc_info *) ipmacsec_buf_ptr(&info, (Ip_u32)(scNum*sizeof(Ipmacsec_secy_sc_info)), &remlen); if (!sc_info) break; ipmacsec_lmi_strf_sc_info(sc_info, pref, str, sizeof(str)); ipcom_printf("%s", str); if (display_stats) { ipcom_printf("\n"); (void)ipmacsec_lmi_secy_print_rx_sc_stats(lh, ifname, sc_info->sci); } ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER, pref); } err_out: if (scNum == 0) { ipcom_printf("%s*** No RX SCs found ***\n", pref); ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER, pref); } ipmacsec_nlmsg_free(&info); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_print_tx_sc *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_secy_print_tx_sc(IPMACSEC_LMI_HANDLE lh, char *ifname, IP_CONST char *prefix, Ip_bool display_stats) { Ipmacsec_secy_sc_info sc_info; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; char str[IPMACSEC_DISPLAY_BUF_LEN]; IP_CONST char *pref = (prefix ? prefix : ""); ret = ipmacsec_lmi_secy_get_tx_sc_status(lh, ifname, &sc_info); if (ret != IPMACSEC_LMIERR_NONE) { ipcom_printf("%s*** No TX SCs found ***\n", pref); ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SA_DELIMITER, pref); return ret; } ipmacsec_lmi_strf_sc_info(&sc_info, pref, str, sizeof(str)); ipcom_printf("%s", str); if (display_stats) { ipcom_printf("\n"); (void)ipmacsec_lmi_secy_print_tx_sc_stats(lh, ifname); } ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER, pref); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_print_rx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_secy_print_rx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, Ip_u8 *sci, int an, Ip_u32 ref, IP_CONST char *prefix, Ip_bool display_stats) { return ipmacsec_lmi_secy_print_sa(lh, ifname, sci, an, ref, IPMACSEC_RX, prefix, display_stats); } /* *=========================================================================== * ipmacsec_lmi_secy_print_tx_sa *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_secy_print_tx_sa(IPMACSEC_LMI_HANDLE lh, char *ifname, int an, Ip_u32 ref, IP_CONST char *prefix, Ip_bool display_stats) { return ipmacsec_lmi_secy_print_sa(lh, ifname, IP_NULL, an, ref, IPMACSEC_TX, prefix, display_stats); } /* *=========================================================================== * ipmacsec_lmi_secy_print_cipher_suite_info *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_secy_print_cipher_suite_info(Ipmacsec_ciphersuite_descriptor *desc, IP_CONST char *prefix, Ip_bool include_details) { IP_CONST char *pref = (prefix ? prefix : ""); if (!desc) { return IPMACSEC_LMIERR_INVALID_PARAMETER; } ipcom_printf("%s" "name: %s", pref, desc->name); ipcom_printf("\n"); ipcom_printf("%s" "selector index: %u, identifier: " IPMACSEC_CIPHER_SUITE_ID_STRING, pref, desc->index, IPMACSEC_CIPHER_SUITE_ID_OCTETS(desc->id)); ipcom_printf("\n"); if (!include_details) return 0; ipcom_printf("%s" "integrityProtection: %s, confidentialityProtection: %s", pref, IPMACSEC_BOOL_STRING(desc->integrityProtection), IPMACSEC_BOOL_STRING(desc->confidentialityProtection)); ipcom_printf("\n"); ipcom_printf("%s" "offsetConfidentiality: %s, changesDataLength: %s, mandatory: %s", pref, IPMACSEC_BOOL_STRING(desc->offsetConfidentiality), IPMACSEC_BOOL_STRING(desc->changesDataLength), IPMACSEC_BOOL_STRING(desc->mandatory)); ipcom_printf("\n"); ipcom_printf("%s" "key_bits: %u, icv_bits: %u", pref, desc->key_bits, desc->icv_bits); ipcom_printf("\n"); ipcom_printf("%s" "min_iv_bits: %llu, max_iv_bits: %llu", pref, desc->min_iv_bits, desc->max_iv_bits); ipcom_printf("\n"); return 0; } /* *=========================================================================== * ipmacsec_lmi_secy_print_cipher_suite_list *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC int ipmacsec_lmi_secy_print_cipher_suite_list(IPMACSEC_LMI_HANDLE lh, char *ifname, IP_CONST char *prefix, Ip_bool include_details) { Ipmacsec_buffer list; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ip_u32 csNum = 0, remlen = 0; IP_CONST char *pref = (prefix ? prefix : ""); /* Allocate enough buffer space for descriptors */ IPMACSEC_BUF_INIT(&list); if (ipmacsec_buf_alloc(&list, sizeof(Ipmacsec_ciphersuite_descriptor)*(__IPMACSEC_CIPHERSUITE_MAX-1)) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_cipher_suite_info_list(lh, ifname, &list); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } for (csNum = 0;;csNum++) { Ipmacsec_ciphersuite_descriptor *desc = (Ipmacsec_ciphersuite_descriptor *) ipmacsec_buf_ptr(&list, (Ip_u32)(csNum*sizeof(Ipmacsec_ciphersuite_descriptor)), &remlen); if (!desc) break; ipmacsec_lmi_secy_print_cipher_suite_info(desc, prefix, include_details); ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER, pref); } err_out: if (csNum == 0) { ipcom_printf("%s*** No Cipher Suites found ***\n", pref); ipcom_printf("%s" IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER, pref); } ipmacsec_buf_free(&list); return ret; } /* *=========================================================================== * ipmacsec_lmi_secy_print_port_info *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_lmi_secy_print_port_info(IPMACSEC_LMI_HANDLE lh, char *ifname, IP_CONST char *prefix, Ip_bool cp) { IP_CONST char *pref = (prefix ? prefix : ""); Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; IP_CONST char *err_str = "***retrieve failed***"; Ip_bool boolval; Ip_portif_admin_ptp_mac_val admin_p2p_mac; if (cp) { ret = ipmacsec_lmi_secy_get_ControlledPortEnabled(lh, ifname, &boolval); ipcom_printf("%s" "ControlledPortEnabled: %s, ", pref, ((ret == IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ret = ipmacsec_lmi_secy_get_adminPointToPointMAC(lh, ifname, &admin_p2p_mac); if (ret == IPMACSEC_LMIERR_NONE) { ipcom_printf("adminPointToPointMAC: %s", ipmacsec_secy_cp_adminPointToPointMAC_name(admin_p2p_mac)); } else { ipcom_printf("adminPointToPointMAC: %s, " , err_str); } ipcom_printf("\n"); } ret = ipmacsec_lmi_secy_get_MAC_Enabled(lh, ifname, &boolval, cp); ipcom_printf("%s" "MAC_Enabled: %s, ", pref, ((ret == IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ret = ipmacsec_lmi_secy_get_MAC_Operational(lh, ifname, &boolval, cp); ipcom_printf("MAC_Operational: %s, ", ((ret == IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ret = ipmacsec_lmi_secy_get_operPointToPointMAC(lh, ifname, &boolval, cp); ipcom_printf("operPointToPointMAC: %s", ((ret == IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ipcom_printf("\n"); return 0; } /* *=========================================================================== * ipmacsec_lmi_secy_dump *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: * */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_secy_dump(IPMACSEC_LMI_HANDLE lmi_handle, char *ifname, Ip_bool display_stats) { IPMACSEC_LMI_HANDLE lh = lmi_handle; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; IP_CONST char *err_str = "***retrieve failed***"; IP_CONST char *na_str = "*N/A*"; Ip_u8 sci[IPMACSEC_SCI_LEN]; Ip_bool boolval; Ip_u32 u32val; Ip_u16 u16val; Ipmacsec_validateFrames_type validateFrames = __IPMACSEC_SECY_VALIDATEFRAMES_INVALID; Ipmacsec_ciphersuite_descriptor cipher_suite_desc; Ipmacsec_buffer info; Ip_u32 scNum = 0, remlen = 0; (void)na_str; ipcom_printf(IPMACSEC_LMI_SECY_DUMP_DELIMITER); if (!ifname) { ipcom_printf("Cannot dump SecY info - ifname not specified\n"); ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out_no_warn; } if (!lh) { lh = ipmacsec_lmi_handle_create(); } if (!ipmacsec_lmi_secy_exists(lh, ifname)) { ipcom_printf("Cannot dump SecY info - SecY does not exist for interface %s\n", ifname); ret = IPMACSEC_LMIERR_SECY_DOESNOT_EXIST; goto err_out_no_warn; } ipcom_printf("####################################\n"); ipcom_printf("SecY Information for Interface %s:\n", ifname); ipcom_printf("####################################\n"); /* 1st display the control info */ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Control information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "========================\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Global:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "------\n"); ret = ipmacsec_lmi_secy_is_enabled(lh, ifname, &boolval); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "enabled: %s", ((ret==IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Generation:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "----------\n"); ret = ipmacsec_lmi_secy_get_protectFrames(lh, ifname, &boolval); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT3 "protectFrames: %s, ", ((ret==IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ret = ipmacsec_lmi_secy_get_alwaysIncludeSCI(lh, ifname, &boolval); ipcom_printf( "alwaysIncludeSCI: %s, ", ((ret==IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ret = ipmacsec_lmi_secy_get_useES(lh, ifname, &boolval); ipcom_printf( "useES: %s, ", ((ret==IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ret = ipmacsec_lmi_secy_get_useSCB(lh, ifname, &boolval); ipcom_printf( "useSCB: %s", ((ret==IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Validation:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "----------\n"); ret = ipmacsec_lmi_secy_get_validateFrames(lh, ifname, &validateFrames); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "validateFrames: %s, ", ipmacsec_secy_validateFrames_name(validateFrames)); else ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "validateFrames: %s, ", err_str); ret = ipmacsec_lmi_secy_get_replayProtect(lh, ifname, &boolval); ipcom_printf( "replayProtect: %s, ", ((ret==IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ret = ipmacsec_lmi_secy_get_replayWindow(lh, ifname, &u32val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf( "replayWindow: %u", u32val); else ipcom_printf( "replayWindow: %s", err_str); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); /* next display the SecY config info */ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Config information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "=======================\n"); ret = ipmacsec_lmi_secy_get_tx_sci(lh, ifname, sci); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "sci: " IPMACSEC_SCI_STRING, IPMACSEC_SCI_OCTETS(sci)); else ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "sci: %s", err_str); ipcom_printf("\n"); ret = ipmacsec_lmi_secy_get_maxRxSCs(lh, ifname, &u16val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "maxRxSCs: %u, ", u16val); else ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "maxRxSCs: %s, ", err_str); ret = ipmacsec_lmi_secy_get_maxRxKeys(lh, ifname, &u16val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf( "maxRxKeys: %u, ", u16val); else ipcom_printf( "maxRxKeys: %s, ", err_str); ret = ipmacsec_lmi_secy_get_maxTxKeys(lh, ifname, &u16val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf( "maxTxKeys: %u", u16val); else ipcom_printf( "maxTxKeys: %s", err_str); ipcom_printf("\n"); ret = ipmacsec_lmi_secy_get_pn_threshold(lh, ifname, &u32val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "pn_threshold: %u (0x%x), ", u32val, u32val); else ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "pn_threshold: %s, ", err_str); ret = ipmacsec_lmi_secy_get_info_notification(lh, ifname, &boolval); ipcom_printf( "info_notify: %s", ((ret==IPMACSEC_LMIERR_NONE) ? IPMACSEC_BOOL_STRING(boolval) : err_str)); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); /* next display the SecY Crypto config info */ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Crypto Config information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "==============================\n"); ret = ipmacsec_lmi_secy_get_confidentialityOffset(lh, ifname, &u16val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "confidentialityOffset: %u", u16val); else ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "confidentialityOffset: %s", err_str); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "Cipher Suite Details:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "--------------------\n"); ret = ipmacsec_lmi_secy_get_cipher_suite(lh, ifname, &cipher_suite_desc); if (ret == IPMACSEC_LMIERR_NONE) (void)ipmacsec_lmi_secy_print_cipher_suite_info(&cipher_suite_desc, IPMACSEC_LMI_SECY_DUMP_INDENT3, IP_TRUE); else ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "%s\n", err_str); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); /* next display the oper info */ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Operational information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "============================\n"); ret = ipmacsec_lmi_secy_get_numActiveRxSCs(lh, ifname, &u16val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "numActiveRxSCs: %u, ", u16val); else ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "numActiveRxSCs: %s, ", err_str); ret = ipmacsec_lmi_secy_get_numCreatedRxSCs(lh, ifname, &u16val); if (ret == IPMACSEC_LMIERR_NONE) ipcom_printf( "numCreatedRxSCs: %u", u16val); else ipcom_printf( "numCreatedRxSCs: %s", err_str); ipcom_printf("\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); /* next display the controlled and uncontrolled port info */ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Controlled Port information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "================================\n"); ret = ipmacsec_lmi_secy_print_port_info(lh, ifname, IPMACSEC_LMI_SECY_DUMP_INDENT2, IP_TRUE /*Controlled Port*/); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Uncontrolled Port information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "==================================\n"); ret = ipmacsec_lmi_secy_print_port_info(lh, ifname, IPMACSEC_LMI_SECY_DUMP_INDENT2, IP_FALSE /*Uncontrolled Port*/); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); /* next display the Key DB contents */ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Key information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "====================\n"); ret = ipmacsec_lmi_secy_print_key_info(lh, ifname, IP_NULL, IPMACSEC_LMI_SECY_DUMP_INDENT2); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 IPMACSEC_LMI_SECY_PRINT_SECTION_DELIMITER); /* next display the SC/SA info + optional stats */ /* Start with TX SC & corresponding SAs*/ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Tx SC information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "======================\n"); (void)ipmacsec_lmi_secy_print_tx_sc(lh, ifname, IPMACSEC_LMI_SECY_DUMP_INDENT2, display_stats); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Tx SA information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "======================\n"); (void)ipmacsec_lmi_secy_print_tx_sa(lh, ifname, -1, 0, IPMACSEC_LMI_SECY_DUMP_INDENT2, display_stats); /* Next the RX SCs and corresponding SAs */ ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Rx SC information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "======================\n"); (void)ipmacsec_lmi_secy_print_rx_sc(lh, ifname, IP_NULL, IPMACSEC_LMI_SECY_DUMP_INDENT2, display_stats); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "SECY Rx SA information:\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "======================\n"); /* Allocate enough buffer space for RX SC key descriptors */ IPMACSEC_BUF_INIT(&info); if (ipmacsec_nlmsg_alloc(&info) == IP_NULL) { ret = IPMACSEC_LMIERR_ALLOC_FAILED; goto err_out; } ret = ipmacsec_lmi_secy_get_rx_sc_status(lh, ifname, IP_NULL, &info); if (ret != IPMACSEC_LMIERR_NONE) { goto err_out; } for (scNum = 0;;scNum++) { Ipmacsec_secy_sc_info *sc_info = (Ipmacsec_secy_sc_info *) ipmacsec_buf_ptr(&info, (Ip_u32)(scNum*sizeof(Ipmacsec_secy_sc_info)), &remlen); if (!sc_info) break; (void)ipmacsec_lmi_secy_print_rx_sa(lh, ifname, sc_info->sci, -1, 0, IPMACSEC_LMI_SECY_DUMP_INDENT2, display_stats); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER); } if (scNum == 0) { ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 "*** No RX SAs found ***\n"); ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT2 IPMACSEC_LMI_SECY_PRINT_SC_DELIMITER); } /* Last optionally display Secy and CP/UCP Stats */ if (display_stats) { #ifndef IPMACSEC_USE_STATS ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "*** SECY Statistics Gathering Disabled ***\n"); #else (void)ipmacsec_lmi_secy_print_stats(lh, ifname); (void)ipmacsec_lmi_secy_print_port_stats(lh, ifname, 0); (void)ipmacsec_lmi_secy_print_port_stats(lh, ifname, 1); #endif } err_out: if (ret != IPMACSEC_LMIERR_NONE) ipcom_printf(IPMACSEC_LMI_SECY_DUMP_INDENT1 "*** ERROR - Results may be incomplete ***\n"); err_out_no_warn: ipcom_printf(IPMACSEC_LMI_SECY_DUMP_DELIMITER); if (!lmi_handle) { ipmacsec_lmi_handle_delete(lh); } return ret; } /* *=========================================================================== * ipmacsec_lmi_monitor_start *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_monitor_start(Ip_u32 timeout, Ip_bool exit_on_error, Ip_u32 *pid, void *callback, Ip_u32 nl_groups) { Ipmacsec_netlink_handle *nlhandle; struct Ip_timeval tv; Ip_u32 groups; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_UNSPECIFIED_ERROR; IPMACSEC_NL_CB callback_fn = (IPMACSEC_NL_CB)(callback ? callback : ipmacsec_lmi_monitor_callback); IPCOM_UNUSED_ARG(exit_on_error); if (pid) *pid = 0; tv.tv_sec = timeout; tv.tv_usec = 0; if (nl_groups) groups = nl_groups; else groups = IP_NLMSG_GROUP_MASK(IPMACSEC_NLGRP_NOTIFY) | IP_NLMSG_GROUP_MASK(IPMACSEC_NLGRP_MONITOR); nlhandle = ipmacsec_netlink_open(groups); if (!nlhandle) { ret = IPMACSEC_LMIERR_NETLINK_OPEN_ERROR; goto error_out; } /* Register */ ret = ipmacsec_netlink_register(nlhandle, callback_fn, &tv, IP_TRUE); if (ret < 0) { ret = IPMACSEC_LMIERR_NETLINK_REG_ERROR; goto error_out; } /* Invoke the netlink loop */ ipcom_printf("IPMACSEC-LMI-MONITOR: Starting (pid = 0x%x)\n", nlhandle->local_nladdr.nl_pid); if (pid) *pid = nlhandle->local_nladdr.nl_pid; ret = ipmacsec_netlink_loop(nlhandle); if (ret < 0) { ret = IPMACSEC_LMIERR_NETLINK_LOOP_ERROR;; } else if (ret > 0) { ret = IPMACSEC_LMIERR_NONE; } error_out: ipmacsec_netlink_close(nlhandle); ipcom_printf("IPMACSEC-LMI-MONITOR: Exiting with ret = %d (%s)\n", ret, ipmacsec_lmi_error_name(ret)); return ret; } /* *=========================================================================== * ipmacsec_lmi_monitor_exit *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_PUBLIC Ipmacsec_lmi_error ipmacsec_lmi_monitor_exit(Ip_u32 pid) { Ipmacsec_netlink_handle *nlhandle; /* a dummy handle to store pid */ if (!pid) { return IPMACSEC_LMIERR_INVALID_PID; } nlhandle=ipcom_malloc(sizeof(Ipmacsec_netlink_handle)); if (nlhandle==IP_NULL) return IPMACSEC_LMIERR_ALLOC_FAILED; nlhandle->local_nladdr.nl_pid = pid; if (ipmacsec_netlink_loop_exit(nlhandle) < 0) { ipcom_free(nlhandle); return IPMACSEC_LMIERR_UNSPECIFIED_ERROR; } ipcom_free(nlhandle); return IPMACSEC_LMIERR_NONE; } /* *=========================================================================== * ipmacsec_lmi_secy_setup_profile *=========================================================================== * Description: see "ipmacsec.h" * Parameters: * Returns: */ IP_GLOBAL Ipmacsec_lmi_error ipmacsec_lmi_secy_setup_profile(char *ifname, Ipmacsec_secy_profile *ut_profile) { IPMACSEC_LMI_HANDLE lh = IP_NULL; Ipmacsec_lmi_error ret = IPMACSEC_LMIERR_NONE; Ip_size_t len; char sysvar[256]; Ip_u8 sa, sci[IPMACSEC_SCI_LEN]; Ip_u16 sc; if (!ifname) { IPCOM_LOG0(ERR, "IPMACSEC-PROFILE: ifname not specified"); ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } if (!ut_profile) { IPCOM_LOG0(ERR, "IPMACSEC-PROFILE: profile not specified"); ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } IPCOM_LOG1(INFO, "IPMACSEC-PROFILE: Setting up Secy profile for interface %s", ifname); /* Create an LMI handle */ lh = ipmacsec_lmi_handle_create(); if (!lh) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to create LMI handle for interface %s", ifname); ret = IPMACSEC_LMIERR_HANDLE_CREATE_FAILED; goto err_out; } /* Verify that the SecY exists n the interface before doing anything */ if (!ipmacsec_lmi_secy_exists(lh, ifname)) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: SecY does not exist for interface %s", ifname); ret = IPMACSEC_LMIERR_SECY_DOESNOT_EXIST; goto err_out; } /* retrieve the SecY tx SCI if any (mandatory if useES is false) */ IPMACSEC_INVALIDATE_SCI(sci); if (ut_profile->sci_sysvar) { len = sizeof(sysvar); if (ipcom_sysvar_get(ut_profile->sci_sysvar, sysvar, &len)) { ret = ipmacsec_parse_sci_string(sysvar, sci); if (ret < 0) { IPCOM_LOG1(WARNING, "IPMACSEC-PROFILE: Failed to parse sci sysvar value for interface %s", ifname); } } else { IPCOM_LOG2(WARNING, "Failed to get %s for interface %s", ut_profile->sci_sysvar, ifname); } } else { IPCOM_LOG1(INFO, "IPMACSEC-PROFILE: sci sysvar not specified for interface %s", ifname); } if (IPMACSEC_INVALID_SCI(sci) && !ut_profile->useES) { IPCOM_LOG1(INFO, "IPMACSEC-PROFILE: sci value invalid while useES is false for interface %s", ifname); ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } /* 1st Disable the SecY to make sure everything is in the clear */ ret = ipmacsec_lmi_secy_enable(lh, ifname, IP_FALSE); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to disable SecY for interface %s", ifname); goto err_out; } /* Set the SecY parameters */ ret = ipmacsec_lmi_secy_set_tx_sci(lh, ifname, sci); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set tx sci for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_cipher_suite(lh, ifname, ut_profile->cipher_suite_index); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set cipher_suite for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_protectFrames(lh, ifname, ut_profile->protectFrames); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set protectFrames for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_alwaysIncludeSCI(lh, ifname, ut_profile->alwaysIncludeSCI); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set alwaysIncludeSCI for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_useES(lh, ifname, ut_profile->useES); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set useES for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_useSCB(lh, ifname, ut_profile->useSCB); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set useSCB for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_validateFrames(lh, ifname, ut_profile->validateFrames); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set validateFrames for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_replayProtect(lh, ifname, ut_profile->replayProtect); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set replayProtect for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_replayWindow(lh, ifname, ut_profile->replayWindow); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set replayWindow for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_confidentialityOffset(lh, ifname, ut_profile->confidentialityOffset); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set replayWindow for interface %s", ifname); goto err_out; } if (ut_profile->pn_threshold) { ret = ipmacsec_lmi_secy_set_pn_threshold(lh, ifname, ut_profile->pn_threshold); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set pn_threshold for interface %s", ifname); goto err_out; } } ret = ipmacsec_lmi_secy_set_info_notification(lh, ifname, ut_profile->info_notify); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set info_notification for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_ControlledPortEnabled(lh, ifname, ut_profile->cp_profile.ControlledPortEnabled); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set ControlledPortEnabled for interface %s", ifname); goto err_out; } ret = ipmacsec_lmi_secy_set_adminPointToPointMAC(lh, ifname, ut_profile->cp_profile.adminPointToPointMAC); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to set CP adminPointToPointMAC for interface %s", ifname); goto err_out; } /* Create the Tx SC */ ret = ipmacsec_lmi_secy_create_tx_sc(lh, ifname); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to create TX SC for interface %s", ifname); goto err_out; } /* Create any specified TX SAs */ for (sa=0; satx_sc_profile.sa_profile[sa]; Ipmacsec_sak_profile *sak_profile = sa_profile->sak_profile; /* Verify SA profile parameters */ if (!sa_profile->create) { IPCOM_LOG2(INFO, "IPMACSEC-PROFILE: Skipping TX SA profile #%u for interface %s", sa, ifname); continue; } if (IPMACSEC_INVALID_AN(sa_profile->an)) { IPCOM_LOG3(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Invalid TX SA AN value (%u) for interface %s", sa, sa_profile->an, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (!IPMACSEC_CONFIDENTIALITY_VALID(sa_profile->confidentiality)) { IPCOM_LOG3(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Invalid TX SA Confidentiality value (%u) for interface %s", sa, sa_profile->confidentiality, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (!IPMACSEC_ENABLE_FLAG_VALID(sa_profile->enableTx)) { IPCOM_LOG3(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Invalid TX SA enableTx value (%u) for interface %s", sa, sa_profile->enableTx, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (!sak_profile) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - No SAK profile specified for interface %s", sa, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (!sak_profile->key_matrial) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - No SAK Key material specified for interface %s", sa, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } /* Install the Key */ key_desc.key_id.val = sak_profile->key_id_val; key_desc.key_size = sak_profile->key_size; key_desc.key_type |= IPMACSEC_KEYTYPE_TRANSMIT; ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, sak_profile->key_matrial); if (ret != IPMACSEC_LMIERR_NONE) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Failed to install Key for interface %s", sa, ifname); goto err_out; } /* Init the SA descriptor, info and control, then create and set control for the SA */ if (ipmacsec_lmi_secy_sa_descriptor_init(&sa_desc, sci, sa_profile->an, IPMACSEC_TX, sa_profile->ref, &key_desc.key_id) == IP_NULL) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Failed to initialize SA descriptor for interface %s", sa, ifname); goto err_out; } if (ipmacsec_lmi_secy_tx_sa_info_init(&sa_info, sa_profile->nextPN, sa_profile->confidentiality) == IP_NULL) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Failed to initialize SA info for interface %s", sa, ifname); goto err_out; } ret = ipmacsec_lmi_secy_create_tx_sa(lh, ifname, &sa_desc, &sa_info); if (ret != IPMACSEC_LMIERR_NONE) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Failed to create SA for interface %s", sa, ifname); goto err_out; } if (sa_profile->enableTx != IPMACSEC_ENABLEFLAG_IGNORE) { if (ipmacsec_lmi_secy_tx_sa_ctrl_init(&sa_ctrl, sa_profile->enableTx) == IP_NULL) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Failed to initialize SA control for interface %s", sa, ifname); goto err_out; } ret = ipmacsec_lmi_secy_control_tx_sa(lh, ifname, &sa_desc, &sa_ctrl); if (ret != IPMACSEC_LMIERR_NONE) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: TX SA profile %u - Failed to control the SA for interface %s", sa, ifname); goto err_out; } } } /* Create any specified RX SCs and SAs */ for (sc=0; sc < IPMACSEC_MAX_RX_SC; sc++) { Ip_u8 rx_sci[IPMACSEC_SCI_LEN]; if (!ut_profile->rx_sc_profile[sc].create) { IPCOM_LOG2(INFO, "IPMACSEC-PROFILE: Skipping RX SC profile #%u for interface %s", sc, ifname); continue; } /* Any RX SC that is to be created requires a valid SCI value */ IPMACSEC_INVALIDATE_SCI(rx_sci); if (ut_profile->rx_sc_profile[sc].sci_sysvar) { len = sizeof(sysvar); if (ipcom_sysvar_get(ut_profile->rx_sc_profile[sc].sci_sysvar, sysvar, &len)) { ret = ipmacsec_parse_sci_string(sysvar, rx_sci); if (ret < 0) { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: Failed to parse rx_sci sysvar value for interface %s", ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } } else { IPCOM_LOG2(ERR, "Failed to get %s for interface %s", ut_profile->rx_sc_profile[sc].sci_sysvar, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } } else { IPCOM_LOG1(ERR, "IPMACSEC-PROFILE: rx_sci sysvar not specified for interface %s", ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (IPMACSEC_INVALID_SCI(rx_sci)) { IPCOM_LOG1(INFO, "IPMACSEC-PROFILE: rx_sci value invalid for interface %s", ifname); ret = IPMACSEC_LMIERR_INVALID_PARAMETER; goto err_out; } /* Create the RX SC */ ret = ipmacsec_lmi_secy_create_rx_sc(lh, ifname, rx_sci); if (ret != IPMACSEC_LMIERR_NONE ) { IPCOM_LOG9(ERR, "IPMACSEC-PROFILE: Failed to create RX SC " "(sci: %.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x) for interface %s", rx_sci[0],rx_sci[1],rx_sci[2],rx_sci[3], rx_sci[4],rx_sci[5],rx_sci[6],rx_sci[7], ifname); goto err_out; } /* Create any specified RX SAs */ for (sa=0; sarx_sc_profile[sc].sa_profile[sa]; Ipmacsec_sak_profile *sak_profile = sa_profile->sak_profile; /* Verify SA profile parameters */ if (!sa_profile->create) { IPCOM_LOG2(INFO, "IPMACSEC-PROFILE: Skipping RX SA profile #%u for interface %s", sa, ifname); continue; } if (IPMACSEC_INVALID_AN(sa_profile->an)) { IPCOM_LOG3(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Invalid RX SA AN value (%u) for interface %s", sa, sa_profile->an, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (sa_profile->lowestPN > sa_profile->nextPN) { IPCOM_LOG3(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Invalid lowestPN value (%u) for interface %s", sa, sa_profile->lowestPN, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (!IPMACSEC_ENABLE_FLAG_VALID(sa_profile->enableRx)) { IPCOM_LOG3(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Invalid RX SA enableRx value (%u) for interface %s", sa, sa_profile->enableRx, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (!sak_profile) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - No SAK profile specified for interface %s", sa, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } if (!sak_profile->key_matrial) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - No SAK Key material specified for interface %s", sa, ifname); ret = IPMACSEC_LMIERR_INVALID_PROFILE; goto err_out; } /* Install the Key */ key_desc.key_id.val = sak_profile->key_id_val; key_desc.key_size = sak_profile->key_size; key_desc.key_type |= IPMACSEC_KEYTYPE_RECEIVE; ret = ipmacsec_lmi_secy_key_install(lh, ifname, &key_desc, sak_profile->key_matrial); if (ret != IPMACSEC_LMIERR_NONE) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Failed to install Key for interface %s", sa, ifname); goto err_out; } /* Init the SA descriptor, info and control, then create and set control for the SA */ if (ipmacsec_lmi_secy_sa_descriptor_init(&sa_desc, rx_sci, sa_profile->an, IPMACSEC_RX, sa_profile->ref, &key_desc.key_id) == IP_NULL) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Failed to initialize SA descriptor for interface %s", sa, ifname); goto err_out; } if (ipmacsec_lmi_secy_rx_sa_info_init(&sa_info, sa_profile->nextPN, sa_profile->lowestPN) == IP_NULL) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Failed to initialize SA info for interface %s", sa, ifname); goto err_out; } ret = ipmacsec_lmi_secy_create_rx_sa(lh, ifname, &sa_desc, &sa_info); if (ret != IPMACSEC_LMIERR_NONE) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Failed to create SA for interface %s", sa, ifname); goto err_out; } if (sa_profile->enableRx != IPMACSEC_ENABLEFLAG_IGNORE) { if (ipmacsec_lmi_secy_rx_sa_ctrl_init(&sa_ctrl, sa_profile->enableRx, 0, 0) == IP_NULL) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Failed to initialize SA control for interface %s", sa, ifname); goto err_out; } ret = ipmacsec_lmi_secy_control_rx_sa(lh, ifname, &sa_desc, &sa_ctrl); if (ret != IPMACSEC_LMIERR_NONE) { IPCOM_LOG2(ERR, "IPMACSEC-PROFILE: RX SA profile %u - Failed to control the SA for interface %s", sa, ifname); goto err_out; } } } } err_out: if (ret != IPMACSEC_LMIERR_NONE) IPCOM_LOG3(ERR, "IPMACSEC-PROFILE: Failed to properly setup profile for interface %s (ret = %d, %s)", (ifname ? ifname : "*unspecified*"), ret, ipmacsec_lmi_error_name(ret)); ipmacsec_lmi_handle_delete(lh); return ret; }