[qca-nss-sfe] SAWF related changes in SFE.
1. Adding sawf_metadata in SFE connection information
2. Addition of per cpu per service class stats DB as part of SFE.
Change-Id: I44e2a0d7b6144ee28a24fc5edd21fdc1cd439142
Signed-off-by: Parikshit Gune <quic_pgune@quicinc.com>
diff --git a/sfe_ipv4.c b/sfe_ipv4.c
index 3b3d1cb..b5416d0 100644
--- a/sfe_ipv4.c
+++ b/sfe_ipv4.c
@@ -32,6 +32,7 @@
#include <linux/netfilter.h>
#include <linux/inetdevice.h>
#include <linux/netfilter_ipv4.h>
+#include <linux/seqlock.h>
#include <net/protocol.h>
#include <net/gre.h>
@@ -733,6 +734,21 @@
}
/*
+ * sfe_ipv4_service_class_stats_inc()
+ * Increment per cpu per service class stats.
+ */
+void sfe_ipv4_service_class_stats_inc(struct sfe_ipv4 *si, uint8_t sid, uint64_t bytes)
+{
+ struct sfe_ipv4_service_class_stats_db *sc_stats_db = this_cpu_ptr(si->stats_pcpu_psc);
+ struct sfe_ipv4_per_service_class_stats *sc_stats = &sc_stats_db->psc_stats[sid];
+
+ write_seqcount_begin(&sc_stats->seq);
+ sc_stats->tx_bytes += bytes;
+ sc_stats->tx_packets++;
+ write_seqcount_end(&sc_stats->seq);
+}
+
+/*
* sfe_ipv4_exception_stats_inc()
* Increment exception stats.
*/
@@ -1055,6 +1071,8 @@
struct net *net;
struct sock *sk;
unsigned int src_if_idx;
+ u32 flow_sawf_tag;
+ u32 return_sawf_tag;
if (msg->rule_flags & SFE_RULE_CREATE_FLAG_USE_FLOW_BOTTOM_INTERFACE) {
flow_interface_num = msg->conn_rule.flow_interface_num;
@@ -1232,6 +1250,17 @@
}
/*
+ * Mark SAWF metadata if the sawf tag is valid and set.
+ */
+ original_cm->sawf_valid = false;
+ flow_sawf_tag = SFE_GET_SAWF_TAG(msg->sawf_rule.flow_mark);
+ if (likely(SFE_SAWF_TAG_IS_VALID(flow_sawf_tag))) {
+ original_cm->mark = msg->sawf_rule.flow_mark;
+ original_cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_MARK;
+ original_cm->sawf_valid = true;
+ }
+
+ /*
* Add VLAN rule to original_cm
*/
if (msg->valid_flags & SFE_RULE_CREATE_VLAN_VALID) {
@@ -1435,6 +1464,17 @@
}
/*
+ * Mark SAWF metadata in reply match if the sawf tag is valid.
+ */
+ reply_cm->sawf_valid = false;
+ return_sawf_tag = SFE_GET_SAWF_TAG(msg->sawf_rule.return_mark);
+ if (likely(SFE_SAWF_TAG_IS_VALID(return_sawf_tag))) {
+ reply_cm->mark = msg->sawf_rule.return_mark;
+ reply_cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_MARK;
+ reply_cm->sawf_valid = true;
+ }
+
+ /*
* Setup UDP Socket if found to be valid for decap.
*/
RCU_INIT_POINTER(reply_cm->up, NULL);
@@ -1991,6 +2031,9 @@
u64 dest_rx_bytes;
u64 last_sync_jiffies;
u32 src_mark, dest_mark, src_priority, dest_priority, src_dscp, dest_dscp;
+ bool original_cm_sawf_valid, reply_cm_sawf_valid;
+ u32 flow_service_class, return_service_class;
+ u32 flow_msduq, return_msduq;
u32 packet, byte, original_cm_flags;
u16 pppoe_session_id;
u8 pppoe_remote_mac[ETH_ALEN];
@@ -2051,7 +2094,12 @@
original_cm_flags = original_cm->flags;
pppoe_session_id = original_cm->pppoe_session_id;
ether_addr_copy(pppoe_remote_mac, original_cm->pppoe_remote_mac);
-
+ original_cm_sawf_valid = original_cm->sawf_valid;
+ reply_cm_sawf_valid = reply_cm->sawf_valid;
+ flow_service_class = SFE_GET_SAWF_SERVICE_CLASS(original_cm->mark);
+ flow_msduq = SFE_GET_SAWF_MSDUQ(original_cm->mark);
+ return_service_class = SFE_GET_SAWF_SERVICE_CLASS(reply_cm->mark);
+ return_msduq = SFE_GET_SAWF_MSDUQ(reply_cm->mark);
#ifdef CONFIG_NF_FLOW_COOKIE
src_flow_cookie = original_cm->flow_cookie;
dst_flow_cookie = reply_cm->flow_cookie;
@@ -2103,6 +2151,16 @@
pppoe_session_id, pppoe_remote_mac);
}
+ if (original_cm_sawf_valid) {
+ bytes_read += snprintf(msg + bytes_read, CHAR_DEV_MSG_SIZE, "flow_service_class=\"%d\" flow_msduq=\"%d\" ",
+ flow_service_class, flow_msduq);
+ }
+
+ if (reply_cm_sawf_valid) {
+ bytes_read += snprintf(msg + bytes_read, CHAR_DEV_MSG_SIZE, "return_service_class=\"%d\" return_msduq=\"%d\" ",
+ return_service_class, return_msduq);
+ }
+
bytes_read += snprintf(msg + bytes_read, CHAR_DEV_MSG_SIZE, "/>\n");
if (copy_to_user(buffer + *total_read, msg, CHAR_DEV_MSG_SIZE)) {
@@ -2553,12 +2611,22 @@
}
/*
+ * Allocate per cpu per service class memory.
+ */
+ si->stats_pcpu_psc = alloc_percpu_gfp(struct sfe_ipv4_service_class_stats_db,
+ GFP_KERNEL | __GFP_ZERO);
+ if (!si->stats_pcpu_psc) {
+ DEBUG_ERROR("failed to allocate per cpu per service clas stats memory\n");
+ goto exit1;
+ }
+
+ /*
* Create sys/sfe_ipv4
*/
si->sys_ipv4 = kobject_create_and_add("sfe_ipv4", NULL);
if (!si->sys_ipv4) {
DEBUG_ERROR("failed to register sfe_ipv4\n");
- goto exit1;
+ goto exit2;
}
/*
@@ -2567,20 +2635,20 @@
result = sysfs_create_file(si->sys_ipv4, &sfe_ipv4_debug_dev_attr.attr);
if (result) {
DEBUG_ERROR("failed to register debug dev file: %d\n", result);
- goto exit2;
+ goto exit3;
}
result = sysfs_create_file(si->sys_ipv4, &sfe_ipv4_cpu_attr.attr);
if (result) {
DEBUG_ERROR("failed to register debug dev file: %d\n", result);
- goto exit3;
+ goto exit4;
}
#ifdef CONFIG_NF_FLOW_COOKIE
result = sysfs_create_file(si->sys_ipv4, &sfe_ipv4_flow_cookie_attr.attr);
if (result) {
DEBUG_ERROR("failed to register flow cookie enable file: %d\n", result);
- goto exit4;
+ goto exit5;
}
#endif /* CONFIG_NF_FLOW_COOKIE */
@@ -2592,7 +2660,7 @@
#endif
if (result < 0) {
DEBUG_ERROR("can't register nf local out hook: %d\n", result);
- goto exit5;
+ goto exit6;
}
DEBUG_INFO("Register nf local out hook success: %d\n", result);
#endif
@@ -2602,7 +2670,7 @@
result = register_chrdev(0, "sfe_ipv4", &sfe_ipv4_debug_dev_fops);
if (result < 0) {
DEBUG_ERROR("Failed to register chrdev: %d\n", result);
- goto exit6;
+ goto exit7;
}
si->debug_dev = result;
@@ -2617,7 +2685,7 @@
spin_lock_init(&si->lock);
return 0;
-exit6:
+exit7:
#ifdef SFE_PROCESS_LOCAL_OUT
DEBUG_TRACE("sfe: Unregister local out hook\n");
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0))
@@ -2625,20 +2693,23 @@
#else
nf_unregister_net_hooks(&init_net, sfe_ipv4_ops_local_out, ARRAY_SIZE(sfe_ipv4_ops_local_out));
#endif
-exit5:
+exit6:
#endif
#ifdef CONFIG_NF_FLOW_COOKIE
sysfs_remove_file(si->sys_ipv4, &sfe_ipv4_flow_cookie_attr.attr);
-exit4:
+exit5:
#endif /* CONFIG_NF_FLOW_COOKIE */
sysfs_remove_file(si->sys_ipv4, &sfe_ipv4_cpu_attr.attr);
-exit3:
+exit4:
sysfs_remove_file(si->sys_ipv4, &sfe_ipv4_debug_dev_attr.attr);
-exit2:
+exit3:
kobject_put(si->sys_ipv4);
+exit2:
+ free_percpu(si->stats_pcpu_psc);
+
exit1:
free_percpu(si->stats_pcpu);
@@ -2682,6 +2753,7 @@
kobject_put(si->sys_ipv4);
free_percpu(si->stats_pcpu);
+ free_percpu(si->stats_pcpu_psc);
}
#ifdef CONFIG_NF_FLOW_COOKIE