IPACM: add TCP SYN filtering rules
Add TCP SYN filtering rules to route TCP SYN packets
to exception for L2TP use case.
Acked-by: Shihuan Liu <shihuanl@qti.qualcomm.com>
Change-Id: I00b5c94dee56940b4b79c5ed2f029c088d683416
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 280c830..cb63e34 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -238,6 +238,12 @@
/* handle tethering client */
int handle_tethering_client(bool reset, ipacm_client_enum ipa_client);
+ /* add tcp syn flt rule */
+ int add_tcp_syn_flt_rule(ipa_ip_type iptype);
+
+ /* add tcp syn flt rule for l2tp interface*/
+ int add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type);
+
/* store ipv4 UL filter rule handlers from Q6*/
uint32_t wan_ul_fl_rule_hdl_v4[MAX_WAN_UL_FILTER_RULES];
@@ -267,6 +273,8 @@
bool is_downstream_set[IPA_IP_MAX];
_ipacm_offload_prefix prefix[IPA_IP_MAX];
+ uint32_t tcp_syn_flt_rule_hdl[IPA_IP_MAX];
+
private:
/* get hdr proc ctx type given source and destination l2 hdr type */
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 7d0f10c..b39c678 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -1222,6 +1222,12 @@
/* initial multicast/broadcast/fragment filter rule */
init_fl_rule(data->iptype);
+#ifdef FEATURE_L2TP
+ if(ipa_if_cate == WLAN_IF)
+ {
+ add_tcp_syn_flt_rule(data->iptype);
+ }
+#endif
install_ipv4_icmp_flt_rule();
/* populate the flt rule offset for eth bridge */
@@ -1313,6 +1319,17 @@
if (num_dft_rt_v6 == 0)
{
+#ifdef FEATURE_L2TP
+ if(ipa_if_cate == WLAN_IF)
+ {
+ add_tcp_syn_flt_rule(data->iptype);
+ }
+ else if(ipa_if_cate == ODU_IF)
+ {
+ add_tcp_syn_flt_rule_l2tp(IPA_IP_v4);
+ add_tcp_syn_flt_rule_l2tp(IPA_IP_v6);
+ }
+#endif
install_ipv6_icmp_flt_rule();
/* populate the flt rule offset for eth bridge */
@@ -2851,6 +2868,17 @@
}
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
}
+#ifdef FEATURE_L2TP
+ if(ipa_if_cate == ODU_IF)
+ {
+ if(m_filtering.DeleteFilteringHdls(tcp_syn_flt_rule_hdl, IPA_IP_v6, IPA_IP_MAX) == false)
+ {
+ IPACMERR("Error Deleting TCP SYN L2TP Filtering Rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+#endif
}
IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
@@ -5461,3 +5489,127 @@
}
return false;
}
+
+/* add tcp syn flt rule */
+int IPACM_Lan::add_tcp_syn_flt_rule(ipa_ip_type iptype)
+{
+ int len;
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_add_flt_rule *m_pFilteringTable;
+
+ if(rx_prop == NULL)
+ {
+ IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
+ return IPACM_SUCCESS;
+ }
+
+ len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
+ m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
+ if(!m_pFilteringTable)
+ {
+ PERROR("Not enough memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(m_pFilteringTable, 0, len);
+
+ m_pFilteringTable->commit = 1;
+ m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
+ m_pFilteringTable->global = false;
+ m_pFilteringTable->ip = iptype;
+ m_pFilteringTable->num_rules = 1;
+
+ memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.rule.retain_hdr = 1;
+ 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(flt_rule_entry.rule.attrib));
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_TCP_SYN;
+ if(iptype == IPA_IP_v4)
+ {
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
+ flt_rule_entry.rule.attrib.u.v4.protocol = 6;
+ }
+ else
+ {
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ flt_rule_entry.rule.attrib.u.v6.next_hdr = 6;
+ }
+
+ memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
+
+ if(false == m_filtering.AddFilteringRule(m_pFilteringTable))
+ {
+ IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
+ free(m_pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ tcp_syn_flt_rule_hdl[iptype] = m_pFilteringTable->rules[0].flt_rule_hdl;
+ free(m_pFilteringTable);
+ return IPACM_SUCCESS;
+}
+
+/* add tcp syn flt rule for l2tp interface*/
+int IPACM_Lan::add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type)
+{
+ int len;
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_add_flt_rule *m_pFilteringTable;
+
+ if(rx_prop == NULL)
+ {
+ IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
+ return IPACM_SUCCESS;
+ }
+
+ len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
+ m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
+ if(!m_pFilteringTable)
+ {
+ PERROR("Not enough memory.\n");
+ return IPACM_FAILURE;
+ }
+ memset(m_pFilteringTable, 0, len);
+
+ 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 = 1;
+
+ memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.rule.retain_hdr = 1;
+ 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(flt_rule_entry.rule.attrib));
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_TCP_SYN_L2TP;
+ if(inner_ip_type == IPA_IP_v4)
+ {
+ flt_rule_entry.rule.attrib.ether_type = 0x0800;
+ }
+ else
+ {
+ flt_rule_entry.rule.attrib.ether_type = 0x86dd;
+ }
+
+ memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
+
+ if(false == m_filtering.AddFilteringRule(m_pFilteringTable))
+ {
+ IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
+ free(m_pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ tcp_syn_flt_rule_hdl[inner_ip_type] = m_pFilteringTable->rules[0].flt_rule_hdl;
+ free(m_pFilteringTable);
+ return IPACM_SUCCESS;
+}
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 03b5925..ff8fcee 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -1766,6 +1766,15 @@
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_private_subnet_fl_rule);
#endif
IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
+
+#ifdef FEATURE_L2TP
+ if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v4], IPA_IP_v4, 1) == false)
+ {
+ IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+#endif
}
/* Delete v6 filtering rules */
@@ -1791,6 +1800,14 @@
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
IPACMDBG_H("Deleted default v6 filter rules successfully.\n");
}
+#ifdef FEATURE_L2TP
+ if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v6], IPA_IP_v6, 1) == false)
+ {
+ IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+#endif
}
IPACMDBG_H("finished delete filtering rules\n ");