[qca-nss-clients] Add Multicast support for IPv4 netlink module

Change-Id: I9851d76efb02a4f2a7c139203289ca52e66ed96d
Signed-off-by: Wayne Tan <wtan@codeaurora.org>
diff --git a/netlink/include/nss_nlcmn_if.h b/netlink/include/nss_nlcmn_if.h
index 97d9869..478eaf1 100644
--- a/netlink/include/nss_nlcmn_if.h
+++ b/netlink/include/nss_nlcmn_if.h
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2015,2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015,2018-2020, 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.
@@ -38,6 +38,14 @@
 };
 
 /**
+ * @brief NSS subsystems in alphabetical order for nssinfo tool
+ */
+enum nss_nlcmn_subsys {
+	NSS_NLCMN_SUBSYS_IPV4,
+	NSS_NLCMN_SUBSYS_MAX
+};
+
+/**
  * @brief messages senders must use this to initialize command
  *
  * @param cm[IN] common message
diff --git a/netlink/include/nss_nlipv4_if.h b/netlink/include/nss_nlipv4_if.h
index 0cbd706..ef9de8e 100644
--- a/netlink/include/nss_nlipv4_if.h
+++ b/netlink/include/nss_nlipv4_if.h
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2015-2016,2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016,2018-2020, 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.
@@ -36,15 +36,16 @@
  * @brief IPv4 rule
  */
 struct nss_nlipv4_rule {
-	struct nss_nlcmn cm;			/**< common message header */
+	struct nss_nlcmn cm;				/**< common message header */
 
-	char flow_ifname[IFNAMSIZ];		/**< ingress interface name */
-	char return_ifname[IFNAMSIZ];		/**< egress interface name */
+	char flow_ifname[IFNAMSIZ];			/**< ingress interface name */
+	char return_ifname[IFNAMSIZ];			/**< egress interface name */
 
-	enum nss_nl_iftype flow_iftype;		/**< ingress interface type */
-	enum nss_nl_iftype return_iftype;	/**< egress interface type */
+	enum nss_nl_iftype flow_iftype;			/**< ingress interface type */
+	enum nss_nl_iftype return_iftype;		/**< egress interface type */
 
-	struct nss_ipv4_msg nim;		/**< rule message */
+	struct nss_ipv4_msg nim;			/**< rule message */
+	struct nss_ipv4_stats_notification stats;	/**< NSS statistics*/
 };
 
 /**
diff --git a/netlink/nss_nlipv4.c b/netlink/nss_nlipv4.c
index 6e1fa23..d647036 100644
--- a/netlink/nss_nlipv4.c
+++ b/netlink/nss_nlipv4.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, 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.
@@ -55,7 +55,7 @@
 #include "nss_nlipsec_if.h"
 #include "nss_nlipsec.h"
 #include "nss_nlipv4_if.h"
-
+#include "nss_ipv4.h"
 /*
  * NSS NETLINK IPv4 context
  */
@@ -68,6 +68,7 @@
  */
 static int nss_nlipv4_ops_create_rule(struct sk_buff *skb, struct genl_info *info);
 static int nss_nlipv4_ops_destroy_rule(struct sk_buff *skb, struct genl_info *info);
+static int nss_nlipv4_process_notify(struct notifier_block *nb, unsigned long val, void *data);
 
 /*
  * IPv4 family definition
@@ -98,6 +99,13 @@
 	{.cmd = NSS_IPV4_TX_DESTROY_RULE_MSG, .doit = nss_nlipv4_ops_destroy_rule,},	/* rule destroy */
 };
 
+/*
+ * statistics call back handler for ipv4 from NSS
+ */
+static struct notifier_block nss_ipv4_stats_notifier_nb = {
+	.notifier_call = nss_nlipv4_process_notify,
+};
+
 #define NSS_NLIPV4_OPS_SZ ARRAY_SIZE(nss_nlipv4_ops)
 
 static struct nss_nlipv4_ctx gbl_ctx;
@@ -612,39 +620,24 @@
  * nss_nlipv4_process_notify()
  * 	process notification messages from NSS
  */
-static void nss_nlipv4_process_notify(void *app_data, struct nss_ipv4_msg *nim)
+static int nss_nlipv4_process_notify(struct notifier_block *nb, unsigned long val, void *data)
 {
 	struct nss_nlipv4_rule *nl_rule;
-	struct nss_ipv4_msg *nl_nim;
 	struct sk_buff *skb;
+	struct nss_ipv4_stats_notification *nss_stats;
 
-	skb = nss_nl_new_msg(&nss_nlipv4_family, nim->cm.type);
+	skb = nss_nl_new_msg(&nss_nlipv4_family, NSS_NLCMN_SUBSYS_IPV4);
 	if (!skb) {
 		nss_nl_error("unable to allocate NSS_NLIPV4 event\n");
-		return;
+		return NOTIFY_DONE;
 	}
 
 	nl_rule = nss_nl_get_data(skb);
-	nl_nim = &nl_rule->nim;
-
-	/*
-	 * initialize the NETLINK common header
-	 */
-	nss_nlipv4_rule_init(nl_rule, nim->cm.type);
-
-	/*
-	 * clear NSS common message items that are not useful to uspace
-	 */
-	nim->cm.interface = 0;
-	nim->cm.cb = (nss_ptr_t)NULL;
-	nim->cm.app_data = (nss_ptr_t)NULL;
-
-	/*
-	 * copy the contents of the sync message into the NETLINK message
-	 */
-	memcpy(nl_nim, nim, sizeof(struct nss_ipv4_msg));
-
+	nss_stats = (struct nss_ipv4_stats_notification *)data;
+	memcpy(&nl_rule->stats, nss_stats, sizeof(struct nss_ipv4_stats_notification));
 	nss_nl_mcast_event(&nss_nlipv4_family, skb);
+
+	return NOTIFY_DONE;
 }
 
 /*
@@ -915,7 +908,7 @@
  */
 bool nss_nlipv4_init(void)
 {
-	int error;
+	int error,ret;
 
 	nss_nl_info_always("Init NSS netlink IPv4 handler\n");
 
@@ -931,8 +924,8 @@
 	/*
 	 * register device call back handler for ipv4 from NSS
 	 */
-	gbl_ctx.nss = nss_ipv4_notify_register(nss_nlipv4_process_notify, &gbl_ctx);
-	if (!gbl_ctx.nss) {
+	ret = nss_ipv4_stats_register_notifier(&nss_ipv4_stats_notifier_nb);
+	if (ret) {
 		nss_nl_info_always("Error: retreiving the NSS Context \n");
 		goto unreg_family;
 	}
@@ -970,7 +963,7 @@
 	/*
 	 * Unregister the device callback handler for ipv4
 	 */
-	nss_ipv4_notify_unregister();
+	nss_ipv4_stats_unregister_notifier(&nss_ipv4_stats_notifier_nb);
 
 	gbl_ctx.nss = NULL;