diff options
author | Skylar Chang <chiaweic@codeaurora.org> | 2015-09-29 17:30:12 -0700 |
---|---|---|
committer | Skylar Chang <chiaweic@codeaurora.org> | 2015-09-29 17:35:40 -0700 |
commit | 06de5f1ff678fff654441eee0f7a4991b591336c (patch) | |
tree | 1776d70c7ed2d84c15448f5ac4c4d51b63b9f3dd | |
parent | aec4d3a28128534078da7cb2cbcc6ba85c0cd7f0 (diff) | |
download | ipacfg-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.h | 1 | ||||
-rw-r--r-- | ipacm/inc/IPACM_Wan.h | 45 | ||||
-rw-r--r-- | ipacm/src/IPACM_Netlink.cpp | 27 | ||||
-rw-r--r-- | ipacm/src/IPACM_Wan.cpp | 58 |
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) { |