Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bf0c60e authored by Shihuan Liu's avatar Shihuan Liu Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: add new IP filtering bitmaps



Add new IP filtering bitmaps to match TCP SYN packets.

Change-Id: I73ab2944c3d351fdb57f147d3efedd1b5829835e
Acked-by: default avatarShihuan Liu <shihuanl@qti.qualcomm.com>
Signed-off-by: default avatarSkylar Chang <chiaweic@codeaurora.org>
parent f035a4ad
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -536,6 +536,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;
}
+187 −0
Original line number Diff line number Diff line
@@ -826,6 +826,21 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule,
		ihl_ofst_meq32 += 2;
	}

	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);
@@ -1164,6 +1179,57 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip6(u16 *en_rule,
		ihl_ofst_meq32 += 2;
	}

	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);
@@ -1238,6 +1304,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,
@@ -1706,6 +1793,21 @@ static int ipa_flt_generate_eq_ip4(enum ipa_ip_type ip,
		ihl_ofst_meq32 += 2;
	}

	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");
@@ -2103,6 +2205,65 @@ static int ipa_flt_generate_eq_ip6(enum ipa_ip_type ip,
		ihl_ofst_meq32 += 2;
	}

	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");
@@ -2245,6 +2406,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;
+2 −0
Original line number Diff line number Diff line
@@ -132,6 +132,8 @@
#define IPA_FLT_MAC_DST_ADDR_802_3	(1ul << 20)
#define IPA_FLT_MAC_ETHER_TYPE		(1ul << 21)
#define IPA_FLT_MAC_DST_ADDR_L2TP	(1ul << 22)
#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