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

Commit e6608906 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa3: Ignore invalid NAT entries when counting nat rules"

parents e7832301 c9908739
Loading
Loading
Loading
Loading
+36 −9
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1517,6 +1517,7 @@ static int ipa3_read_table(
	char *entry;
	size_t entry_size;
	bool entry_zeroed;
	bool entry_valid;
	u32 i, num_entries = 0, id = *rule_id, pos = 0;

	IPADBG("\n");
@@ -1538,20 +1539,33 @@ static int ipa3_read_table(
			&entry_zeroed);
		if (result) {
			IPAERR(
				"Failed to determine whether the %s entry is definitely zero",
				ipahal_nat_type_str(nat_type));
				"Failed to determine whether the %s entry is definitely zero\n"
					, ipahal_nat_type_str(nat_type));
			goto bail;
		}
		if (entry_zeroed)
			continue;

		result = ipahal_nat_is_entry_valid(nat_type, entry,
			&entry_valid);
		if (result) {
			IPAERR(
				"Failed to determine whether the %s entry is valid\n"
					, ipahal_nat_type_str(nat_type));
			goto bail;
		}

		if (entry_valid) {
			++num_entries;
			pos += scnprintf(buff + pos, buff_size - pos,
				"\tEntry_Index=%d\n", id);
		} else {
			pos += scnprintf(buff + pos, buff_size - pos,
				"\tEntry_Index=%d - Invalid Entry\n", id);
		}

		pos += ipahal_nat_stringify_entry(nat_type, entry,
			buff + pos, buff_size - pos);

		++num_entries;
	}

	if (num_entries)
@@ -1637,6 +1651,7 @@ static int ipa3_read_pdn_table(char *buff, u32 buff_size)
	char *pdn_entry;
	size_t pdn_entry_size;
	bool entry_zeroed;
	bool entry_valid;
	u32 pos = 0;

	IPADBG("\n");
@@ -1654,13 +1669,25 @@ static int ipa3_read_pdn_table(char *buff, u32 buff_size)
			pdn_entry, &entry_zeroed);
		if (result) {
			IPAERR(
				"Failed to determine whether the PDN entry is definitely zero");
				"Failed to determine whether the PDN entry is definitely zero\n");
			goto bail;
		}
		if (entry_zeroed)
			continue;

		pos += scnprintf(buff + pos, buff_size - pos, "PDN %d: ", i);
		result = ipahal_nat_is_entry_valid(IPAHAL_NAT_IPV4_PDN,
			pdn_entry, &entry_valid);
		if (result) {
			IPAERR(
				"Failed to determine whether the PDN entry is valid\n");
			goto bail;
		}
		if (entry_valid)
			pos += scnprintf(buff + pos, buff_size - pos,
				"PDN %d: ", i);
		else
			pos += scnprintf(buff + pos, buff_size - pos,
				"PDN %d - Invalid: ", i);

		pos += ipahal_nat_stringify_entry(IPAHAL_NAT_IPV4_PDN,
			pdn_entry, buff + pos, buff_size - pos);
+64 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,7 @@

#define IPA_64_LOW_32_MASK (0xFFFFFFFF)
#define IPA_64_HIGH_32_MASK (0xFFFFFFFF00000000ULL)
#define IPAHAL_NAT_INVALID_PROTOCOL (0xFF)

static const char *ipahal_nat_type_to_str[IPA_NAT_MAX] = {
	__stringify(IPAHAL_NAT_IPV4),
@@ -73,6 +74,40 @@ static bool ipa_nat_ipv6ct_is_entry_zeroed_v_4_0(const void *entry)
	return (memcmp(&zero_entry, entry, sizeof(zero_entry))) ? false : true;
}

static bool ipa_nat_ipv4_is_entry_valid_v_3_0(const void *entry)
{
	struct ipa_nat_hw_ipv4_entry *hw_entry =
		(struct ipa_nat_hw_ipv4_entry *)entry;

	return hw_entry->enable &&
		hw_entry->protocol != IPAHAL_NAT_INVALID_PROTOCOL;
}

static bool ipa_nat_ipv4_is_index_entry_valid_v_3_0(const void *entry)
{
	struct ipa_nat_hw_indx_entry *hw_entry =
		(struct ipa_nat_hw_indx_entry *)entry;

	return hw_entry->tbl_entry != 0;
}

static bool ipa_nat_ipv4_is_pdn_entry_valid_v_4_0(const void *entry)
{
	struct ipa_nat_hw_pdn_entry *hw_entry =
		(struct ipa_nat_hw_pdn_entry *)entry;

	return hw_entry->public_ip != 0;
}

static bool ipa_nat_ipv6ct_is_entry_valid_v_4_0(const void *entry)
{
	struct ipa_nat_hw_ipv6ct_entry *hw_entry =
		(struct ipa_nat_hw_ipv6ct_entry *)entry;

	return hw_entry->enable &&
		hw_entry->protocol != IPAHAL_NAT_INVALID_PROTOCOL;
}

static int ipa_nat_ipv4_stringify_entry_v_3_0(const void *entry,
	char *buff, size_t buff_size)
{
@@ -194,11 +229,15 @@ static int ipa_nat_ipv6ct_stringify_entry_v_4_0(const void *entry,
 * struct ipahal_nat_obj - H/W information for specific IPA version
 * @entry_size - CB to get the size of the entry
 * @is_entry_zeroed - CB to determine whether an entry is definitely zero
 * @is_entry_valid - CB to determine whether an entry is valid
 *  Validity criterium depends on entry type. E.g. for NAT base table
 *   Entry need to be with valid protocol and enabled.
 * @stringify_entry - CB to create string that represents an entry
 */
struct ipahal_nat_obj {
	size_t (*entry_size)(void);
	bool (*is_entry_zeroed)(const void *entry);
	bool (*is_entry_valid)(const void *entry);
	int (*stringify_entry)(const void *entry, char *buff, size_t buff_size);
};

@@ -216,11 +255,13 @@ static struct ipahal_nat_obj ipahal_nat_objs[IPA_HW_MAX][IPA_NAT_MAX] = {
	[IPA_HW_v3_0][IPAHAL_NAT_IPV4] = {
			ipa_nat_ipv4_entry_size_v_3_0,
			ipa_nat_ipv4_is_entry_zeroed_v_3_0,
			ipa_nat_ipv4_is_entry_valid_v_3_0,
			ipa_nat_ipv4_stringify_entry_v_3_0
		},
	[IPA_HW_v3_0][IPAHAL_NAT_IPV4_INDEX] = {
			ipa_nat_ipv4_index_entry_size_v_3_0,
			ipa_nat_ipv4_is_index_entry_zeroed_v_3_0,
			ipa_nat_ipv4_is_index_entry_valid_v_3_0,
			ipa_nat_ipv4_index_stringify_entry_v_3_0
		},

@@ -228,16 +269,19 @@ static struct ipahal_nat_obj ipahal_nat_objs[IPA_HW_MAX][IPA_NAT_MAX] = {
	[IPA_HW_v4_0][IPAHAL_NAT_IPV4] = {
			ipa_nat_ipv4_entry_size_v_3_0,
			ipa_nat_ipv4_is_entry_zeroed_v_3_0,
			ipa_nat_ipv4_is_entry_valid_v_3_0,
			ipa_nat_ipv4_stringify_entry_v_4_0
		},
	[IPA_HW_v4_0][IPAHAL_NAT_IPV4_PDN] = {
			ipa_nat_ipv4_pdn_entry_size_v_4_0,
			ipa_nat_ipv4_is_pdn_entry_zeroed_v_4_0,
			ipa_nat_ipv4_is_pdn_entry_valid_v_4_0,
			ipa_nat_ipv4_pdn_stringify_entry_v_4_0
		},
	[IPA_HW_v4_0][IPAHAL_NAT_IPV6CT] = {
			ipa_nat_ipv6ct_entry_size_v_4_0,
			ipa_nat_ipv6ct_is_entry_zeroed_v_4_0,
			ipa_nat_ipv6ct_is_entry_valid_v_4_0,
			ipa_nat_ipv6ct_stringify_entry_v_4_0
		}
};
@@ -335,6 +379,25 @@ int ipahal_nat_is_entry_zeroed(enum ipahal_nat_type nat_type, void *entry,
	return 0;
}

int ipahal_nat_is_entry_valid(enum ipahal_nat_type nat_type, void *entry,
	bool *entry_valid)
{
	if (WARN(entry == NULL || entry_valid == NULL,
		"NULL pointer received\n"))
		return -EINVAL;
	if (WARN(nat_type < 0 || nat_type >= IPA_NAT_MAX,
		"requested NAT type %d is invalid\n", nat_type))
		return -EINVAL;

	IPAHAL_DBG("Determine whether the entry is valid for NAT type=%s\n",
		ipahal_nat_type_str(nat_type));
	*entry_valid = ipahal_nat_objs[ipahal_ctx->hw_type][nat_type].
		is_entry_valid(entry);
	IPAHAL_DBG("The entry is %svalid\n", (*entry_valid) ? "" : "not ");

	return 0;
}

int ipahal_nat_stringify_entry(enum ipahal_nat_type nat_type, void *entry,
	char *buff, size_t buff_size)
{
+13 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -52,6 +52,18 @@ int ipahal_nat_entry_size(enum ipahal_nat_type nat_type, size_t *entry_size);
int ipahal_nat_is_entry_zeroed(enum ipahal_nat_type nat_type, void *entry,
	bool *entry_zeroed);

/*
 * ipahal_nat_is_entry_valid() - Determines whether HW NAT entry is
 *                                valid.
 *  Validity criterium depends on entry type. E.g. for NAT base table
 *   Entry need to be with valid protocol and enabled.
 * @nat_type: [in] The type of the NAT entry
 * @entry: [in] The NAT entry
 * @entry_valid: [out] True if the received entry is valid
 */
int ipahal_nat_is_entry_valid(enum ipahal_nat_type nat_type, void *entry,
	bool *entry_valid);

/*
 * ipahal_nat_stringify_entry() - Creates a string for HW NAT entry
 * @nat_type: [in] The type of the NAT entry