Add reference count to registered mac address of station

Cherry-pick of aosp/2057192

When using mac randomization at Cloud Android, registered address
can be unintentionally removed when such control packet series are
received.

HWSIM_CMD_ADD_MAC_ADDR 02:15:b2:00:00:00, aa:bb:cc:dd:ee:ff
HWSIM_CMD_ADD_MAC_ADDR 02:15:b2:00:00:00, aa:bb:cc:dd:ee:ff
HWSIM_CMD_DEL_MAC_ADDR 02:15:b2:00:00:00, aa:bb:cc:dd:ee:ff

This can occur when scanning Wi-Fi APs at Cloud Android VM.

Add reference count at registered address to track addition and
deletion of mac address.

Test: lunch aosp_cf_x86_64_phone-userdebug && m && launch_cvd
      atest CtsOsTestCases
      Check android.os.cts.StrictModeTest#testEncryptedNetwork
      and android.os.cts.StrictModeTest#testNetwork passes
Bug: 223101490
Bug: 235182238
Change-Id: I61d6c5a7147d3e645edf54e15b6cabc85a51d10f
diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c
index 6b3ae5d..860c214 100644
--- a/wmediumd/wmediumd.c
+++ b/wmediumd/wmediumd.c
@@ -902,7 +902,7 @@
 	struct frame *frame;
 	struct ieee80211_hdr *hdr;
 	u8 *src, *hwaddr, *addr;
-	void *new;
+	void *new_addrs;
 	unsigned int i;
 
 	genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_MAX, NULL);
@@ -976,13 +976,16 @@
 		if (!sender)
 			break;
 		for (i = 0; i < sender->n_addrs; i++) {
-			if (memcmp(sender->addrs[i].addr, addr, ETH_ALEN) == 0)
+			if (memcmp(sender->addrs[i].addr, addr, ETH_ALEN) == 0) {
+				sender->addrs[i].count += 1;
 				return;
+			}
 		}
-		new = realloc(sender->addrs, ETH_ALEN * (sender->n_addrs + 1));
-		if (!new)
+		new_addrs = realloc(sender->addrs, sizeof(struct addr) * (sender->n_addrs + 1));
+		if (!new_addrs)
 			break;
-		sender->addrs = new;
+		sender->addrs = new_addrs;
+		sender->addrs[sender->n_addrs].count = 1;
 		memcpy(sender->addrs[sender->n_addrs].addr, addr, ETH_ALEN);
 		sender->n_addrs += 1;
 		break;
@@ -998,10 +1001,13 @@
 		for (i = 0; i < sender->n_addrs; i++) {
 			if (memcmp(sender->addrs[i].addr, addr, ETH_ALEN))
 				continue;
-			sender->n_addrs -= 1;
-			memmove(sender->addrs[i].addr,
-				sender->addrs[sender->n_addrs].addr,
-				ETH_ALEN);
+			sender->addrs[i].count -= 1;
+			if (sender->addrs[i].count <= 0) {
+				sender->n_addrs -= 1;
+				memmove(&sender->addrs[i],
+					&sender->addrs[sender->n_addrs],
+					sizeof(struct addr));
+			}
 			break;
 		}
 		break;
diff --git a/wmediumd/wmediumd.h b/wmediumd/wmediumd.h
index 3c9818d..f8bc395 100644
--- a/wmediumd/wmediumd.h
+++ b/wmediumd/wmediumd.h
@@ -147,6 +147,7 @@
 
 struct addr {
 	u8 addr[ETH_ALEN];
+	uint16_t count;
 };
 
 struct station {