Adding suppport for boot time #Conn cfg
Adding support using sysctl to configure the number of
connections supported by IPv4 and IPv6 in NSS FW. This
configuration is boot time configuration. Update file
/etc/sysctl.conf with the following entry (an example)
dev.nss.ipv4cfg.ipv4_conn=512
dev.nss.ipv6cfg.ipv6_conn=1024
Change-Id: Ifb3e655d330cd79048231fae60d27dbb9eb37856
Signed-off-by: Vijay Dewangan <vdewanga@codeaurora.org>
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index 6549a84..f6698e9 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -369,7 +369,6 @@
#define NSS_IPV6_CREATE_FLAG_VLAN_MARKING 0x10
/** Rule for VLAN marking */
-
/**
* Structure to be used while sending an IPv6 flow/connection destroy rule.
*/
diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h
index 24a7da4..595593a 100644
--- a/exports/nss_ipv4.h
+++ b/exports/nss_ipv4.h
@@ -36,6 +36,7 @@
NSS_IPV4_RX_ESTABLISH_RULE_MSG, /**< IPv4 establish rule message */
NSS_IPV4_RX_CONN_STATS_SYNC_MSG, /**< IPv4 connection stats sync message */
NSS_IPV4_RX_NODE_STATS_SYNC_MSG, /**< IPv4 generic statistics sync message */
+ NSS_IPV4_TX_CONN_CFG_RULE_MSG, /**< IPv4 number of connections supported rule message */
NSS_IPV4_MAX_MSG_TYPES, /**< IPv4 message max type number */
};
@@ -187,6 +188,14 @@
};
/**
+ * The IPv4 rule number of supported connections sub-message structure.
+ */
+struct nss_ipv4_rule_conn_cfg_msg {
+ uint32_t num_conn; /**< Number of supported IPv4 connections */
+};
+
+
+/**
* The NSS IPv4 rule establish structure.
*/
struct nss_ipv4_rule_establish {
@@ -373,6 +382,7 @@
struct nss_ipv4_rule_establish rule_establish; /**< Message: rule establish confirmation */
struct nss_ipv4_conn_sync conn_stats; /**< Message: connection stats sync */
struct nss_ipv4_node_sync node_stats; /**< Message: node stats sync */
+ struct nss_ipv4_rule_conn_cfg_msg rule_conn_cfg; /**< Message: rule connections supported */
} msg;
};
@@ -422,4 +432,18 @@
*/
extern void nss_ipv4_register_handler(void);
+/**
+ * @brief IPv4 sysctl register
+ *
+ * @return None
+ */
+extern void nss_ipv4_register_sysctl(void);
+
+/**
+ * @brief IPv4 sysctl unregister
+ *
+ * @return None
+ */
+extern void nss_ipv4_unregister_sysctl(void);
+
#endif /* __NSS_IPV4_H */
diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h
index e08513a..7535e66 100644
--- a/exports/nss_ipv6.h
+++ b/exports/nss_ipv6.h
@@ -36,6 +36,7 @@
NSS_IPV6_RX_ESTABLISH_RULE_MSG, /**< IPv6 establish rule message */
NSS_IPV6_RX_CONN_STATS_SYNC_MSG, /**< IPv6 connection stats sync message */
NSS_IPV6_RX_NODE_STATS_SYNC_MSG, /**< IPv6 generic statistics sync message */
+ NSS_IPV6_TX_CONN_CFG_RULE_MSG, /**< IPv6 connection cfg rule message */
NSS_IPV6_MAX_MSG_TYPES,
};
@@ -225,6 +226,13 @@
};
/**
+ * The IPv6 rule conn cfgsub-message structure.
+ */
+struct nss_ipv6_rule_conn_cfg_msg {
+ uint32_t num_conn; /**< Holds number of supported connections in IPv6 */
+};
+
+/**
* The NSS IPv6 rule establish structure.
*/
struct nss_ipv6_rule_establish {
@@ -344,6 +352,7 @@
struct nss_ipv6_rule_establish rule_establish; /**< Message: rule establish confirmation */
struct nss_ipv6_conn_sync conn_stats; /**< Message: stats sync */
struct nss_ipv6_node_sync node_stats; /**< Message: node stats sync */
+ struct nss_ipv6_rule_conn_cfg_msg rule_conn_cfg;/**< Message: rule conn cfg */
} msg;
};
@@ -392,4 +401,20 @@
* @return none
*/
extern void nss_ipv6_register_handler(void);
+
+/**
+ * @brief IPv4 sysctl register
+ *
+ * @return None
+ */
+extern void nss_ipv6_register_sysctl(void);
+
+/**
+ * @brief IPv4 sysctl unregister
+ *
+ * @return None
+ */
+extern void nss_ipv6_unregister_sysctl(void);
+
+
#endif /* __NSS_IPV6_H */
diff --git a/nss_hlos_if.h b/nss_hlos_if.h
index ec70158..1251ce8 100755
--- a/nss_hlos_if.h
+++ b/nss_hlos_if.h
@@ -22,6 +22,15 @@
#ifndef __NSS_HLOS_IF_H
#define __NSS_HLOS_IF_H
+#define MIN_NUM_CONN 256 /**< MIN Connection shared between IPv4 and IPv6 */
+#define MAX_TOTAL_NUM_CONN_IPV4_IPV6 8196 /**< MAX Connection shared between IPv4 and IPv6 */
+
+/*
+ * Variables used for sysctl updates.
+ */
+extern int nss_ipv4_conn_cfg;
+extern int nss_ipv6_conn_cfg;
+
/*
* Request/Response types
*/
diff --git a/nss_init.c b/nss_init.c
index 4d04bdd..646ab0d 100755
--- a/nss_init.c
+++ b/nss_init.c
@@ -829,30 +829,29 @@
.data = &nss_ctl_redirect,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec,
},
{
.procname = "debug",
.data = &nss_ctl_debug,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &nss_debug_handler,
+ .proc_handler = &nss_debug_handler,
},
{
.procname = "coredump",
.data = &nss_cmd_buf.coredump,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &nss_coredump_handler,
+ .proc_handler = &nss_coredump_handler,
},
{
.procname = "rps",
.data = &nss_rps_cfg,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &nss_rpscfg_handler,
+ .proc_handler = &nss_rpscfg_handler,
},
-
{ }
};
@@ -921,6 +920,12 @@
nss_dev_header = register_sysctl_table(nss_root);
/*
+ * Registering sysctl for ipv4/6 specific config.
+ */
+ nss_ipv4_register_sysctl();
+ nss_ipv6_register_sysctl();
+
+ /*
* Setup Runtime Sample values
*/
nss_runtime_samples.freq_scale[0].frequency = NSS_FREQ_110;
@@ -980,6 +985,12 @@
if (nss_dev_header)
unregister_sysctl_table(nss_dev_header);
+ /*
+ * Unregister ipv4/6 specific sysctl
+ */
+ nss_ipv4_unregister_sysctl();
+ nss_ipv6_unregister_sysctl();
+
platform_driver_unregister(&nss_driver);
}
diff --git a/nss_ipv4.c b/nss_ipv4.c
index 05bdea3..68d28b9 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -18,6 +18,7 @@
* nss_ipv4.c
* NSS IPv4 APIs
*/
+#include <linux/sysctl.h>
#include <linux/ppp_channel.h>
#include "nss_tx_rx_common.h"
@@ -25,6 +26,8 @@
extern void nss_rx_metadata_ipv4_create_response(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim);
extern void nss_rx_ipv4_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync *nirs);
+int nss_ipv4_conn_cfg __read_mostly = 4096;
+
/*
* nss_ipv4_driver_conn_sync_update()
* Update driver specific information from the messsage.
@@ -300,7 +303,153 @@
}
}
+/*
+ * nss_ipv4_conn_cfg_callback()
+ * call back function for the ipv6 connection configuration handler
+ */
+static void nss_ipv4_conn_cfg_callback(void *app_data, struct nss_if_msg *nim)
+{
+
+ if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
+ nss_warning("IPv4 connection configuration failed with error: %d\n", nim->cm.error);
+ return;
+ }
+
+ nss_info("IPv4 connection configuration success: %d\n", nim->cm.error);
+}
+
+/*
+ * nss_ipv4_conn_cfg_handler()
+ * Sets the number of connections for IPv4
+ */
+static int nss_ipv4_conn_cfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
+ struct nss_ipv4_msg nim;
+ struct nss_ipv4_rule_conn_cfg_msg *nirccm;
+ nss_tx_status_t nss_tx_status;
+ int ret = 1;
+ uint32_t sum_of_conn = nss_ipv4_conn_cfg + nss_ipv6_conn_cfg;
+
+ /*
+ * The input should be power of 2.
+ * Input for ipv4 and ipv6 sum togther should not exceed 8k
+ * Min. value should be at leat 256 connections. This is the
+ * minimum connections we will support for each of them.
+ */
+ if ((nss_ipv4_conn_cfg & (nss_ipv4_conn_cfg - 1)) ||
+ (sum_of_conn > MAX_TOTAL_NUM_CONN_IPV4_IPV6) ||
+ (nss_ipv4_conn_cfg < MIN_NUM_CONN)) {
+ nss_warning("%p: input supported connections (%d) does not adhere\
+ specifications\n1) not power of 2,\n2) is less than \
+ min val: %d, OR\n IPv4/6 total exceeds %d\n",
+ nss_ctx,
+ nss_ipv4_conn_cfg,
+ MIN_NUM_CONN,
+ MAX_TOTAL_NUM_CONN_IPV4_IPV6);
+ return ret;
+ }
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+
+ if (ret) {
+ return ret;
+ }
+
+ if ((!write)) {
+ nss_warning("%p: IPv4 supported connections write failed: %d\n", nss_ctx, nss_ipv4_conn_cfg);
+ return ret;
+ }
+
+
+ nss_info("%p: IPv4 supported connections: %d\n", nss_ctx, nss_ipv4_conn_cfg);
+
+ nss_cmn_msg_init(&nim.cm, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_CONN_CFG_RULE_MSG,
+ sizeof(struct nss_ipv4_rule_conn_cfg_msg), nss_ipv4_conn_cfg_callback, NULL);
+
+ nirccm = &nim.msg.rule_conn_cfg;
+ nirccm->num_conn = htonl(nss_ipv4_conn_cfg);
+ nss_tx_status = nss_ipv4_tx(nss_ctx, &nim);
+
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: nss_tx error setting IPv4 Connections: %d\n",
+ nss_ctx,
+ nss_ipv4_conn_cfg);
+ }
+ return ret;
+}
+
+static ctl_table nss_ipv4_table[] = {
+ {
+ .procname = "ipv4_conn",
+ .data = &nss_ipv4_conn_cfg,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_ipv4_conn_cfg_handler,
+ },
+ { }
+};
+
+static ctl_table nss_ipv4_dir[] = {
+ {
+ .procname = "ipv4cfg",
+ .mode = 0555,
+ .child = nss_ipv4_table,
+ },
+ { }
+};
+
+
+static ctl_table nss_ipv4_root_dir[] = {
+ {
+ .procname = "nss",
+ .mode = 0555,
+ .child = nss_ipv4_dir,
+ },
+ { }
+};
+
+static ctl_table nss_ipv4_root[] = {
+ {
+ .procname = "dev",
+ .mode = 0555,
+ .child = nss_ipv4_root_dir,
+ },
+ { }
+};
+
+static struct ctl_table_header *nss_ipv4_header;
+
+/*
+ * nss_ipv4_register_sysctl()
+ * Register sysctl specific to ipv4
+ */
+void nss_ipv4_register_sysctl(void)
+{
+ /*
+ * Register sysctl table.
+ */
+ nss_ipv4_header = register_sysctl_table(nss_ipv4_root);
+}
+
+/*
+ * nss_ipv4_unregister_sysctl()
+ * Unregister sysctl specific to ipv4
+ */
+void nss_ipv4_unregister_sysctl(void)
+{
+ /*
+ * Unregister sysctl table.
+ */
+ if (nss_ipv4_header) {
+ unregister_sysctl_table(nss_ipv4_header);
+ }
+}
+
EXPORT_SYMBOL(nss_ipv4_tx);
EXPORT_SYMBOL(nss_ipv4_notify_register);
EXPORT_SYMBOL(nss_ipv4_notify_unregister);
EXPORT_SYMBOL(nss_ipv4_get_mgr);
+EXPORT_SYMBOL(nss_ipv4_register_sysctl);
+EXPORT_SYMBOL(nss_ipv4_unregister_sysctl);
diff --git a/nss_ipv6.c b/nss_ipv6.c
index 94bfc81..3b51486 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -25,6 +25,8 @@
extern void nss_rx_metadata_ipv6_create_response(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim);
extern void nss_rx_ipv6_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nirs);
+int nss_ipv6_conn_cfg __read_mostly = 4096;
+
/*
* nss_ipv6_driver_conn_sync_update()
* Update driver specific information from the messsage.
@@ -300,8 +302,153 @@
}
}
+/*
+ * nss_ipv6_conn_cfg_callback()
+ * call back function for the ipv6 connection configuration handler
+ */
+static void nss_ipv6_conn_cfg_callback(void *app_data, struct nss_if_msg *nim)
+{
+ if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
+ nss_warning("IPv6 connection configuration failed with error: %d\n", nim->cm.error);
+ return;
+ }
+
+ nss_info("IPv6 connection configuration success: %d\n", nim->cm.error);
+}
+
+
+/*
+ * nss_ipv6_conn_cfg_handler()
+ * Sets the number of connections for IPv6
+ */
+static int nss_ipv6_conn_cfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
+ struct nss_ipv6_msg nim;
+ struct nss_ipv6_rule_conn_cfg_msg *nirccm;
+ nss_tx_status_t nss_tx_status;
+ int ret = 1;
+ uint32_t sum_of_conn = nss_ipv4_conn_cfg + nss_ipv6_conn_cfg;
+
+ /*
+ * Specifications for input
+ * 1) The input should be power of 2.
+ * 2) Input for ipv4 and ipv6 sum togther should not exceed 8k
+ * 3) Min. value should be at leat 256 connections. This is the
+ * minimum connections we will support for each of them.
+ */
+ if ((nss_ipv6_conn_cfg & (nss_ipv6_conn_cfg - 1)) ||
+ (sum_of_conn > MAX_TOTAL_NUM_CONN_IPV4_IPV6) ||
+ (nss_ipv6_conn_cfg < MIN_NUM_CONN)) {
+ nss_warning("%p: input supported connections (%d) does not adhere\
+ specifications\n1) not power of 2,\n2) is less than \
+ min val: %d, OR\n IPv4/6 total exceeds %d\n",
+ nss_ctx,
+ nss_ipv6_conn_cfg,
+ MIN_NUM_CONN,
+ MAX_TOTAL_NUM_CONN_IPV4_IPV6);
+ return ret;
+ }
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+
+ if (ret) {
+ return ret;
+ }
+
+ if (!write) {
+ nss_warning("%p: IPv6 supported connections write failed: %d\n", nss_ctx, nss_ipv6_conn_cfg);
+ return ret;
+ }
+
+ nss_info("%p: IPv6 supported connections: %d\n", nss_ctx, nss_ipv6_conn_cfg);
+
+ nss_cmn_msg_init(&nim.cm, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_CFG_RULE_MSG,
+ sizeof(struct nss_ipv6_rule_conn_cfg_msg), nss_ipv6_conn_cfg_callback, NULL);
+
+ nirccm = &nim.msg.rule_conn_cfg;
+ nirccm->num_conn = htonl(nss_ipv6_conn_cfg);
+ nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
+
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: nss_tx error setting IPv6 Connections: %d\n",
+ nss_ctx,
+ nss_ipv6_conn_cfg);
+ }
+ return ret;
+}
+
+static ctl_table nss_ipv6_table[] = {
+ {
+ .procname = "ipv6_conn",
+ .data = &nss_ipv6_conn_cfg,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_ipv6_conn_cfg_handler,
+ },
+ { }
+};
+
+static ctl_table nss_ipv6_dir[] = {
+ {
+ .procname = "ipv6cfg",
+ .mode = 0555,
+ .child = nss_ipv6_table,
+ },
+ { }
+};
+
+static ctl_table nss_ipv6_root_dir[] = {
+ {
+ .procname = "nss",
+ .mode = 0555,
+ .child = nss_ipv6_dir,
+ },
+ { }
+};
+
+static ctl_table nss_ipv6_root[] = {
+ {
+ .procname = "dev",
+ .mode = 0555,
+ .child = nss_ipv6_root_dir,
+ },
+ { }
+};
+
+static struct ctl_table_header *nss_ipv6_header;
+
+/*
+ * nss_ipv6_register_sysctl()
+ * Register sysctl specific to ipv4
+ */
+void nss_ipv6_register_sysctl(void)
+{
+ /*
+ * Register sysctl table.
+ */
+ nss_ipv6_header = register_sysctl_table(nss_ipv6_root);
+}
+
+/*
+ * nss_ipv6_unregister_sysctl()
+ * Unregister sysctl specific to ipv4
+ */
+void nss_ipv6_unregister_sysctl(void)
+{
+ /*
+ * Unregister sysctl table.
+ */
+ if (nss_ipv6_header) {
+ unregister_sysctl_table(nss_ipv6_header);
+ }
+}
+
EXPORT_SYMBOL(nss_ipv6_tx);
EXPORT_SYMBOL(nss_ipv6_notify_register);
EXPORT_SYMBOL(nss_ipv6_notify_unregister);
EXPORT_SYMBOL(nss_ipv6_get_mgr);
EXPORT_SYMBOL(nss_ipv6_register_handler);
+EXPORT_SYMBOL(nss_ipv6_register_sysctl);
+EXPORT_SYMBOL(nss_ipv6_unregister_sysctl);