[qca-nss-drv] IPsec message changes for v2.0
Message changes for supporting IPsec v2.0 manager
Change-Id: I59bbdbaf23a491410082aa0819f9584aa9097adc
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
Signed-off-by: Samarjeet Banerjee <banerjee@codeaurora.org>
Signed-off-by: Sourav Poddar <souravp@codeaurora.org>
diff --git a/Makefile b/Makefile
index d998548..72898f1 100644
--- a/Makefile
+++ b/Makefile
@@ -44,8 +44,6 @@
nss_gre_tunnel_stats.o \
nss_if.o \
nss_init.o \
- nss_ipsec.o \
- nss_ipsec_log.o \
nss_ipv4.o \
nss_ipv4_stats.o \
nss_ipv4_log.o \
@@ -126,25 +124,27 @@
qca-nss-drv-objs += nss_hal/nss_hal.o
ifeq ($(SoC),$(filter $(SoC),ipq806x ipq40xx))
-qca-nss-drv-objs += \
- nss_data_plane/nss_data_plane_gmac.o \
- nss_hal/ipq806x/nss_hal_pvt.o \
- nss_dtls.o \
- nss_dtls_log.o \
- nss_dtls_stats.o \
- nss_crypto.o \
- nss_crypto_log.o
+qca-nss-drv-objs += nss_data_plane/nss_data_plane_gmac.o \
+ nss_hal/ipq806x/nss_hal_pvt.o \
+ nss_dtls.o \
+ nss_dtls_log.o \
+ nss_dtls_stats.o \
+ nss_crypto.o \
+ nss_crypto_log.o \
+ nss_ipsec_log.o \
+ nss_ipsec.o
ccflags-y += -I$(obj)/nss_hal/ipq806x -DNSS_HAL_IPQ806X_SUPPORT
endif
ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64))
-qca-nss-drv-objs += \
- nss_data_plane/nss_data_plane_edma.o \
- nss_hal/ipq807x/nss_hal_pvt.o \
- nss_dtls_cmn.o \
- nss_dtls_cmn_log.o \
- nss_crypto_cmn.o \
- nss_crypto_cmn_log.o
+qca-nss-drv-objs += nss_data_plane/nss_data_plane_edma.o \
+ nss_hal/ipq807x/nss_hal_pvt.o \
+ nss_dtls_cmn.o \
+ nss_dtls_cmn_log.o \
+ nss_crypto_cmn.o \
+ nss_crypto_cmn_log.o \
+ nss_ipsec_cmn_log.o \
+ nss_ipsec_cmn.o
ccflags-y += -I$(obj)/nss_hal/ipq807x -DNSS_HAL_IPQ807x_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT
endif
@@ -154,7 +154,9 @@
nss_dtls_cmn.o \
nss_dtls_cmn_log.o \
nss_crypto_cmn.o \
- nss_crypto_cmn_log.o
+ nss_crypto_cmn_log.o \
+ nss_ipsec_cmn_log.o \
+ nss_ipsec_cmn.o
ccflags-y += -I$(obj)/nss_hal/ipq60xx -DNSS_HAL_IPQ60XX_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT
endif
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index 6adb649..228b3a6 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -147,7 +147,7 @@
/**< Virtual interface number for core-to-core transmissions. */
#define NSS_C2C_RX_INTERFACE (NSS_SPECIAL_IF_START + 13)
/**< Virtual interface number for core-to-core reception. */
-#define NSS_IPSEC_RULE_INTERFACE (NSS_SPECIAL_IF_START + 18)
+#define NSS_IPSEC_CMN_INTERFACE (NSS_SPECIAL_IF_START + 18)
/**< Virtual interface number for IPSec rule. */
#define NSS_COREFREQ_INTERFACE (NSS_SPECIAL_IF_START + 19)
/**< Virtual interface number for core frequency. */
diff --git a/exports/nss_dynamic_interface.h b/exports/nss_dynamic_interface.h
index e172df6..d6cdc12 100644
--- a/exports/nss_dynamic_interface.h
+++ b/exports/nss_dynamic_interface.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -80,6 +80,11 @@
NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER,
NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER,
NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER,
+ NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER,
+ NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER_BOUNCE,
+ NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER,
+ NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER_BOUNCE,
+ NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT,
NSS_DYNAMIC_INTERFACE_TYPE_MAX
};
diff --git a/exports/nss_ipsec_cmn.h b/exports/nss_ipsec_cmn.h
new file mode 100644
index 0000000..b9522bb
--- /dev/null
+++ b/exports/nss_ipsec_cmn.h
@@ -0,0 +1,543 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/**
+ * @file nss_ipsec_cmn.h
+ * NSS IPsec interface definitions.
+ */
+
+#ifndef __NSS_IPSEC_CMN_H_
+#define __NSS_IPSEC_CMN_H_
+
+/**
+ * @addtogroup nss_nss_ipsec_subsystem
+ * @{
+ */
+
+#define NSS_IPSEC_CMN_ARPHRD_IPSEC 31 /**< ARP (iana.org) hardware type for an IPsec tunnel. */
+
+/**
+ * Flags for SA configuration.
+ */
+#define NSS_IPSEC_CMN_FLAG_IPV6 (0x1 << 0) /**< IPv6 header. */
+#define NSS_IPSEC_CMN_FLAG_IPV4_NATT (0x1 << 1) /**< IPv4 NAT traversal. */
+#define NSS_IPSEC_CMN_FLAG_IPV4_UDP (0x1 << 2) /**< IPv4 UDP traversal. */
+#define NSS_IPSEC_CMN_FLAG_ESP_ESN (0x1 << 3) /**< Enable ESP extended sequence number. */
+#define NSS_IPSEC_CMN_FLAG_ESP_SKIP (0x1 << 4) /**< Skip ESP sequence number and ICV. */
+#define NSS_IPSEC_CMN_FLAG_ESP_REPLAY (0x1 << 5) /**< Check ESP replay counter. */
+#define NSS_IPSEC_CMN_FLAG_CIPHER_NULL (0x1 << 6) /**< NULL cipher mode. */
+#define NSS_IPSEC_CMN_FLAG_CIPHER_GCM (0x1 << 7) /**< Galios counter mode. */
+#define NSS_IPSEC_CMN_FLAG_COPY_DSCP (0x1 << 8) /**< Copy DSCP from inner to outer header. */
+#define NSS_IPSEC_CMN_FLAG_COPY_DF (0x1 << 9) /**< Copy DF from inner node to outer node. */
+
+#define NSS_IPSEC_CMN_FLAG_HDR_MASK \
+ (NSS_IPSEC_CMN_FLAG_IPV6 | NSS_IPSEC_CMN_FLAG_IPV4_NATT | NSS_IPSEC_CMN_FLAG_IPV4_UDP)
+ /**< Flag header mask. */
+
+#define NSS_IPSEC_CMN_FEATURE_INLINE_ACCEL 0x1 /**< Interface enabled for inline exception. */
+
+/**
+ * nss_ipsec_cmn_msg_type
+ * IPsec message types.
+ */
+enum nss_ipsec_cmn_msg_type {
+ NSS_IPSEC_CMN_MSG_TYPE_NONE = 0, /**< Nothing to do. */
+ NSS_IPSEC_CMN_MSG_TYPE_NODE_CONFIG = 1, /**< Configure IPsec node. */
+ NSS_IPSEC_CMN_MSG_TYPE_CTX_CONFIG = 2, /**< Configure IPsec dynamic node. */
+ NSS_IPSEC_CMN_MSG_TYPE_CTX_SYNC = 3, /**< Synchronize context statistics to host. */
+ NSS_IPSEC_CMN_MSG_TYPE_SA_CREATE = 4, /**< Create SA. */
+ NSS_IPSEC_CMN_MSG_TYPE_SA_DESTROY = 5, /**< Destroy SA. */
+ NSS_IPSEC_CMN_MSG_TYPE_SA_SYNC = 6, /**< Synchronize SA statistics to host. */
+ NSS_IPSEC_CMN_MSG_TYPE_FLOW_CREATE = 7, /**< Create flow. */
+ NSS_IPSEC_CMN_MSG_TYPE_FLOW_DESTROY = 8, /**< Delete flow. */
+ NSS_IPSEC_CMN_MSG_TYPE_MAX
+};
+
+/**
+ * nss_ipsec_cmn_msg_error
+ * IPsec message error types.
+ */
+enum nss_ipsec_cmn_msg_error {
+ NSS_IPSEC_CMN_MSG_ERROR_NONE = 0, /**< No error. */
+ NSS_IPSEC_CMN_MSG_ERROR_CTX_INVAL = 1, /**< Invalid context. */
+ NSS_IPSEC_CMN_MSG_ERROR_SA_ALLOC = 2, /**< Failed to allocate SA. */
+ NSS_IPSEC_CMN_MSG_ERROR_SA_INVAL = 3, /**< Invalid SA. */
+ NSS_IPSEC_CMN_MSG_ERROR_SA_DUP = 4, /**< SA exists. */
+ NSS_IPSEC_CMN_MSG_ERROR_SA_INUSE = 5, /**< SA is in use. */
+ NSS_IPSEC_CMN_MSG_ERROR_FLOW_ALLOC = 6, /**< Failed to allocate flow. */
+ NSS_IPSEC_CMN_MSG_ERROR_FLOW_INVAL = 7, /**< Flow not found. */
+ NSS_IPSEC_CMN_MSG_ERROR_FLOW_DUP = 8, /**< Duplicate flow. */
+ NSS_IPSEC_CMN_MSG_ERROR_FLOW_SA = 9, /**< Failed to find SA for the flow. */
+ NSS_IPSEC_CMN_MSG_ERROR_NODE_REG_DYNIF = 10,
+ /**< Error registering dynamic interface. */
+ NSS_IPSEC_CMN_MSG_ERROR_UNHANDLED_MSG= 11, /**< Unhandled message type. */
+ NSS_IPSEC_CMN_MSG_ERROR_MAX /**< Maximum error message. */
+};
+
+/**
+ * nss_ipsec_cmn_ctx_type
+ * IPsec context type.
+ */
+enum nss_ipsec_cmn_ctx_type {
+ NSS_IPSEC_CMN_CTX_TYPE_NONE = 0, /**< Invalid direction. */
+ NSS_IPSEC_CMN_CTX_TYPE_INNER, /**< Encapsulation. */
+ NSS_IPSEC_CMN_CTX_TYPE_INNER_BOUNCE, /**< Inner bounce */
+ NSS_IPSEC_CMN_CTX_TYPE_OUTER, /**< Decapsulation. */
+ NSS_IPSEC_CMN_CTX_TYPE_OUTER_BOUNCE, /**< Outer bounce. */
+ NSS_IPSEC_CMN_CTX_TYPE_REDIR, /**< Redirect. */
+ NSS_IPSEC_CMN_CTX_TYPE_MAX
+};
+
+/**
+ * nss_ipsec_cmn_flow_tuple
+ * IPsec tuple for creating flow entries.
+ *
+ * Note: This is a common selector which is used for preparing
+ * a lookup tuple for incoming packets. The tuple is used
+ * for computing the hash index in the flow table. There are multiple
+ * fields in the tuple and the recipient node decides which fields
+ * it must use from the tuple to calculate the hash index. The host
+ * has no view of the hash index and hence must compute its own index
+ * based on the tuple.
+ */
+struct nss_ipsec_cmn_flow_tuple {
+ uint32_t dest_ip[4]; /**< Destination IP. */
+ uint32_t src_ip[4]; /**< Source IP. */
+ uint32_t spi_index; /**< ESP SPI index. */
+
+ uint16_t dst_port; /**< Destination L4 port. */
+ uint16_t src_port; /**< Source L4 port. */
+
+ uint8_t user_pattern; /**< User defined field. */
+ uint8_t protocol; /**< IP protocol types. */
+ uint8_t ip_ver; /**< IP version. */
+};
+
+/**
+ *nss_ipsec_cmn_sa_tuple
+ * IPsec outer header configuration.
+ */
+struct nss_ipsec_cmn_sa_tuple {
+ uint32_t dest_ip[4]; /**< Destination IP. */
+ uint32_t src_ip[4]; /**< Source IP. */
+ uint32_t spi_index; /**< ESP SPI index. */
+
+ uint16_t dest_port; /* Destination L4 port. */
+ uint16_t src_port; /* Source L4 port. */
+
+ uint16_t crypto_index; /**< Crypto index for the SA. */
+ uint8_t protocol; /**< Outer protocol. */
+ uint8_t ip_ver; /**< IP version. */
+
+ uint8_t hop_limit; /**< Time-to-Live or next hop limit. */
+ uint8_t res[3]; /**< Reserved. */
+};
+
+/**
+ *nss_ipsec_cmn_sa_data
+ * IPsec SA data used for transformation.
+ */
+struct nss_ipsec_cmn_sa_data {
+ uint32_t seq_start; /**< Starting sequence number. */
+ uint32_t flags; /**< Configuration flags. */
+
+ uint16_t window_size; /**< ESP sequence number window. */
+ uint8_t dscp; /**< Default DSCP value of the SA. */
+ uint8_t df; /**< Default do not fragment value of the SA. */
+
+ uint8_t blk_len; /**< Cipher block length. */
+ uint8_t iv_len; /**< IV length. */
+ uint8_t icv_len; /**< ESP trailers ICV length to apply. */
+ uint8_t res1; /**< Reserved. */
+
+ uint32_t res2[4]; /**< Reserved for future use. */
+};
+
+/**
+ * nss_ipsec_cmn_flow
+ * IPsec flow configuration message.
+ */
+struct nss_ipsec_cmn_flow {
+ struct nss_ipsec_cmn_flow_tuple flow_tuple; /**< Flow tuple. */
+ struct nss_ipsec_cmn_sa_tuple sa_tuple; /**< SA tuple. */
+};
+
+/**
+ * nss_ipsec_cmn_sa
+ * IPsec SA configuration message.
+ */
+struct nss_ipsec_cmn_sa {
+ struct nss_ipsec_cmn_sa_tuple sa_tuple; /**< SA tuple. */
+ struct nss_ipsec_cmn_sa_data sa_data; /**< SA data. */
+};
+
+/**
+ * nss_ipsec_cmn_ctx
+ * IPsec context configuration.
+ */
+struct nss_ipsec_cmn_ctx {
+ enum nss_ipsec_cmn_ctx_type type; /**< Node type. */
+ uint32_t except_ifnum; /**< Exception interface for egress. */
+};
+
+/**
+ * nss_ipsec_cmn_node
+ * IPsec node configuration.
+ */
+struct nss_ipsec_cmn_node {
+ bool dma_redirect; /**< Enable redirect DMA ring. */
+ bool dma_lookaside; /**< Enable lookaside DMA ring. */
+ uint16_t max_sa; /**< Maximum number of SA(s) supported. */
+};
+
+/**
+ * nss_ipsec_cmn_sa_replay
+ * IPsec replay statistics
+ */
+struct nss_ipsec_cmn_sa_replay {
+ uint64_t seq_start; /**< Start of replay window. */
+ uint64_t seq_cur; /**< Current sequence number. */
+ uint16_t window_size; /**< Window size. */
+ uint8_t res[6]; /**< Reserved for future use. */
+};
+
+/**
+ * nss_ipsec_cmn_sa_stats
+ * IPsec SA statistics.
+ */
+struct nss_ipsec_cmn_sa_stats {
+ struct nss_cmn_node_stats cmn_stats; /**< Packet statistics. */
+ uint32_t fail_headroom; /**< Failed headroom check. */
+ uint32_t fail_tailroom; /**< Failed tailroom check. */
+ uint32_t fail_replay; /**< Failure in anti-replay check. */
+ uint32_t fail_replay_dup; /**< Failure in anti-replay; duplicate records. */
+ uint32_t fail_replay_win; /**< Failure in anti-replay; packet outside the window. */
+ uint32_t fail_pbuf_crypto; /**< Failed to allocate crypto pbuf. */
+ uint32_t fail_queue; /**< Failure due to queue full in IPsec. */
+ uint32_t fail_queue_crypto; /**< Failure due to queue full in crypto. */
+ uint32_t fail_queue_nexthop; /**< Failure due to queue full in next hop. */
+ uint32_t fail_pbuf_alloc; /**< Failure in pbuf allocation. */
+ uint32_t fail_pbuf_linear; /**< Failure in pbuf linearization. */
+ uint32_t fail_pbuf_stats; /**< Failure in pbuf allocation for statistics. */
+ uint32_t fail_pbuf_align; /**< Failure in pbuf access due non-word alignment. */
+ uint32_t fail_cipher; /**< Failure in decrypting the data. */
+ uint32_t fail_auth; /**< Failure in authenticating the data. */
+ uint32_t fail_seq_ovf; /**< Failure due to sequence number rollover. */
+ uint32_t fail_blk_len; /**< Failure in decapsulation due to bad cipher block length. */
+ uint32_t fail_hash_len; /**< Failure in decapsulation due to bad hash block length. */
+ uint32_t fail_transform; /**< Failure in transformation; general error. */
+ uint32_t fail_crypto; /**< Failure in crypto transformation. */
+ uint32_t fail_cle; /**< Failure in classification; general failure. */
+};
+
+/**
+ * nss_ipsec_cmn_sa_sync
+ * IPsec SA sync message.
+ */
+struct nss_ipsec_cmn_sa_sync {
+ struct nss_ipsec_cmn_sa_replay replay; /**< Replay statistics. */
+ struct nss_ipsec_cmn_sa_tuple sa_tuple; /**< SA tuple. */
+ struct nss_ipsec_cmn_sa_stats stats; /**< Packet and failure statistics. */
+};
+
+/**
+ * nss_ipsec_cmn_ctx_stats
+ * IPsec context statistics.
+ */
+struct nss_ipsec_cmn_ctx_stats {
+ struct nss_cmn_node_stats cmn_stats;
+ /**< Packet statistics. */
+ uint32_t exceptioned; /**< Exceptioned to host. */
+ uint32_t linearized; /**< Linearized packets. */
+ uint32_t redirected; /**< Redirected from inline. */
+ uint32_t fail_sa; /**< Failed to find SA. */
+ uint32_t fail_flow; /**< Failed to find flow. */
+ uint32_t fail_stats; /**< Failed to send statistics. */
+ uint32_t fail_exception; /**< Failed to exception. */
+ uint32_t fail_transform; /**< Failed to produce output. */
+ uint32_t fail_linearized; /**< Failed to linearize. */
+};
+
+/**
+ * nss_ipsec_cmn_ctx_sync
+ * IPsec context synchronous message.
+ */
+struct nss_ipsec_cmn_ctx_sync {
+ enum nss_ipsec_cmn_ctx_type type; /**< IPsec context type. */
+ struct nss_ipsec_cmn_ctx_stats stats; /**< Context statistics. */
+};
+
+/**
+ * nss_ipsec_cmn_msg
+ * Message structure for NSS IPsec messages.
+ */
+struct nss_ipsec_cmn_msg {
+ struct nss_cmn_msg cm; /**< Common message header. */
+
+ /**
+ * Payload of IPsec interface message.
+ */
+ union {
+ struct nss_ipsec_cmn_node node; /**< Node configuration message. */
+ struct nss_ipsec_cmn_ctx ctx; /**< Context configuration message. */
+ struct nss_ipsec_cmn_sa sa; /**< SA configuration message. */
+ struct nss_ipsec_cmn_flow flow; /**< Flow configuration message. */
+ struct nss_ipsec_cmn_sa_sync sa_sync; /**< SA statistics message. */
+ struct nss_ipsec_cmn_ctx_sync ctx_sync; /**< Context statistics message. */
+ } msg; /**< Message payload. */
+};
+
+/**
+ * Callback function for receiving message notifications.
+ *
+ * @datatypes
+ * nss_ipsec_cmn_msg
+ *
+ * @param[in] app_data Pointer to the application context of the message.
+ * @param[in] msg Pointer to the message data.
+ */
+typedef void (*nss_ipsec_cmn_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg);
+
+/**
+ * Callback function for receiving data.
+ *
+ * @datatypes
+ * net_device \n
+ * sk_buff \n
+ * napi_struct
+ *
+ * @param[in] netdev Pointer to the associated network device.
+ * @param[in] skb Pointer to the message data.
+ * @param[in] napi Pointer to the NAPI structure.
+ */
+typedef void (*nss_ipsec_cmn_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi);
+
+/**
+ * nss_ipsec_cmn_get_context
+ * Gets the NSS context for the IPsec handle.
+ *
+ * @return
+ * Pointer to the NSS core context.
+ */
+extern struct nss_ctx_instance *nss_ipsec_cmn_get_context(void);
+
+/**
+ * nss_ipsec_cmn_get_ifnum_with_coreid
+ * Gets the IPsec interface number with a core ID.
+ *
+ * @param[in] ifnum NSS interface number.
+ *
+ * @return
+ * Interface number with the core ID.
+ */
+extern uint32_t nss_ipsec_cmn_get_ifnum_with_coreid(int32_t ifnum);
+
+/**
+ * nss_ipsec_cmn_register_if
+ * Registers the IPsec interface with the NSS for sending and
+ * receiving messages.
+ *
+ * @datatypes
+ * nss_ipsec_cmn_data_callback_t \n
+ * nss_ipsec_cmn_msg_callback_t \n
+ * nss_dynamic_interface_type \n
+ * net_device
+ *
+ * @param[in] if_num NSS interface number.
+ * @param[in] netdev Pointer to the associated network device.
+ * @param[in] cb_data Callback for the data.
+ * @param[in] cb_msg Callback for the message.
+ * @param[in] features Socket buffer types supported by this interface.
+ * @param[in] type Dynamic interface type.
+ * @param[in] app_data Application context.
+ *
+ * @return
+ * Pointer to the NSS core context.
+ */
+extern struct nss_ctx_instance *nss_ipsec_cmn_register_if(uint32_t if_num, struct net_device *netdev,
+ nss_ipsec_cmn_data_callback_t cb_data,
+ nss_ipsec_cmn_msg_callback_t cb_msg,
+ uint32_t features, enum nss_dynamic_interface_type type, void *app_data);
+
+/**
+ * nss_ipsec_cmn_unregister_if
+ * Deregisters a IPSEC tunnel interface from the NSS.
+ *
+ * @param[in] if_num NSS interface number.
+. *
+ * @return
+ * None.
+ *
+ * @dependencies
+ * The tunnel interface must have been previously registered.
+ *
+ * @return
+ * True if successful, else false.
+ */
+extern bool nss_ipsec_cmn_unregister_if(uint32_t if_num);
+
+/**
+ * nss_ipsec_cmn_notify_register
+ * Register an event callback to handle notification from IPsec firmware package.
+ *
+ * @datatypes
+ * nss_ipsec_cmn_msg_callback_t \n
+ *
+ * @param[in] ifnum NSS interface number.
+ * @param[in] cb Callback for IPsec message.
+ * @param[in] app_data Pointer to the application context.
+ *
+ * @return
+ * Pointer to NSS core context.
+ */
+extern struct nss_ctx_instance *nss_ipsec_cmn_notify_register(uint32_t ifnum, nss_ipsec_cmn_msg_callback_t cb, void *app_data);
+
+/**
+ * nss_ipsec_cmn_notify_unregister
+ * Deregisters the message notifier from the HLOS driver.
+ *
+ * @datatypes
+ * nss_ctx_instance
+ *
+ * @param[in,out] ctx Pointer to the context of the HLOS driver.
+ * @param[in] if_num NSS interface number.
+ *
+ * @return
+ * None.
+ *
+ * @dependencies
+ * The message notifier must have been previously registered.
+ */
+extern void nss_ipsec_cmn_notify_unregister(struct nss_ctx_instance *ctx, uint32_t if_num);
+
+/**
+ * nss_ipsec_cmn_msg_init
+ * Initializes an IPsec message.
+ *
+ * @datatypes
+ * nss_ipsec_cmn_msg \n
+ * nss_ipsec_cmn_msg_type \n
+ * nss_ipsec_cmn_msg_callback_t
+ *
+ * @param[in,out] nim Pointer to the NSS interface message.
+ * @param[in] if_num NSS interface number.
+ * @param[in] type Type of message.
+ * @param[in] len Size of the payload.
+ * @param[in] cb Callback function for the message.
+ * @param[in] app_data Pointer to the application context of the message.
+ *
+ * @return
+ * None.
+ */
+extern void nss_ipsec_cmn_msg_init(struct nss_ipsec_cmn_msg *nim, uint16_t if_num, enum nss_ipsec_cmn_msg_type type,
+ uint16_t len, nss_ipsec_cmn_msg_callback_t cb, void *app_data);
+
+/**
+ * nss_ipsec_cmn_tx_msg
+ * Sends an asynchronous IPsec message to the NSS.
+ *
+ * @datatypes
+ * nss_ctx_instance \n
+ * nss_ipsec_cmn_msg
+ *
+ * @param[in] nss_ctx Pointer to the NSS HLOS driver context.
+ * @param[in] msg Pointer to the message data.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+extern nss_tx_status_t nss_ipsec_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_cmn_msg *msg);
+
+/**
+ * nss_ipsec_cmn_tx_msg_sync
+ * Sends a synchronous IPsec message to the NSS.
+ *
+ * @datatypes
+ * nss_ctx_instance \n
+ * nss_ipsec_cmn_msg_type \n
+ * nss_ipsec_cmn_msg
+ *
+ * @param[in] nss_ctx Pointer to the NSS HLOS driver context.
+ * @param[in] if_num NSS interface number.
+ * @param[in] type Type of message.
+ * @param[in] len Size of the payload.
+ * @param[in] nicm Pointer to the NSS IPsec message.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+extern nss_tx_status_t nss_ipsec_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num,
+ enum nss_ipsec_cmn_msg_type type, uint16_t len,
+ struct nss_ipsec_cmn_msg *nicm);
+
+/**
+ * nss_ipsec_cmn_tx_buf
+ * Sends a buffer to NSS for IPsec encapsulation or de-capsulation.
+ *
+ * @datatypes
+ * sk_buff \n
+ * nss_ctx_instance
+ *
+ * @param[in] nss_ctx Pointer to the NSS HLOS driver context.
+ * @param[in] skb Pointer to the message data.
+ * @param[in] if_num Pointer to the NSS interface number.
+ *
+ * @return
+ * Status of the Tx operation.
+ */
+extern nss_tx_status_t nss_ipsec_cmn_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num);
+
+/**
+ * nss_ipsec_cmn_ppe_port_config
+ * Configure Packet Processing Engine IPsec port.
+ *
+ * @datatypes
+ * nss_ctx_instance \n
+ * net_device
+ *
+ * @param[in] ctx Pointer to the context of the HLOS driver.
+ * @param[in] netdev Pointer to the associated network device.
+ * @param[in] if_num Data interface number.
+ * @param[in] vsi_num Virtual switch instance number.
+ *
+ * @return
+ * True if successful, else false.
+ */
+extern bool nss_ipsec_cmn_ppe_port_config(struct nss_ctx_instance *ctx, struct net_device *netdev,
+ uint32_t if_num, uint32_t vsi_num);
+
+/**
+ * nss_ipsec_cmn_ppe_mtu_update()
+ * Configure Packet Processing Engine MTU for IPsec inline.
+ *
+ * @datatypes
+ * nss_ctx_instance
+ *
+ * @param[in] ctx Pointer to the context of the HLOS driver.
+ * @param[in] if_num Data interface number.
+ * @param[in] mtu Maximum transmission unit of interface number.
+ * @param[in] mru Maximum receive unit of interface number.
+ *
+ * @return
+ * True if successful, else false.
+ */
+bool nss_ipsec_cmn_ppe_mtu_update(struct nss_ctx_instance *ctx, uint32_t if_num, uint16_t mtu, uint16_t mru);
+
+/**
+ * @}
+ */
+
+#endif /* !__NSS_IPSEC_CMN_H */
diff --git a/nss_core.h b/nss_core.h
index 40f9b72..26dbd06 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -48,6 +48,7 @@
* to this file
*/
#include "nss_ipsec.h"
+#include "nss_ipsec_cmn.h"
#include "nss_crypto.h"
/*
@@ -656,6 +657,10 @@
/* Vlan callback */
nss_wifili_msg_callback_t wifili_msg_callback;
/* wifili interface event callback function */
+
+ nss_ipsec_cmn_msg_callback_t ipsec_cmn_msg_callback;
+ /* IPSEC common interface event callback function */
+
uint32_t dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_MAX];
/*
diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c
index b3bd2b9..628c93f 100644
--- a/nss_hal/nss_hal.c
+++ b/nss_hal/nss_hal.c
@@ -410,7 +410,16 @@
if (npd->ipsec_enabled == NSS_FEATURE_ENABLED) {
nss_top->ipsec_handler_id = nss_dev->id;
+#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT)
+ nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER] = nss_dev->id;
+ nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER] = nss_dev->id;
+ nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER_BOUNCE] = nss_dev->id;
+ nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER_BOUNCE] = nss_dev->id;
+ nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT] = nss_dev->id;
+ nss_ipsec_cmn_register_handler();
+#else
nss_ipsec_register_handler();
+#endif
}
if (npd->wlanredirect_enabled == NSS_FEATURE_ENABLED) {
diff --git a/nss_ipsec.c b/nss_ipsec.c
index 4b44f50..2184bff 100644
--- a/nss_ipsec.c
+++ b/nss_ipsec.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -32,17 +32,17 @@
#elif defined(NSS_HAL_FSM9010_SUPPORT)
#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_ENCAP_IF_NUMBER
#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_DECAP_IF_NUMBER
-#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
+#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE
#elif defined(NSS_HAL_IPQ807x_SUPPORT)
-#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
-#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
-#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
+#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE
+#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE
+#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE
#elif defined(NSS_HAL_IPQ60XX_SUPPORT)
-#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
-#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
-#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_RULE_INTERFACE
+#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE
+#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE
+#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE
#else
#define NSS_IPSEC_ENCAP_INTERFACE_NUM -1
diff --git a/nss_ipsec_cmn.c b/nss_ipsec_cmn.c
new file mode 100644
index 0000000..18ed565
--- /dev/null
+++ b/nss_ipsec_cmn.c
@@ -0,0 +1,579 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_tx_rx_common.h"
+#include "nss_dynamic_interface.h"
+#include "nss_ipsec_cmn.h"
+#include "nss_ppe.h"
+#include "nss_ipsec_cmn_log.h"
+
+#define NSS_IPSEC_CMN_TX_TIMEOUT 3000 /* 3 Seconds */
+#define NSS_IPSEC_CMN_INTERFACE_MAX_LONG BITS_TO_LONGS(NSS_MAX_NET_INTERFACES)
+#define NSS_IPSEC_CMN_STATS_MAX_LINES (NSS_STATS_NODE_MAX + 32)
+#define NSS_IPSEC_CMN_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_IPSEC_CMN_STATS_MAX_LINES)
+
+/*
+ * Private data structure for handling synchronous messaging.
+ */
+static struct nss_ipsec_cmn_pvt {
+ struct semaphore sem;
+ struct completion complete;
+ struct nss_ipsec_cmn_msg nicm;
+ unsigned long if_map[NSS_IPSEC_CMN_INTERFACE_MAX_LONG];
+} ipsec_cmn_pvt;
+
+/*
+ * nss_ipsec_cmn_stats_sync()
+ * Update ipsec_cmn node statistics.
+ */
+static void nss_ipsec_cmn_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm)
+{
+ struct nss_ipsec_cmn_msg *nicm = (struct nss_ipsec_cmn_msg *)ncm;
+ struct nss_top_instance *nss_top = nss_ctx->nss_top;
+ struct nss_cmn_node_stats *msg_stats = &nicm->msg.ctx_sync.stats.cmn_stats;
+ uint64_t *if_stats;
+ int8_t i;
+
+ spin_lock_bh(&nss_top->stats_lock);
+
+ /*
+ * Update common node stats,
+ * Note: DTLS only supports a single queue for RX
+ */
+ if_stats = nss_top->stats_node[ncm->interface];
+ if_stats[NSS_STATS_NODE_RX_PKTS] += msg_stats->rx_packets;
+ if_stats[NSS_STATS_NODE_RX_BYTES] += msg_stats->rx_bytes;
+
+ for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
+ if_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += msg_stats->rx_dropped[i];
+ }
+
+ if_stats[NSS_STATS_NODE_TX_PKTS] += msg_stats->tx_packets;
+ if_stats[NSS_STATS_NODE_TX_BYTES] += msg_stats->tx_bytes;
+
+ spin_unlock_bh(&nss_top->stats_lock);
+}
+
+/*
+ * nss_ipsec_cmn_stats_read()
+ * Read ipsec_cmn node statistics.
+ */
+static ssize_t nss_ipsec_cmn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context();
+ enum nss_dynamic_interface_type type;
+ ssize_t bytes_read = 0;
+ size_t len = 0, size;
+ uint32_t if_num;
+ char *buf;
+
+ size = NSS_IPSEC_CMN_STATS_SIZE_PER_IF * bitmap_weight(ipsec_cmn_pvt.if_map, NSS_MAX_NET_INTERFACES);
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (!buf) {
+ nss_warning("Could not allocate memory for local statistics buffer\n");
+ return 0;
+ }
+
+ /*
+ * Common node stats for each IPSEC dynamic interface.
+ */
+ for_each_set_bit(if_num, ipsec_cmn_pvt.if_map, NSS_MAX_NET_INTERFACES) {
+
+ type = nss_dynamic_interface_get_type(nss_ctx, if_num);
+ switch (type) {
+ case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER:
+ len += scnprintf(buf + len, size - len, "\nInner if_num:%03u", if_num);
+ break;
+
+ case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER:
+ len += scnprintf(buf + len, size - len, "\nOuter if_num:%03u", if_num);
+ break;
+
+ default:
+ len += scnprintf(buf + len, size - len, "\nUnknown(%d) if_num:%03u", type, if_num);
+ break;
+ }
+
+ len += scnprintf(buf + len, size - len, "\n-------------------\n");
+ len += nss_stats_fill_common_stats(if_num, buf, len, size - len);
+ }
+
+ bytes_read = simple_read_from_buffer(ubuf, sz, ppos, buf, len);
+ kfree(buf);
+
+ return bytes_read;
+}
+
+/*
+ * nss_ipsec_cmn_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(ipsec_cmn)
+
+/*
+ * nss_ipsec_cmn_verify_ifnum()
+ * Verify if the interface number is a IPsec interface.
+ */
+static bool nss_ipsec_cmn_verify_ifnum(struct nss_ctx_instance *nss_ctx, uint32_t if_num)
+{
+ enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_ctx, if_num);
+
+ if (if_num == NSS_IPSEC_CMN_INTERFACE)
+ return true;
+
+ switch (type) {
+ case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER:
+ case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER:
+ case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER_BOUNCE:
+ case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER_BOUNCE:
+ case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT:
+ return true;
+
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+/*
+ * nss_ipsec_cmn_msg_handler()
+ * Handle NSS -> HLOS messages for IPSEC tunnel.
+ */
+static void nss_ipsec_cmn_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data)
+{
+ nss_ipsec_cmn_msg_callback_t cb;
+ struct nss_ipsec_cmn_msg *nim;
+
+ NSS_VERIFY_CTX_MAGIC(nss_ctx);
+
+ /*
+ * Trace messages.
+ */
+ nim = (struct nss_ipsec_cmn_msg *)ncm;
+ nss_ipsec_cmn_log_rx_msg(nim);
+
+ /*
+ * Is this a valid request/response packet?
+ */
+ if (ncm->type >= NSS_IPSEC_CMN_MSG_TYPE_MAX) {
+ nss_warning("%p: Invalid message type(%u) for interface(%u)\n", nss_ctx, ncm->type, ncm->interface);
+ return;
+ }
+
+ if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipsec_cmn_msg)) {
+ nss_warning("%p: Invalid message length(%d)\n", nss_ctx, nss_cmn_get_msg_len(ncm));
+ return;
+ }
+
+ if (ncm->type == NSS_IPSEC_CMN_MSG_TYPE_CTX_SYNC)
+ nss_ipsec_cmn_stats_sync(nss_ctx, ncm);
+
+ /*
+ * Update the callback and app_data for NOTIFY messages, ipsec_cmn sends all notify messages
+ * to the same callback/app_data.
+ */
+ if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) {
+ ncm->cb = (nss_ptr_t)nss_ctx->nss_top->if_rx_msg_callback[ncm->interface];
+ ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[nss_ctx->id][ncm->interface].app_data;
+ }
+
+ /*
+ * Log failures
+ */
+ nss_core_log_msg_failures(nss_ctx, ncm);
+
+ /*
+ * Callback
+ */
+ cb = (nss_ipsec_cmn_msg_callback_t)ncm->cb;
+ app_data = (void *)ncm->app_data;
+
+ /*
+ * Call IPsec message callback
+ */
+ if (!cb) {
+ nss_warning("%p: No callback for IPsec interface %d\n", nss_ctx, ncm->interface);
+ return;
+ }
+
+ nss_trace("%p: calling ipsecsmgr message handler(%u)\n", nss_ctx, ncm->interface);
+ cb(app_data, ncm);
+}
+
+/*
+ * nss_ipsec_cmn_sync_resp()
+ * Callback to handle the completion of HLOS-->NSS messages.
+ */
+static void nss_ipsec_cmn_sync_resp(void *app_data, struct nss_cmn_msg *ncm)
+{
+ struct nss_ipsec_cmn_msg *pvt_msg = app_data;
+ struct nss_ipsec_cmn_msg *resp_msg = container_of(ncm, struct nss_ipsec_cmn_msg, cm);
+
+ /*
+ * Copy response message to pvt message
+ */
+ memcpy(pvt_msg, resp_msg, sizeof(*resp_msg));
+
+ /*
+ * Write memory barrier
+ */
+ smp_wmb();
+
+ complete(&ipsec_cmn_pvt.complete);
+}
+
+/*
+ * nss_ipsec_cmn_get_context()
+ * Retrieve context for IPSEC redir.
+ */
+struct nss_ctx_instance *nss_ipsec_cmn_get_context(void)
+{
+ return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ipsec_handler_id];
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_get_context);
+
+/*
+ * nss_ipsec_cmn_get_ifnum_with_coreid()
+ * Return IPsec interface number with coreid.
+ */
+uint32_t nss_ipsec_cmn_get_ifnum_with_coreid(int32_t ifnum)
+{
+ struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context();
+
+ NSS_VERIFY_CTX_MAGIC(nss_ctx);
+ return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, ifnum);
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_get_ifnum_with_coreid);
+
+/*
+ * nss_ipsec_cmn_msg_init()
+ * Initialize message
+ */
+void nss_ipsec_cmn_msg_init(struct nss_ipsec_cmn_msg *nim, uint16_t if_num, enum nss_ipsec_cmn_msg_type type,
+ uint16_t len, nss_ipsec_cmn_msg_callback_t cb, void *app_data)
+{
+ nss_cmn_msg_init(&nim->cm, if_num, type, len, cb, app_data);
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_msg_init);
+
+/*
+ * nss_ipsec_cmn_tx_msg()
+ * Transmit a IPSEC message to NSS FW.
+ */
+nss_tx_status_t nss_ipsec_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_cmn_msg *msg)
+{
+ struct nss_cmn_msg *ncm = &msg->cm;
+
+ /*
+ * Trace messages.
+ */
+ nss_ipsec_cmn_log_tx_msg(msg);
+
+ /*
+ * Sanity check the message
+ */
+ if (ncm->type >= NSS_IPSEC_CMN_MSG_TYPE_MAX) {
+ nss_warning("%p: Invalid message type(%u)\n", nss_ctx, ncm->type);
+ return NSS_TX_FAILURE;
+ }
+
+ if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, ncm->interface)) {
+ nss_warning("%p: Invalid message interface(%u)\n", nss_ctx, ncm->interface);
+ return NSS_TX_FAILURE;
+ }
+
+ if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipsec_cmn_msg)) {
+ nss_warning("%p: Invalid message length(%u)\n", nss_ctx, nss_cmn_get_msg_len(ncm));
+ return NSS_TX_FAILURE;
+ }
+
+ return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE);
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_tx_msg);
+
+/*
+ * nss_ipsec_cmn_tx_msg_sync()
+ * Transmit a IPSEC redir message to NSS firmware synchronously.
+ */
+nss_tx_status_t nss_ipsec_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num,
+ enum nss_ipsec_cmn_msg_type type, uint16_t len,
+ struct nss_ipsec_cmn_msg *nicm)
+{
+ struct nss_ipsec_cmn_msg *local_nicm = &ipsec_cmn_pvt.nicm;
+ nss_tx_status_t status;
+ int ret = 0;
+
+ /*
+ * Length of the message should be the based on type
+ */
+ if (len > sizeof(struct nss_ipsec_cmn_msg)) {
+ nss_warning("%p: Invalid message length(%u), type (%d), I/F(%u)\n", nss_ctx, len, type, if_num);
+ return NSS_TX_FAILURE;
+ }
+
+ down(&ipsec_cmn_pvt.sem);
+
+ /*
+ * We need to copy the message content into the actual message
+ * to be sent to NSS
+ */
+ memset(local_nicm, 0, sizeof(*local_nicm));
+
+ nss_ipsec_cmn_msg_init(local_nicm, if_num, type, len, nss_ipsec_cmn_sync_resp, local_nicm);
+ memcpy(&local_nicm->msg, &nicm->msg, len);
+
+ status = nss_ipsec_cmn_tx_msg(nss_ctx, local_nicm);
+ if (status != NSS_TX_SUCCESS) {
+ nss_warning("%p: Failed to send message\n", nss_ctx);
+ goto done;
+ }
+
+ ret = wait_for_completion_timeout(&ipsec_cmn_pvt.complete, msecs_to_jiffies(NSS_IPSEC_CMN_TX_TIMEOUT));
+ if (!ret) {
+ nss_warning("%p: Failed to receive response, timeout(%d)\n", nss_ctx, ret);
+ status = NSS_TX_FAILURE_NOT_READY;
+ goto done;
+ }
+
+ /*
+ * Read memory barrier
+ */
+ smp_rmb();
+
+ if (local_nicm->cm.response != NSS_CMN_RESPONSE_ACK) {
+ status = NSS_TX_FAILURE;
+ nicm->cm.response = local_nicm->cm.response;
+ nicm->cm.error = local_nicm->cm.error;
+ goto done;
+ }
+
+ /*
+ * Copy the message received
+ */
+ memcpy(&nicm->msg, &local_nicm->msg, len);
+
+done:
+ up(&ipsec_cmn_pvt.sem);
+ return status;
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_tx_msg_sync);
+
+/*
+ * nss_ipsec_cmn_tx_buf()
+ * Send packet to IPsec interface in NSS.
+ */
+nss_tx_status_t nss_ipsec_cmn_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num)
+{
+ nss_trace("%p: Send to IPsec I/F(%u), skb(%p)\n", nss_ctx, if_num, os_buf);
+ NSS_VERIFY_CTX_MAGIC(nss_ctx);
+
+ if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, if_num)) {
+ nss_warning("%p: Interface number(%d) is not IPSec type\n", nss_ctx, if_num);
+ return NSS_TX_FAILURE;
+ }
+
+ return nss_core_send_packet(nss_ctx, os_buf, if_num, 0);
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_tx_buf);
+
+/*
+ * nss_ipsec_cmn_register_if()
+ * Register dynamic node for IPSEC redir.
+ */
+struct nss_ctx_instance *nss_ipsec_cmn_register_if(uint32_t if_num, struct net_device *netdev,
+ nss_ipsec_cmn_data_callback_t cb_data,
+ nss_ipsec_cmn_msg_callback_t cb_msg,
+ uint32_t features, enum nss_dynamic_interface_type type, void *app_ctx)
+{
+ struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context();
+ uint32_t status;
+
+ if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, if_num)) {
+ nss_warning("%p: Invalid IPsec interface(%u)\n", nss_ctx, if_num);
+ return NULL;
+ }
+
+ if (nss_ctx->subsys_dp_register[if_num].ndev) {
+ nss_warning("%p: Failed find free slot for IPsec NSS I/F:%u\n", nss_ctx, if_num);
+ return NULL;
+ }
+
+ if (features & NSS_IPSEC_CMN_FEATURE_INLINE_ACCEL)
+ nss_ppe_tx_ipsec_add_intf_msg(nss_ipsec_cmn_get_ifnum_with_coreid(if_num));
+
+ /*
+ * Registering handler for sending tunnel interface msgs to NSS.
+ */
+ status = nss_core_register_handler(nss_ctx, if_num, nss_ipsec_cmn_msg_handler, app_ctx);
+ if (status != NSS_CORE_STATUS_SUCCESS){
+ nss_warning("%p: Failed to register message handler for IPsec NSS I/F:%u\n", nss_ctx, if_num);
+ return NULL;
+ }
+
+ nss_core_register_subsys_dp(nss_ctx, if_num, cb_data, NULL, app_ctx, netdev, features);
+ nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type);
+
+ nss_top_main.if_rx_msg_callback[if_num] = cb_msg;
+
+ /*
+ * Atomically set the bitmap for the interface number
+ */
+ set_bit(if_num, ipsec_cmn_pvt.if_map);
+
+ return nss_ctx;
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_register_if);
+
+/*
+ * nss_ipsec_cmn_unregister_if()
+ * Unregister dynamic node for IPSEC redir.
+ */
+bool nss_ipsec_cmn_unregister_if(uint32_t if_num)
+{
+ struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context();
+ struct net_device *dev;
+ uint32_t status;
+
+ nss_assert(nss_ctx);
+
+ if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, if_num)) {
+ nss_warning("%p: Invalid IPsec interface(%u)\n", nss_ctx, if_num);
+ return false;
+ }
+
+ dev = nss_cmn_get_interface_dev(nss_ctx, if_num);
+ if (!dev) {
+ nss_warning("%p: Failed to find registered netdev for IPsec NSS I/F:%u\n", nss_ctx, if_num);
+ return false;
+ }
+
+ nss_top_main.if_rx_msg_callback[if_num] = NULL;
+ nss_core_unregister_subsys_dp(nss_ctx, if_num);
+
+ /*
+ * Atomically clear the bitmap for the interface number
+ */
+ clear_bit(if_num, ipsec_cmn_pvt.if_map);
+
+ status = nss_core_unregister_handler(nss_ctx, if_num);
+ if (status != NSS_CORE_STATUS_SUCCESS) {
+ nss_warning("%p: Failed to unregister handler for IPsec NSS I/F:%u\n", nss_ctx, if_num);
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_unregister_if);
+
+/*
+ * nss_ipsec_cmn_notify_register()
+ * Register a handler for notification from NSS firmware.
+ */
+struct nss_ctx_instance *nss_ipsec_cmn_notify_register(uint32_t if_num, nss_ipsec_cmn_msg_callback_t cb, void *app_data)
+{
+ struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context();
+ uint32_t ret;
+
+ BUG_ON(!nss_ctx);
+
+ ret = nss_core_register_handler(nss_ctx, if_num, nss_ipsec_cmn_msg_handler, app_data);
+ if (ret != NSS_CORE_STATUS_SUCCESS) {
+ nss_warning("%p: unable to register event handler for interface(%u)\n", nss_ctx, if_num);
+ return NULL;
+ }
+
+ nss_top_main.if_rx_msg_callback[if_num] = cb;
+ return nss_ctx;
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_notify_register);
+
+/*
+ * nss_ipsec_cmn_notify_unregister()
+ * unregister the IPsec notifier for the given interface number (if_num)
+ */
+void nss_ipsec_cmn_notify_unregister(struct nss_ctx_instance *nss_ctx, uint32_t if_num)
+{
+ uint32_t ret;
+
+ if (if_num >= NSS_MAX_NET_INTERFACES) {
+ nss_warning("%p: notify unregister received for invalid interface %d\n", nss_ctx, if_num);
+ return;
+ }
+
+ ret = nss_core_unregister_handler(nss_ctx, if_num);
+ if (ret != NSS_CORE_STATUS_SUCCESS) {
+ nss_warning("%p: unable to unregister event handler for interface(%u)\n", nss_ctx, if_num);
+ return;
+ }
+
+ nss_top_main.if_rx_msg_callback[if_num] = NULL;
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_notify_unregister);
+
+/*
+ * nss_ipsec_cmn_ppe_port_config()
+ * Configure PPE port for IPsec inline
+ */
+bool nss_ipsec_cmn_ppe_port_config(struct nss_ctx_instance *nss_ctx, struct net_device *netdev,
+ uint32_t if_num, uint32_t vsi_num)
+{
+#ifdef NSS_PPE_SUPPORTED
+ if_num = NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num);
+
+ if (nss_ppe_tx_ipsec_config_msg(if_num, vsi_num, netdev->mtu, netdev->mtu) != NSS_TX_SUCCESS) {
+ nss_warning("%p: Failed to configure PPE IPsec port\n", nss_ctx);
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_ppe_port_config);
+
+/*
+ * nss_ipsec_cmn_ppe_mtu_update()
+ * Update PPE MTU for IPsec inline
+ */
+bool nss_ipsec_cmn_ppe_mtu_update(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint16_t mtu, uint16_t mru)
+{
+#ifdef NSS_PPE_SUPPORTED
+ if_num = NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num);
+
+ if (nss_ppe_tx_ipsec_mtu_msg(if_num, mtu, mru) != NSS_TX_SUCCESS) {
+ nss_warning("%p: Failed to update PPE MTU for IPsec port\n", nss_ctx);
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+EXPORT_SYMBOL(nss_ipsec_cmn_ppe_mtu_update);
+
+/*
+ * nss_ipsec_cmn_register_handler()
+ * Registering handler for sending msg to base ipsec_cmn node on NSS.
+ */
+void nss_ipsec_cmn_register_handler(void)
+{
+ sema_init(&ipsec_cmn_pvt.sem, 1);
+ init_completion(&ipsec_cmn_pvt.complete);
+ nss_stats_create_dentry("ipsec_cmn", &nss_ipsec_cmn_stats_ops);
+}
diff --git a/nss_ipsec_cmn_log.c b/nss_ipsec_cmn_log.c
new file mode 100644
index 0000000..a126ccc
--- /dev/null
+++ b/nss_ipsec_cmn_log.c
@@ -0,0 +1,354 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_ipsec_cmn_log.c
+ * NSS IPSEC logger file.
+ */
+
+#include "nss_core.h"
+
+#define NSS_IPSEC_LOG_IPV4 4
+#define NSS_IPSEC_LOG_IPV6 6
+
+/*
+ * nss_ipsec_cmn_log_msg_types_str
+ * IPSEC message strings
+ */
+static int8_t *nss_ipsec_cmn_log_msg_types_str[NSS_IPSEC_CMN_MSG_TYPE_MAX] __maybe_unused = {
+ "IPSEC CMN Msg None",
+ "IPSEC CMN Node Config",
+ "IPSEC CMN CTX Config",
+ "IPSEC CMN CTX Sync",
+ "IPSEC CMN SA Create",
+ "IPSEC CMN SA Destroy",
+ "IPSEC CMN SA Sync",
+ "IPSEC CMN Flow Create",
+ "IPSEC CMN Flow Destroy",
+};
+
+/*
+ * nss_ipsec_cmn_log_node_msg_types_str
+ * IPSEC cmn node message strings
+ */
+static int8_t *nss_ipsec_cmn_log_node_str[] __maybe_unused = {
+ "IPSEC CMN Node DMA Redirect",
+ "IPSEC CMN Node DMA Lookaside",
+ "IPSEC CMN Node Maximum SA",
+};
+
+/*
+ * nss_ipsec_cmn_log_ctx_msg_types_str
+ * IPSEC cmn ctx message strings
+ */
+static int8_t *nss_ipsec_cmn_log_ctx_str[] __maybe_unused = {
+ "IPSEC CMN CTX Type",
+ "IPSEC CMN CTX Exception Interface",
+};
+
+/*
+ * nss_ipsec_cmn_log_ctx_types_str
+ * IPSEC cmn context strings
+ */
+static int8_t *nss_ipsec_cmn_ctx_types_str[] __maybe_unused = {
+ "IPSEC CMN CTX NONE",
+ "IPSEC CMN CTX INNER",
+ "IPSEC CMN CTX INNER BOUNCE",
+ "IPSEC CMN CTX OUTER",
+ "IPSEC CMN CTX OUTER BOUNCE",
+ "IPSEC CMN CTX REDIRECT",
+};
+
+/*
+ * nss_ipsec_cmn_log_flow_tuple_str
+ * IPSEC cmn flow tuple strings
+ */
+static int8_t *nss_ipsec_cmn_log_flow_tuple_str[] __maybe_unused = {
+ "Dest IP",
+ "Src IP",
+ "Spi Index",
+ "Dest Port",
+ "Src Port",
+ "User Pattern",
+ "User Protocol",
+ "IP Version",
+};
+
+/*
+ * nss_ipsec_cmn_log_sa_tuple_str
+ * IPSEC cmn SA tuple strings
+ */
+static int8_t *nss_ipsec_cmn_log_sa_tuple_str[] __maybe_unused = {
+ "Dest IP",
+ "Src IP",
+ "Spi Index",
+ "Dest Port",
+ "Src Port",
+ "Crypto Index",
+ "Protocol",
+ "IP Version",
+ "Hop Limit",
+};
+
+/*
+ * nss_ipsec_cmn_log_sa_data_str
+ * IPSEC cmn SA tuple strings
+ */
+static int8_t *nss_ipsec_cmn_log_sa_data_str[] __maybe_unused = {
+ "Sequence Start",
+ "Flags",
+ "Window Size",
+ "DSCP",
+ "DF",
+ "Block Length",
+ "IV length",
+ "ICV length",
+};
+
+/*
+ * nss_ipsec_cmn_log_error_str
+ * Strings for error types for IPSEC messages
+ */
+static int8_t *nss_ipsec_cmn_log_error_str[NSS_IPSEC_CMN_MSG_ERROR_MAX] __maybe_unused = {
+ "IPSEC No Error",
+ "IPSEC Invalid Context",
+ "IPSEC SA allocation Error",
+ "IPSEC Invalid SA",
+ "IPSEC Duplicate SA",
+ "IPSEC SA is in Use",
+ "IPSEC Error in Flow Allocation",
+ "IPSEC Invalid Flow",
+ "IPSEC Duplicate Flow",
+ "IPSEC Failure to find SA for Flow",
+ "IPSEC Failed to Register Dynamic Interface",
+ "IPSEC Unhandled Message",
+};
+
+/*
+ * nss_ipsec_cmn_log_node_msg()
+ * Log NSS IPSEC node message.
+ */
+static void nss_ipsec_cmn_log_node_msg(struct nss_ipsec_cmn_msg *nim)
+{
+ struct nss_ipsec_cmn_node *node_msg __maybe_unused = &nim->msg.node;
+
+ nss_trace("%p: NSS IPSEC Node Message:\n"
+ "%s: %d\n"
+ "%s: %d\n"
+ "%s: %d\n", nim,
+ nss_ipsec_cmn_log_node_str[0], node_msg->dma_redirect,
+ nss_ipsec_cmn_log_node_str[1], node_msg->dma_lookaside,
+ nss_ipsec_cmn_log_node_str[2], node_msg->max_sa);
+}
+
+/*
+ * nss_ipsec_cmn_log_ctx_msg()
+ * Log NSS IPSEC ctx message.
+ */
+static void nss_ipsec_cmn_log_ctx_msg(struct nss_ipsec_cmn_msg *nim)
+{
+ struct nss_ipsec_cmn_ctx *ctx_msg __maybe_unused = &nim->msg.ctx;
+
+ nss_trace("%p: NSS IPSEC CTX Message:\n"
+ "%s: %s\n"
+ "%s: %d\n", nim,
+ nss_ipsec_cmn_log_ctx_str[0], nss_ipsec_cmn_ctx_types_str[ctx_msg->type],
+ nss_ipsec_cmn_log_ctx_str[1], ctx_msg->except_ifnum);
+}
+
+/*
+ * nss_ipsec_cmn_log_sa_msg()
+ * Log NSS IPSEC SA message.
+ */
+static void nss_ipsec_cmn_log_sa_msg(struct nss_ipsec_cmn_msg *nim)
+{
+ struct nss_ipsec_cmn_sa *sa_msg __maybe_unused = &nim->msg.sa;
+ struct nss_ipsec_cmn_sa_tuple *tuple = &sa_msg->sa_tuple;
+ struct nss_ipsec_cmn_sa_data *data __maybe_unused = &sa_msg->sa_data;
+
+ nss_trace("%p: NSS IPSEC SA Message:\n", nim);
+
+ if (tuple->ip_ver == 4) {
+ nss_trace("%s: %pI4\n%s: %pI4\n",
+ nss_ipsec_cmn_log_sa_tuple_str[0], tuple->dest_ip,
+ nss_ipsec_cmn_log_sa_tuple_str[1], tuple->src_ip);
+ } else {
+ nss_trace("%s: %pI6\n%s: %pI6\n",
+ nss_ipsec_cmn_log_sa_tuple_str[0], tuple->dest_ip,
+ nss_ipsec_cmn_log_sa_tuple_str[1], tuple->src_ip);
+ }
+
+ nss_trace( "%s: %x\n%s: %d\n%s: %d\n%s: %d\n"
+ "%s: %d\n%s: %d\n%s: %d\n"
+ "%s: %d\n%s: %x\n%s: %d\n%s: %d\n"
+ "%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
+ nss_ipsec_cmn_log_sa_tuple_str[2], tuple->spi_index,
+ nss_ipsec_cmn_log_sa_tuple_str[3], tuple->dest_port,
+ nss_ipsec_cmn_log_sa_tuple_str[4], tuple->src_port,
+ nss_ipsec_cmn_log_sa_tuple_str[5], tuple->crypto_index,
+ nss_ipsec_cmn_log_sa_tuple_str[6], tuple->protocol,
+ nss_ipsec_cmn_log_sa_tuple_str[7], tuple->ip_ver,
+ nss_ipsec_cmn_log_sa_tuple_str[8], tuple->hop_limit,
+
+ nss_ipsec_cmn_log_sa_data_str[0], data->seq_start,
+ nss_ipsec_cmn_log_sa_data_str[1], data->flags,
+ nss_ipsec_cmn_log_sa_data_str[2], data->window_size,
+ nss_ipsec_cmn_log_sa_data_str[3], data->dscp,
+ nss_ipsec_cmn_log_sa_data_str[4], data->df,
+ nss_ipsec_cmn_log_sa_data_str[5], data->blk_len,
+ nss_ipsec_cmn_log_sa_data_str[6], data->iv_len,
+ nss_ipsec_cmn_log_sa_data_str[7], data->icv_len);
+
+}
+
+/*
+ * nss_ipsec_cmn_log_flow_msg()
+ * Log NSS IPSEC Flow message.
+ */
+static void nss_ipsec_cmn_log_flow_msg(struct nss_ipsec_cmn_msg *nim)
+{
+ struct nss_ipsec_cmn_flow *flow_msg __maybe_unused = &nim->msg.flow;
+ struct nss_ipsec_cmn_flow_tuple *flow = &flow_msg->flow_tuple;
+ struct nss_ipsec_cmn_sa_tuple *sa = &flow_msg->sa_tuple;
+
+ nss_trace("%p: NSS IPSEC Flow Message:\n", nim);
+
+ if (sa->ip_ver == 4) {
+ nss_trace("%s: %pI4\n%s: %pI4\n",
+ nss_ipsec_cmn_log_sa_tuple_str[0], sa->dest_ip,
+ nss_ipsec_cmn_log_sa_tuple_str[1], sa->src_ip);
+ } else {
+ nss_trace("%s: %pI6\n%s: %pI6\n",
+ nss_ipsec_cmn_log_sa_tuple_str[0], sa->dest_ip,
+ nss_ipsec_cmn_log_sa_tuple_str[1], sa->src_ip);
+ }
+
+ if (flow->ip_ver == 4) {
+ nss_trace("%s: %pI4\n%s: %pI4\n",
+ nss_ipsec_cmn_log_sa_tuple_str[0], flow->dest_ip,
+ nss_ipsec_cmn_log_sa_tuple_str[1], flow->src_ip);
+ } else {
+ nss_trace("%s: %pI6\n%s: %pI6\n",
+ nss_ipsec_cmn_log_sa_tuple_str[0], flow->dest_ip,
+ nss_ipsec_cmn_log_sa_tuple_str[1], flow->src_ip);
+ }
+
+ nss_trace( "%s: %x\n%s: %d\n%s: %d\n%s: %d\n"
+ "%s: %d\n",
+ nss_ipsec_cmn_log_flow_tuple_str[2], flow->spi_index,
+ nss_ipsec_cmn_log_flow_tuple_str[3], flow->dst_port,
+ nss_ipsec_cmn_log_flow_tuple_str[4], flow->src_port,
+ nss_ipsec_cmn_log_flow_tuple_str[5], flow->user_pattern,
+ nss_ipsec_cmn_log_flow_tuple_str[6], flow->protocol);
+
+ nss_trace( "%s: %x\n%s: %d\n%s: %d\n%s: %d\n"
+ "%s: %d\n%s: %d\n%s: %d\n",
+ nss_ipsec_cmn_log_sa_tuple_str[2], sa->spi_index,
+ nss_ipsec_cmn_log_sa_tuple_str[3], sa->dest_port,
+ nss_ipsec_cmn_log_sa_tuple_str[4], sa->src_port,
+ nss_ipsec_cmn_log_sa_tuple_str[5], sa->crypto_index,
+ nss_ipsec_cmn_log_sa_tuple_str[6], sa->protocol,
+ nss_ipsec_cmn_log_sa_tuple_str[7], sa->ip_ver,
+ nss_ipsec_cmn_log_sa_tuple_str[8], sa->hop_limit);
+}
+
+/*
+ * nss_ipsec_cmn_log_verbose()
+ * Log message contents.
+ */
+static void nss_ipsec_cmn_log_verbose(struct nss_ipsec_cmn_msg *nim)
+{
+ switch (nim->cm.type) {
+ case NSS_IPSEC_CMN_MSG_TYPE_NODE_CONFIG:
+ nss_ipsec_cmn_log_node_msg(nim);
+ break;
+
+ case NSS_IPSEC_CMN_MSG_TYPE_CTX_CONFIG:
+ nss_ipsec_cmn_log_ctx_msg(nim);
+ break;
+
+ case NSS_IPSEC_CMN_MSG_TYPE_SA_CREATE:
+ case NSS_IPSEC_CMN_MSG_TYPE_SA_DESTROY:
+ nss_ipsec_cmn_log_sa_msg(nim);
+ break;
+
+ case NSS_IPSEC_CMN_MSG_TYPE_FLOW_CREATE:
+ case NSS_IPSEC_CMN_MSG_TYPE_FLOW_DESTROY:
+ nss_ipsec_cmn_log_flow_msg(nim);
+ break;
+
+ case NSS_IPSEC_CMN_MSG_TYPE_CTX_SYNC:
+ case NSS_IPSEC_CMN_MSG_TYPE_SA_SYNC:
+ /*
+ * No log for these valid messages.
+ */
+ break;
+
+ default:
+ nss_warning("%p: Invalid message type\n", nim);
+ break;
+ }
+}
+
+/*
+ * nss_ipsec_cmn_log_tx_msg()
+ * Log messages transmitted to FW.
+ */
+void nss_ipsec_cmn_log_tx_msg(struct nss_ipsec_cmn_msg *nim)
+{
+ if (nim->cm.type >= NSS_IPSEC_CMN_MSG_TYPE_MAX) {
+ nss_warning("%p: Invalid message type\n", nim);
+ return;
+ }
+
+ nss_info("%p: type[%d]:%s\n", nim, nim->cm.type, nss_ipsec_cmn_log_msg_types_str[nim->cm.type]);
+ nss_ipsec_cmn_log_verbose(nim);
+}
+
+/*
+ * nss_ipsec_cmn_log_rx_msg()
+ * Log messages received from FW.
+ */
+void nss_ipsec_cmn_log_rx_msg(struct nss_ipsec_cmn_msg *nim)
+{
+ if (nim->cm.response >= NSS_CMN_RESPONSE_LAST) {
+ nss_warning("%p: Invalid response\n", nim);
+ return;
+ }
+
+ if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nim->cm.response == NSS_CMN_RESPONSE_ACK)) {
+ nss_info("%p: type[%d]:%s, response[%d]:%s\n", nim, nim->cm.type,
+ nss_ipsec_cmn_log_msg_types_str[nim->cm.type],
+ nim->cm.response, nss_cmn_response_str[nim->cm.response]);
+ goto verbose;
+ }
+
+ if (nim->cm.error >= NSS_IPSEC_CMN_MSG_ERROR_MAX) {
+ nss_warning("%p: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n",
+ nim, nim->cm.type, nss_ipsec_cmn_log_msg_types_str[nim->cm.type],
+ nim->cm.response, nss_cmn_response_str[nim->cm.response],
+ nim->cm.error);
+ goto verbose;
+ }
+
+ nss_info("%p: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n",
+ nim, nim->cm.type, nss_ipsec_cmn_log_msg_types_str[nim->cm.type],
+ nim->cm.response, nss_cmn_response_str[nim->cm.response],
+ nim->cm.error, nss_ipsec_cmn_log_error_str[nim->cm.error]);
+
+verbose:
+ nss_ipsec_cmn_log_verbose(nim);
+}
diff --git a/nss_ipsec_cmn_log.h b/nss_ipsec_cmn_log.h
new file mode 100644
index 0000000..d99c8be
--- /dev/null
+++ b/nss_ipsec_cmn_log.h
@@ -0,0 +1,37 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * ****************************************************************************
+ */
+
+#ifndef __NSS_IPSEC_CMN_LOG_H__
+#define __NSS_IPSEC_CMN_LOG_H__
+
+/*
+ * nss_ipsec_cmn_log.h
+ * NSS Crypto Log Header File
+ */
+
+/*
+ * nss_ipsec_cmn_log_tx_msg
+ * Logs a ipsec message that is sent to the NSS firmware.
+ */
+void nss_ipsec_cmn_log_tx_msg(struct nss_ipsec_cmn_msg *nim);
+
+/*
+ * nss_ipsec_cmn_log_rx_msg
+ * Logs a ipsec message that is received from the NSS firmware.
+ */
+void nss_ipsec_cmn_log_rx_msg(struct nss_ipsec_cmn_msg *nim);
+
+#endif /* __NSS_IPSEC_CMN_LOG_H__ */
diff --git a/nss_tx_rx_common.h b/nss_tx_rx_common.h
index 904c60b..65a9124 100644
--- a/nss_tx_rx_common.h
+++ b/nss_tx_rx_common.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -62,6 +62,7 @@
extern void nss_crypto_register_handler(void);
extern void nss_crypto_cmn_register_handler(void);
extern void nss_ipsec_register_handler(void);
+extern void nss_ipsec_cmn_register_handler(void);
extern void nss_ipv4_register_handler(void);
extern void nss_ipv4_reasm_register_handler(void);
extern void nss_ipv6_register_handler(void);