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

Commit c9908739 authored by Ghanim Fodi's avatar Ghanim Fodi
Browse files

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



Ignore invalid NAT entries when counting NAT rules for debug
purposes. Table dumping still includes all the rules but
with proper indication for invalid entries.

Change-Id: I45a5d24232fe053ffb61c2f438e012cbf0fce315
Signed-off-by: default avatarGhanim Fodi <gfodi@codeaurora.org>
parent 11a18c0d
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