summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSkylar Chang <chiaweic@codeaurora.org>2015-09-29 17:30:12 -0700
committerSkylar Chang <chiaweic@codeaurora.org>2015-09-29 17:35:40 -0700
commit06de5f1ff678fff654441eee0f7a4991b591336c (patch)
tree1776d70c7ed2d84c15448f5ac4c4d51b63b9f3dd
parentaec4d3a28128534078da7cb2cbcc6ba85c0cd7f0 (diff)
downloadipacfg-mgr-06de5f1ff678fff654441eee0f7a4991b591336c.tar.gz
IPACM: Fix the ipv6-only AP+STA use-case
For ipv6-only AP+STA, SoftAP won't posting v6 default route event to IPACM because of its new feature called priority backhaul. Therefore IPACM needs to listen for RTPROT_RA netlink event instead to find the externel AP's mac and construct the full wlan header. Change-Id: I8fb0135f473e31bb87b46f4a437292dc7931f722 Acked-by: Skylar Chang <chiaweic@codeaurora.org>
-rw-r--r--ipacm/inc/IPACM_Defs.h1
-rw-r--r--ipacm/inc/IPACM_Wan.h45
-rw-r--r--ipacm/src/IPACM_Netlink.cpp27
-rw-r--r--ipacm/src/IPACM_Wan.cpp58
4 files changed, 123 insertions, 8 deletions
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index b424d97..421f400 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -305,6 +305,7 @@ typedef struct _ipacm_event_data_addr
uint32_t ipv4_addr_mask;
uint32_t ipv6_addr[4];
uint32_t ipv6_addr_mask[4];
+ uint32_t ipv6_addr_gw[4];
} ipacm_event_data_addr;
typedef struct _ipacm_event_data_mac
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 159cc46..dcb8719 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -155,8 +155,10 @@ private:
int num_firewall_v4,num_firewall_v6;
uint32_t wan_v4_addr;
uint32_t wan_v4_addr_gw;
+ uint32_t wan_v6_addr_gw[4];
bool wan_v4_addr_set;
bool wan_v4_addr_gw_set;
+ bool wan_v6_addr_gw_set;
bool active_v4;
bool active_v6;
bool header_set_v4;
@@ -261,6 +263,49 @@ private:
return IPACM_INVALID_INDEX;
}
+ inline int get_wan_client_index_ipv6(uint32_t* ipv6_addr)
+ {
+ int cnt, v6_num;
+ int num_wan_client_tmp = num_wan_client;
+
+ IPACMDBG_H("Get ipv6 address 0x%08x.0x%08x.0x%08x.0x%08x\n", ipv6_addr[0], ipv6_addr[1], ipv6_addr[2], ipv6_addr[3]);
+
+ for(cnt = 0; cnt < num_wan_client_tmp; cnt++)
+ {
+ if (get_client_memptr(wan_client, cnt)->ipv6_set)
+ {
+ for(v6_num=0;v6_num < get_client_memptr(wan_client, cnt)->ipv6_set;v6_num++)
+ {
+
+ IPACMDBG_H("stored IPv6 0x%08x.0x%08x.0x%08x.0x%08x\n", get_client_memptr(wan_client, cnt)->v6_addr[v6_num][0],
+ get_client_memptr(wan_client, cnt)->v6_addr[v6_num][1],
+ get_client_memptr(wan_client, cnt)->v6_addr[v6_num][2],
+ get_client_memptr(wan_client, cnt)->v6_addr[v6_num][3]);
+
+ if(ipv6_addr[0] == get_client_memptr(wan_client, cnt)->v6_addr[v6_num][0] &&
+ ipv6_addr[1] == get_client_memptr(wan_client, cnt)->v6_addr[v6_num][1] &&
+ ipv6_addr[2]== get_client_memptr(wan_client, cnt)->v6_addr[v6_num][2] &&
+ ipv6_addr[3] == get_client_memptr(wan_client, cnt)->v6_addr[v6_num][3])
+ {
+ IPACMDBG_H("Matched client index: %d\n", cnt);
+ IPACMDBG_H("The MAC is %02x:%02x:%02x:%02x:%02x:%02x\n",
+ get_client_memptr(wan_client, cnt)->mac[0],
+ get_client_memptr(wan_client, cnt)->mac[1],
+ get_client_memptr(wan_client, cnt)->mac[2],
+ get_client_memptr(wan_client, cnt)->mac[3],
+ get_client_memptr(wan_client, cnt)->mac[4],
+ get_client_memptr(wan_client, cnt)->mac[5]);
+ IPACMDBG_H("header set ipv4(%d) ipv6(%d)\n",
+ get_client_memptr(wan_client, cnt)->ipv4_header_set,
+ get_client_memptr(wan_client, cnt)->ipv6_header_set);
+ return cnt;
+ }
+ }
+ }
+ }
+ return IPACM_INVALID_INDEX;
+ }
+
inline int delete_wan_rtrules(int clt_indx, ipa_ip_type iptype)
{
uint32_t tx_index;
diff --git a/ipacm/src/IPACM_Netlink.cpp b/ipacm/src/IPACM_Netlink.cpp
index 3dfc514..a343e24 100644
--- a/ipacm/src/IPACM_Netlink.cpp
+++ b/ipacm/src/IPACM_Netlink.cpp
@@ -879,7 +879,6 @@ static int ipa_nl_decode_nlmsg
IPACMDBG("In case RTM_NEWROUTE\n");
IPACMDBG("rtm_type: %d\n", msg_ptr->nl_route_info.metainfo.rtm_type);
- IPACMDBG("rtm_type: %d\n", msg_ptr->nl_route_info.metainfo.rtm_type);
IPACMDBG("protocol: %d\n", msg_ptr->nl_route_info.metainfo.rtm_protocol);
IPACMDBG("rtm_scope: %d\n", msg_ptr->nl_route_info.metainfo.rtm_scope);
IPACMDBG("rtm_table: %d\n", msg_ptr->nl_route_info.metainfo.rtm_table);
@@ -888,7 +887,8 @@ static int ipa_nl_decode_nlmsg
/* take care of route add default route & uniroute */
if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
- (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) &&
+ ((msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) ||
+ (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_RA)) &&
(msg_ptr->nl_route_info.metainfo.rtm_scope == RT_SCOPE_UNIVERSE) &&
(msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
{
@@ -967,13 +967,20 @@ static int ipa_nl_decode_nlmsg
data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
- IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
+ IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
+ IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
+ data_addr->ipv6_addr_gw[0] = ntohl(data_addr->ipv6_addr_gw[0]);
+ data_addr->ipv6_addr_gw[1] = ntohl(data_addr->ipv6_addr_gw[1]);
+ data_addr->ipv6_addr_gw[2] = ntohl(data_addr->ipv6_addr_gw[2]);
+ data_addr->ipv6_addr_gw[3] = ntohl(data_addr->ipv6_addr_gw[3]);
+ IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_route_info.attr_info.gateway_addr);
+
evt_data.event = IPA_ROUTE_ADD_EVENT;
data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
data_addr->iptype = IPA_IP_v6;
@@ -1146,7 +1153,8 @@ static int ipa_nl_decode_nlmsg
}
/* take care of route delete of default route & uniroute */
if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
- (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) &&
+ ((msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) ||
+ (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_RA)) &&
(msg_ptr->nl_route_info.metainfo.rtm_scope == 0) &&
(msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
{
@@ -1217,19 +1225,24 @@ static int ipa_nl_decode_nlmsg
{
IPACMDBG("ip -6 route del default dev %s\n", dev_name);
}
- IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
-
+ IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
-
data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
+
+ IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
+ data_addr->ipv6_addr_gw[0] = ntohl(data_addr->ipv6_addr_gw[0]);
+ data_addr->ipv6_addr_gw[1] = ntohl(data_addr->ipv6_addr_gw[1]);
+ data_addr->ipv6_addr_gw[2] = ntohl(data_addr->ipv6_addr_gw[2]);
+ data_addr->ipv6_addr_gw[3] = ntohl(data_addr->ipv6_addr_gw[3]);
+ IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_route_info.attr_info.gateway_addr);
data_addr->iptype = IPA_IP_v6;
}
else
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 6381826..f9c1fb6 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -96,6 +96,7 @@ IPACM_Wan::IPACM_Wan(int iface_index,
wan_v4_addr_set = false;
wan_v4_addr_gw_set = false;
+ wan_v6_addr_gw_set = false;
active_v4 = false;
active_v6 = false;
header_set_v4 = false;
@@ -107,6 +108,7 @@ IPACM_Wan::IPACM_Wan(int iface_index,
num_ipv6_dest_flt_rule = 0;
memset(ipv6_dest_flt_rule_hdl, 0, MAX_DEFAULT_v6_ROUTE_RULES*sizeof(uint32_t));
memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
+ memset(wan_v6_addr_gw, 0, sizeof(wan_v6_addr_gw));
ext_prop = NULL;
num_wan_client = 0;
@@ -832,8 +834,17 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
(active_v6 == false) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX))
{
IPACMDBG_H("\n get default v6 route (dst:00.00.00.00)\n");
- IPACMDBG_H(" IPV6 value: %08x:%08x:%08x:%08x \n",
+ IPACMDBG_H(" IPV6 dst: %08x:%08x:%08x:%08x \n",
data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]);
+ IPACMDBG_H(" IPV6 gateway: %08x:%08x:%08x:%08x \n",
+ data->ipv6_addr_gw[0], data->ipv6_addr_gw[1], data->ipv6_addr_gw[2], data->ipv6_addr_gw[3]);
+ wan_v6_addr_gw[0] = data->ipv6_addr_gw[0];
+ wan_v6_addr_gw[1] = data->ipv6_addr_gw[1];
+ wan_v6_addr_gw[2] = data->ipv6_addr_gw[2];
+ wan_v6_addr_gw[3] = data->ipv6_addr_gw[3];
+ wan_v6_addr_gw_set = true;
+ /* Check & construct STA header */
+ handle_sta_header_add_evt();
handle_route_add_evt(data->iptype);
}
}
@@ -1557,6 +1568,51 @@ int IPACM_Wan::handle_sta_header_add_evt()
}
}
+ /* checking if the ipv4 same as default route */
+ if(wan_v6_addr_gw_set)
+ {
+ index = get_wan_client_index_ipv6(wan_v6_addr_gw);
+ if (index != IPACM_INVALID_INDEX)
+ {
+ IPACMDBG_H("Matched client index: %d\n", index);
+ IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ get_client_memptr(wan_client, index)->mac[0],
+ get_client_memptr(wan_client, index)->mac[1],
+ get_client_memptr(wan_client, index)->mac[2],
+ get_client_memptr(wan_client, index)->mac[3],
+ get_client_memptr(wan_client, index)->mac[4],
+ get_client_memptr(wan_client, index)->mac[5]);
+ if(get_client_memptr(wan_client, index)->ipv6_header_set)
+ {
+ hdr_hdl_sta_v6 = get_client_memptr(wan_client, index)->hdr_hdl_v6;
+ header_set_v6 = true;
+ IPACMDBG_H("add full ipv6 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v6);
+ }
+ else
+ {
+ IPACMERR(" wan-client got ipv6 however didn't construct complete ipv4 header \n");
+ return IPACM_FAILURE;
+ }
+
+ if(get_client_memptr(wan_client, index)->ipv4_header_set)
+ {
+ hdr_hdl_sta_v4 = get_client_memptr(wan_client, index)->hdr_hdl_v4;
+ header_set_v4 = true;
+ IPACMDBG_H("add full ipv4 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v4);
+ }
+ else
+ {
+ IPACMERR(" wan-client got ipv4 however didn't construct complete ipv4 header \n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMDBG_H(" currently can't find matched wan-client's MAC-addr, waiting for header construction\n");
+ return IPACM_SUCCESS;
+ }
+ }
+
/* see if default routes are setup before constructing full header */
if(header_partial_default_wan_v4 == true)
{