Merge "IPACM: Fix IPv6 DL fragmented packet issue"
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index a956643..cb4440a 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -87,7 +87,7 @@
#define WWAN_QMI_IOCTL_DEVICE_NAME "/dev/wwan_ioctl"
#define IPA_DEVICE_NAME "/dev/ipa"
-#define IPA_MAX_FLT_RULE 36
+#define IPA_MAX_FLT_RULE 50
#define MAX_OFFLOAD_PAIR 3
#define MAX_NUM_PROP 8
@@ -161,8 +161,8 @@
IPA_LAN_DELETE_SELF, /* 36 ipacm_event_data_fid */
IPA_WLAN_LINK_DOWN_EVENT, /* 37 ipacm_event_data_mac */
IPA_USB_LINK_UP_EVENT, /* 38 ipacm_event_data_fid */
- IPA_PROCESS_CT_MESSAGE_V6, /* 39 ipacm_ct_evt_data */
- IPA_PRIVATE_SUBNET_CHANGE_EVENT, /* 40 ipacm_event_data_fid */
+ IPA_PROCESS_CT_MESSAGE_V6, /* 39 ipacm_ct_evt_data */
+ IPA_PRIVATE_SUBNET_CHANGE_EVENT, /* 40 ipacm_event_data_fid */
IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, /* 41 ipacm_event_data_fid */
IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, /* 42 ipacm_event_data_fid */
IPA_WAN_EMBMS_LINK_UP_EVENT, /* 43 ipacm_event_data_mac */
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index e3025b5..381f792 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -118,6 +118,8 @@
static bool embms_is_on;
private:
+
+ uint32_t ipv6_frag_firewall_flt_rule_hdl;
uint32_t *wan_route_rule_v4_hdl;
uint32_t *wan_route_rule_v6_hdl;
uint32_t *wan_route_rule_v6_hdl_a5;
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 150b24c..c758e41 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -1454,7 +1454,7 @@
int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
{
struct ipa_flt_rule_add flt_rule_entry;
- int i, rule_v4 = 0, rule_v6 = 0;
+ int i, rule_v4 = 0, rule_v6 = 0, len;
IPACMDBG_H("ip-family: %d; \n", iptype);
@@ -1500,22 +1500,52 @@
}
/* construct ipa_ioc_add_flt_rule with N firewall rules */
- ipa_ioc_add_flt_rule *m_pFilteringTable;
+ ipa_ioc_add_flt_rule *m_pFilteringTable = NULL;
+ len = sizeof(struct ipa_ioc_add_flt_rule) + 1 * sizeof(struct ipa_flt_rule_add);
+ m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
+ if (!m_pFilteringTable)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+
+ if(iptype == IPA_IP_v6 && firewall_config.firewall_enable == true)
+ {
+ m_pFilteringTable->commit = 1;
+ m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
+ m_pFilteringTable->global = false;
+ m_pFilteringTable->ip = IPA_IP_v6;
+ m_pFilteringTable->num_rules = (uint8_t)1;
+
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib));
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_FRAG_HDR;
+
+ memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+ if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+ {
+ IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
+ free(m_pFilteringTable);
+ return IPACM_FAILURE;
+ }
+ else
+ {
+ ipv6_frag_firewall_flt_rule_hdl = m_pFilteringTable->rules[0].flt_rule_hdl;
+ IPACMDBG_H("Installed IPv6 frag firewall rule, handle %d.\n", ipv6_frag_firewall_flt_rule_hdl);
+ }
+ }
if (iptype == IPA_IP_v4)
{
if (rule_v4 == 0)
{
- m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
- calloc(1,
- sizeof(struct ipa_ioc_add_flt_rule) +
- 1 * sizeof(struct ipa_flt_rule_add));
+ memset(m_pFilteringTable, 0, len);
- if (!m_pFilteringTable)
- {
- IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
- return IPACM_FAILURE;
- }
m_pFilteringTable->commit = 1;
m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
m_pFilteringTable->global = false;
@@ -1578,21 +1608,10 @@
/* copy filter hdls */
dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
- free(m_pFilteringTable);
}
else
{
- m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
- calloc(1,
- sizeof(struct ipa_ioc_add_flt_rule) +
- 1 * sizeof(struct ipa_flt_rule_add)
- );
-
- if (m_pFilteringTable == NULL)
- {
- IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
- return IPACM_FAILURE;
- }
+ memset(m_pFilteringTable, 0, len);
m_pFilteringTable->commit = 1;
m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
@@ -1771,7 +1790,6 @@
/* copy filter hdls */
dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
- free(m_pFilteringTable);
}
}
@@ -1779,17 +1797,8 @@
{
if (rule_v6 == 0)
{
- m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
- calloc(1,
- sizeof(struct ipa_ioc_add_flt_rule) +
- 1 * sizeof(struct ipa_flt_rule_add));
+ memset(m_pFilteringTable, 0, len);
-
- if (!m_pFilteringTable)
- {
- IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
- return IPACM_FAILURE;
- }
m_pFilteringTable->commit = 1;
m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
m_pFilteringTable->global = false;
@@ -1888,21 +1897,11 @@
/* copy filter hdls */
dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
- free(m_pFilteringTable);
}
else
{
- m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
- calloc(1,
- sizeof(struct ipa_ioc_add_flt_rule) +
- 1 * sizeof(struct ipa_flt_rule_add)
- );
+ memset(m_pFilteringTable, 0, len);
- if (!m_pFilteringTable)
- {
- IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
- return IPACM_FAILURE;
- }
m_pFilteringTable->commit = 1;
m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
m_pFilteringTable->global = false;
@@ -2093,9 +2092,13 @@
}
/* copy filter hdls*/
dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
- free(m_pFilteringTable);
}
}
+
+ if(m_pFilteringTable != NULL)
+ {
+ free(m_pFilteringTable);
+ }
return IPACM_SUCCESS;
}
@@ -2145,6 +2148,57 @@
return IPACM_FAILURE;
}
+ /* add IPv6 frag rule when firewall is enabled*/
+ if(iptype == IPA_IP_v6 && firewall_config.firewall_enable == true)
+ {
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+
+ flt_rule_entry.rule.retain_hdr = 1;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+
+ memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
+ rt_tbl_idx.ip = IPA_IP_v6;
+ strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
+ if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
+ {
+ IPACMERR("Failed to get routing table index from name\n");
+ return IPACM_FAILURE;
+ }
+ flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
+ IPACMDBG_H("IPv6 frag flt rule uses routing table index %d\n", rt_tbl_idx.idx);
+
+ flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask;
+ flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask;
+ flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data;
+
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_FRAG_HDR;
+
+ change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
+
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v6;
+ if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ return IPACM_FAILURE;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+
+ memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+ pos++;
+ IPACM_Wan::num_v6_flt_rule++;
+ }
+
if (iptype == IPA_IP_v4)
{
original_num_rules = IPACM_Wan::num_v4_flt_rule;
@@ -2350,7 +2404,7 @@
num_firewall_v4++;
IPACM_Wan::num_v4_flt_rule++;
- num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules;
+ num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules - 1;
}
else
{
@@ -2541,7 +2595,7 @@
num_firewall_v6++;
IPACM_Wan::num_v6_flt_rule++;
- num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules;
+ num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules - 1;
}
IPACMDBG_H("Constructed %d firewall rules for ip type %d\n", num_rules, iptype);
return IPACM_SUCCESS;
@@ -3237,6 +3291,10 @@
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
}
+ if (m_filtering.DeleteFilteringHdls(&ipv6_frag_firewall_flt_rule_hdl, IPA_IP_v6, 1) == false)
+ {
+ IPACMERR("Error deleting IPv6 frag filtering rules.\n");
+ }
num_firewall_v6 = 0;
}