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

Change-Id: I3514c6b60e931b90fbbd490e4912e2352c7ae709
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 836d582..bc56993 100644
--- a/netlink/include/nss_nlcmn_if.h
+++ b/netlink/include/nss_nlcmn_if.h
@@ -49,6 +49,7 @@
 	NSS_NLCMN_SUBSYS_ETHRX,
 	NSS_NLCMN_SUBSYS_IPV4,
 	NSS_NLCMN_SUBSYS_IPV4_REASM,
+	NSS_NLCMN_SUBSYS_IPV6,
 	NSS_NLCMN_SUBSYS_IPV6_REASM,
 	NSS_NLCMN_SUBSYS_N2H,
 	NSS_NLCMN_SUBSYS_MAX
diff --git a/netlink/include/nss_nlipv6_if.h b/netlink/include/nss_nlipv6_if.h
index bdf9216..03726ca 100644
--- a/netlink/include/nss_nlipv6_if.h
+++ b/netlink/include/nss_nlipv6_if.h
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2016,2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 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.
@@ -38,15 +38,16 @@
  * @brief IPv6 rule
  */
 struct nss_nlipv6_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_ipv6_msg nim;		/**< rule message */
+	struct nss_ipv6_msg nim;			/**< rule message */
+	struct nss_ipv6_stats_notification stats;	/**< NSS statistics */
 };
 
 /**
diff --git a/netlink/nss_nlipv6.c b/netlink/nss_nlipv6.c
index f19e826..134955b 100644
--- a/netlink/nss_nlipv6.c
+++ b/netlink/nss_nlipv6.c
@@ -1,6 +1,6 @@
 /*
  **************************************************************************
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-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.
@@ -76,6 +76,7 @@
 
 static int nss_nlipv6_ops_create_rule(struct sk_buff *skb, struct genl_info *info);
 static int nss_nlipv6_ops_destroy_rule(struct sk_buff *skb, struct genl_info *info);
+static int nss_nlipv6_process_notify(struct notifier_block *nb, unsigned long val, void *data);
 
 /*
  * IPV6 family definition
@@ -95,7 +96,7 @@
  * multicast group for sending message status & events
  */
 static struct genl_multicast_group nss_nlipv6_mcgrp[] = {
-	{.name = NSS_NLIPV6_FAMILY},
+	{.name = NSS_NLIPV6_MCAST_GRP},
 };
 
 /*
@@ -106,6 +107,13 @@
 	{.cmd = NSS_IPV6_TX_DESTROY_RULE_MSG, .doit = nss_nlipv6_ops_destroy_rule,},	/* rule destroy */
 };
 
+/*
+ * statistics call back handler for ipv6 from NSS
+ */
+static struct notifier_block nss_ipv6_stats_notifier_nb = {
+	.notifier_call = nss_nlipv6_process_notify,
+};
+
 #define NSS_NLIPV6_OPS_SZ ARRAY_SIZE(nss_nlipv6_ops)
 
 static struct nss_nlipv6_ctx gbl_ctx;
@@ -607,41 +615,26 @@
 
 /*
  * nss_nlipv6_process_notify()
- * 	process notification messages from NSS
+ *	process notification messages from NSS
  */
-static void nss_nlipv6_process_notify(void *app_data, struct nss_ipv6_msg *nim)
+static int nss_nlipv6_process_notify(struct notifier_block *nb, unsigned long val, void *data)
 {
 	struct nss_nlipv6_rule *nl_rule;
-	struct nss_ipv6_msg *nl_nim;
 	struct sk_buff *skb;
+	struct nss_ipv6_stats_notification *nss_stats;
 
-	skb = nss_nl_new_msg(&nss_nlipv6_family, nim->cm.type);
+	skb = nss_nl_new_msg(&nss_nlipv6_family, NSS_NLCMN_SUBSYS_IPV6);
 	if (!skb) {
 		nss_nl_error("unable to allocate NSS_NLIPV6 event\n");
-		return;
+		return NOTIFY_DONE;
 	}
 
 	nl_rule = nss_nl_get_data(skb);
-	nl_nim = &nl_rule->nim;
-
-	/*
-	 * initialize the NETLINK common header
-	 */
-	nss_nlipv6_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_ipv6_msg));
-
+	nss_stats = (struct nss_ipv6_stats_notification *)data;
+	memcpy(&nl_rule->stats, nss_stats, sizeof(struct nss_ipv6_stats_notification));
 	nss_nl_mcast_event(&nss_nlipv6_family, skb);
+
+	return NOTIFY_DONE;
 }
 
 /*
@@ -916,7 +909,7 @@
  */
 bool nss_nlipv6_init(void)
 {
-	int error;
+	int error, ret;
 
 	nss_nl_info_always("Init NSS netlink IPV6 handler\n");
 
@@ -932,21 +925,14 @@
 	/*
 	 * register device call back handler for ipv6 from NSS
 	 */
-	gbl_ctx.nss = nss_ipv6_notify_register(nss_nlipv6_process_notify, &gbl_ctx);
-	if (!gbl_ctx.nss) {
+	ret = nss_ipv6_stats_register_notifier(&nss_ipv6_stats_notifier_nb);
+	if (ret) {
 		nss_nl_info_always("Error: retreiving the NSS Context \n");
-		goto unreg_family;
+		genl_unregister_family(&nss_nlipv6_family);
+		return false;
 	}
 
 	return true;
-
-	/*
-	 * undo all registeration
-	 */
-unreg_family:
-	genl_unregister_family(&nss_nlipv6_family);
-
-	return false;
 }
 
 /*
@@ -960,6 +946,11 @@
 	nss_nl_info_always("Exit NSS netlink IPV6 handler\n");
 
 	/*
+	 * Unregister the device callback handler for ipv6
+	 */
+	nss_ipv6_stats_unregister_notifier(&nss_ipv6_stats_notifier_nb);
+
+	/*
 	 * unregister the ops family
 	 */
 	error = genl_unregister_family(&nss_nlipv6_family);
@@ -968,11 +959,6 @@
 		return false;
 	}
 
-	/*
-	 * Unregister the device callback handler for ipv6
-	 */
-	nss_ipv6_notify_unregister();
-
 	gbl_ctx.nss = NULL;
 
 	return true;