Merge "IPACM: Fix conntrack event comes earlier than new neighbor"
diff --git a/ipacm/inc/IPACM_Neighbor.h b/ipacm/inc/IPACM_Neighbor.h
index d37ae5b..55ab92e 100644
--- a/ipacm/inc/IPACM_Neighbor.h
+++ b/ipacm/inc/IPACM_Neighbor.h
@@ -54,6 +54,8 @@
{
uint8_t mac_addr[6];
int iface_index;
+ uint32_t v4_addr;
+ int ipa_if_num;
};
class IPACM_Neighbor : public IPACM_Listener
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index e096eed..8871303 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -188,26 +188,33 @@
while (1)
{
length = read(inotify_fd, buffer, INOTIFY_BUF_LEN);
- struct inotify_event event;
- memcpy(&event, buffer,sizeof(struct inotify_event));
-
if (length < 0)
{
- IPACMERR("inotify read() error return length: %d and mask: 0x%x 0x%x\n", length, event.mask, mask);
+ IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask);
return NULL;
}
- if (event.len > 0)
+ struct inotify_event* event;
+ event = (struct inotify_event*)malloc(length);
+ if(event == NULL)
{
- if ( (event.mask & IN_MODIFY) || (event.mask & IN_MOVE))
+ IPACMERR("Failed to allocate memory.\n");
+ return;
+ }
+ memset(event, 0, length);
+ memcpy(event, buffer, length);
+
+ if (event->len > 0)
+ {
+ if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE))
{
- if (event.mask & IN_ISDIR)
+ if (event->mask & IN_ISDIR)
{
- IPACMDBG("The directory %s was 0x%x\n", event.name, event.mask);
+ IPACMDBG("The directory %s was 0x%x\n", event->name, event->mask);
}
- else if (!strncmp(event.name, IPACM_FIREWALL_FILE_NAME, event.len)) // firewall_rule change
+ else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change
{
- IPACMDBG("File \"%s\" was 0x%x\n", event.name, event.mask);
+ IPACMDBG("File \"%s\" was 0x%x\n", event->name, event->mask);
IPACMDBG("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME);
evt_data.event = IPA_FIREWALL_CHANGE_EVENT;
@@ -216,9 +223,9 @@
/* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
- else if (!strncmp(event.name, IPACM_CFG_FILE_NAME, event.len)) // IPACM_configuration change
+ else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change
{
- IPACMDBG("File \"%s\" was 0x%x\n", event.name, event.mask);
+ IPACMDBG("File \"%s\" was 0x%x\n", event->name, event->mask);
IPACMDBG("The interested file %s .\n", IPACM_CFG_FILE_NAME);
evt_data.event = IPA_CFG_CHANGE_EVENT;
@@ -228,8 +235,9 @@
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
}
- IPACMDBG("Received monitoring event %s.\n", event.name);
+ IPACMDBG("Received monitoring event %s.\n", event->name);
}
+ free(event);
}
(void)inotify_rm_watch(inotify_fd, wd);
diff --git a/ipacm/src/IPACM_Neighbor.cpp b/ipacm/src/IPACM_Neighbor.cpp
index 8d9bdaa..beea12b 100644
--- a/ipacm/src/IPACM_Neighbor.cpp
+++ b/ipacm/src/IPACM_Neighbor.cpp
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (c) 2013, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,7 @@
IPACMDBG("Recieved event %d\n", event);
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
-
+
if (data->iptype == IPA_IP_v4)
{
if (data->ipv4_addr != 0) /* not 0.0.0.0 */
@@ -79,12 +79,13 @@
if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
{
data->if_index = neighbor_client[i].iface_index;
+ neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
- if (event == IPA_NEW_NEIGH_EVENT)
+ if (event == IPA_NEW_NEIGH_EVENT)
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
- else
+ else
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
-
+
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
if (data_all == NULL)
{
@@ -94,7 +95,7 @@
memcpy(data_all, data, sizeof(ipacm_event_data_all));
evt_data.evt_data = (void *)data_all;
IPACM_EvtDispatcher::PostEvt(&evt_data);
-
+
/* ask for replaced iface name*/
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
IPACMDBG("Posted event %d, with %s for ipv4\n",
@@ -109,9 +110,9 @@
else
{
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
- if (event == IPA_NEW_NEIGH_EVENT)
+ if (event == IPA_NEW_NEIGH_EVENT)
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
- else
+ else
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
@@ -127,11 +128,11 @@
evt_data.event,
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
}
- }
+ }
}
else
{ //ipv6 starts
-
+
if ((data->ipv6_addr[0]) || (data->ipv6_addr[1]) || (data->ipv6_addr[2]) || (data->ipv6_addr[3]))
{
IPACMDBG(" Got New_Neighbor event with ipv6 address \n");
@@ -147,7 +148,6 @@
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
-
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
if (data_all == NULL)
{
@@ -157,7 +157,6 @@
memcpy(data_all, data, sizeof(ipacm_event_data_all));
evt_data.evt_data = (void *)data_all;
IPACM_EvtDispatcher::PostEvt(&evt_data);
-
/* ask for replaced iface name*/
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
IPACMDBG("Posted event %d, with %s for ipv6\n",
@@ -172,9 +171,9 @@
else
{
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
- if (event == IPA_NEW_NEIGH_EVENT)
+ if (event == IPA_NEW_NEIGH_EVENT)
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
- else
+ else
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
@@ -203,8 +202,45 @@
/* check if iface is not bridge interface*/
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
{
- neighbor_client[i].iface_index = data->if_index;
+
+ /* use previous ipv4 first */
+ if(data->if_index != neighbor_client[i].iface_index)
+ {
+ IPACMERR("update new kernel iface index \n");
+ neighbor_client[i].iface_index = data->if_index;
}
+
+ /* check if client associated with previous network interface */
+ if(ipa_interface_index != neighbor_client[i].ipa_if_num)
+ {
+ IPACMERR("client associate to different AP \n");
+ return;
+ }
+
+ if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
+ {
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
+ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
+ if (data_all == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return;
+ }
+ data_all->iptype = IPA_IP_v4;
+ data_all->if_index = neighbor_client[i].iface_index;
+ data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
+ memcpy(data_all->mac_addr,
+ neighbor_client[i].mac_addr,
+ sizeof(data_all->mac_addr));
+ evt_data.evt_data = (void *)data_all;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ /* ask for replaced iface name*/
+ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
+ IPACMDBG("Posted event %d, with %s for ipv4 client re-connect\n",
+ evt_data.event,
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
+ }
+ }
break;
}
}
@@ -214,13 +250,16 @@
/* check if iface is not bridge interface*/
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
{
-
+
if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
{
memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
data->mac_addr,
sizeof(data->mac_addr));
neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
+ /* cache the network interface client associated */
+ neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
+ neighbor_client[num_neighbor_client_temp].v4_addr = 0;
IPACMDBG("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
neighbor_client[num_neighbor_client_temp].mac_addr[0],
neighbor_client[num_neighbor_client_temp].mac_addr[1],
@@ -238,7 +277,7 @@
return;
}
}
-
+
}
}
} //ipv6 ends
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 8671fe7..3ec5fab 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -3443,14 +3443,7 @@
return;
}
- if(iptype == IPA_IP_v4)
- {
- attrib->u.v4.src_addr = htonl(attrib->u.v4.src_addr);
- attrib->u.v4.src_addr_mask = htonl(attrib->u.v4.src_addr_mask);
- attrib->u.v4.dst_addr = htonl(attrib->u.v4.dst_addr);
- attrib->u.v4.dst_addr_mask = htonl(attrib->u.v4.dst_addr_mask);
- }
- else if(iptype == IPA_IP_v6)
+ if(iptype == IPA_IP_v6)
{
int i;
for(i=0; i<4; i++)
@@ -3463,7 +3456,7 @@
}
else
{
- IPACMERR("IP type is not expected: %d\n", iptype);
+ IPACMDBG("IP type is not IPv6, do nothing: %d\n", iptype);
}
return;