summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShihuan Liu <chiaweic@codeaurora.org>2017-08-04 11:00:00 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-12-19 11:34:42 -0800
commit4c902280da076ad7e88923875b39423226e76e44 (patch)
treec4d7fb2663dd727d51f4471536da1101242620d3
parentf05aab07b714d98cf39abb4fd9b89b3ee178dbcb (diff)
msm: ipa: add new IP filtering bitmaps
Add new IP filtering bitmaps to match TCP SYN packets. Change-Id: I73ab2944c3d351fdb57f147d3efedd1b5829835e Acked-by: Pooja Kumari <kumarip@qti.qualcomm.com> Signed-off-by: Mohammed Javid <mjavid@codeaurora.org> Acked-by: Shihuan Liu <shihuanl@qti.qualcomm.com> Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c6
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c187
-rw-r--r--include/uapi/linux/msm_ipa.h2
3 files changed, 195 insertions, 0 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index 71da7d28a451..cd39a46037f1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -505,6 +505,12 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib,
if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE)
pr_err("ether_type:%x ", attrib->ether_type);
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN)
+ pr_err("tcp syn ");
+
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP)
+ pr_err("tcp syn l2tp ");
+
pr_err("\n");
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
index b7ed529e9160..b5916cd1fbf6 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
@@ -664,6 +664,21 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule,
ihl_ofst_meq32++;
}
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
+ ihl_ofst_meq32)) {
+ IPAHAL_ERR("ran out of ihl_meq32 eq\n");
+ goto err;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
+ /* 12 => offset of SYN after v4 header */
+ extra = ipa_write_8(12, extra);
+ rest = ipa_write_32(0x20000, rest);
+ rest = ipa_write_32(0x20000, rest);
+ ihl_ofst_meq32++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_META_DATA) {
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_METADATA_COMPARE);
rest = ipa_write_32(attrib->meta_data_mask, rest);
@@ -970,6 +985,57 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip6(u16 *en_rule,
ihl_ofst_meq32++;
}
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
+ ihl_ofst_meq32)) {
+ IPAHAL_ERR("ran out of ihl_meq32 eq\n");
+ goto err;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
+ /* 12 => offset of SYN after v4 header */
+ extra = ipa_write_8(12, extra);
+ rest = ipa_write_32(0x20000, rest);
+ rest = ipa_write_32(0x20000, rest);
+ ihl_ofst_meq32++;
+ }
+
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
+ ihl_ofst_meq32) || IPA_IS_RAN_OUT_OF_EQ(
+ ipa3_0_ihl_ofst_meq32, ihl_ofst_meq32 + 1)) {
+ IPAHAL_ERR("ran out of ihl_meq32 eq\n");
+ goto err;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32 + 1]);
+
+ /* populate TCP protocol eq */
+ if (attrib->ether_type == 0x0800) {
+ extra = ipa_write_8(30, extra);
+ rest = ipa_write_32(0xFF0000, rest);
+ rest = ipa_write_32(0x60000, rest);
+ } else {
+ extra = ipa_write_8(26, extra);
+ rest = ipa_write_32(0xFF00, rest);
+ rest = ipa_write_32(0x600, rest);
+ }
+
+ /* populate TCP SYN eq */
+ if (attrib->ether_type == 0x0800) {
+ extra = ipa_write_8(54, extra);
+ rest = ipa_write_32(0x20000, rest);
+ rest = ipa_write_32(0x20000, rest);
+ } else {
+ extra = ipa_write_8(74, extra);
+ rest = ipa_write_32(0x20000, rest);
+ rest = ipa_write_32(0x20000, rest);
+ }
+ ihl_ofst_meq32 += 2;
+ }
+
if (attrib->attrib_mask & IPA_FLT_META_DATA) {
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_METADATA_COMPARE);
rest = ipa_write_32(attrib->meta_data_mask, rest);
@@ -1044,6 +1110,27 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip6(u16 *en_rule,
ihl_ofst_rng16++;
}
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_rng16,
+ ihl_ofst_rng16)) {
+ IPAHAL_ERR("ran out of ihl_rng16 eq\n");
+ goto err;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_rng16[ihl_ofst_rng16]);
+ /* 20 => offset of Ethertype after v4 header */
+ if (attrib->ether_type == 0x0800) {
+ extra = ipa_write_8(21, extra);
+ rest = ipa_write_16(0x0045, rest);
+ rest = ipa_write_16(0x0045, rest);
+ } else {
+ extra = ipa_write_8(20, extra);
+ rest = ipa_write_16(attrib->ether_type, rest);
+ rest = ipa_write_16(attrib->ether_type, rest);
+ }
+ ihl_ofst_rng16++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_FLOW_LABEL) {
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_FL_EQ);
rest = ipa_write_32(attrib->u.v6.flow_label & 0xFFFFF,
@@ -1480,6 +1567,21 @@ static int ipa_flt_generate_eq_ip4(enum ipa_ip_type ip,
ofst_meq128++;
}
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
+ ihl_ofst_meq32)) {
+ IPAHAL_ERR("ran out of ihl_meq32 eq\n");
+ return -EPERM;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
+ /* 12 => offset of SYN after v4 header */
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].offset = 12;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].mask = 0x20000;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].value = 0x20000;
+ ihl_ofst_meq32++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_TOS_MASKED) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
IPAHAL_ERR("ran out of meq32 eq\n");
@@ -1843,6 +1945,65 @@ static int ipa_flt_generate_eq_ip6(enum ipa_ip_type ip,
ofst_meq128++;
}
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
+ ihl_ofst_meq32)) {
+ IPAHAL_ERR("ran out of ihl_meq32 eq\n");
+ return -EPERM;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
+ /* 12 => offset of SYN after v4 header */
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].offset = 12;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].mask = 0x20000;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].value = 0x20000;
+ ihl_ofst_meq32++;
+ }
+
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
+ ihl_ofst_meq32) || IPA_IS_RAN_OUT_OF_EQ(
+ ipa3_0_ihl_ofst_meq32, ihl_ofst_meq32 + 1)) {
+ IPAHAL_ERR("ran out of ihl_meq32 eq\n");
+ return -EPERM;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32 + 1]);
+
+ /* populate TCP protocol eq */
+ if (attrib->ether_type == 0x0800) {
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].offset = 30;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].mask =
+ 0xFF0000;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].value =
+ 0x60000;
+ } else {
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].offset = 26;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].mask =
+ 0xFF00;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].value =
+ 0x600;
+ }
+
+ /* populate TCP SYN eq */
+ if (attrib->ether_type == 0x0800) {
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].offset = 54;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].mask =
+ 0x20000;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].value =
+ 0x20000;
+ } else {
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].offset = 74;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].mask =
+ 0x20000;
+ eq_atrb->ihl_offset_meq_32[ihl_ofst_meq32].value =
+ 0x20000;
+ }
+ ihl_ofst_meq32 += 2;
+ }
+
if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
IPAHAL_ERR("ran out of meq32 eq\n");
@@ -1985,6 +2146,32 @@ static int ipa_flt_generate_eq_ip6(enum ipa_ip_type ip,
ihl_ofst_rng16++;
}
+ if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP) {
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_rng16,
+ ihl_ofst_rng16)) {
+ IPAHAL_ERR("ran out of ihl_rng16 eq\n");
+ return -EPERM;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ihl_ofst_rng16[ihl_ofst_rng16]);
+ if (attrib->ether_type == 0x0800) {
+ eq_atrb->ihl_offset_range_16[ihl_ofst_rng16].offset
+ = 21;
+ eq_atrb->ihl_offset_range_16[ihl_ofst_rng16].range_low
+ = 0x0045;
+ eq_atrb->ihl_offset_range_16[ihl_ofst_rng16].range_high
+ = 0x0045;
+ } else {
+ eq_atrb->ihl_offset_range_16[ihl_ofst_rng16].offset =
+ 20;
+ eq_atrb->ihl_offset_range_16[ihl_ofst_rng16].range_low
+ = attrib->ether_type;
+ eq_atrb->ihl_offset_range_16[ihl_ofst_rng16].range_high
+ = attrib->ether_type;
+ }
+ ihl_ofst_rng16++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_FLOW_LABEL) {
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_FL_EQ);
eq_atrb->fl_eq_present = 1;
diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h
index 0bdfc9741d19..3d330990676c 100644
--- a/include/uapi/linux/msm_ipa.h
+++ b/include/uapi/linux/msm_ipa.h
@@ -163,6 +163,8 @@
#define IPA_FLT_MAC_SRC_ADDR_802_3 (1ul << 19)
#define IPA_FLT_MAC_DST_ADDR_802_3 (1ul << 20)
#define IPA_FLT_MAC_ETHER_TYPE (1ul << 21)
+#define IPA_FLT_TCP_SYN (1ul << 23)
+#define IPA_FLT_TCP_SYN_L2TP (1ul << 24)
/**
* maximal number of NAT PDNs in the PDN config table